doctrine / mongodb-odm Goto Github PK
View Code? Open in Web Editor NEWThe Official PHP MongoDB ORM/ODM
Home Page: https://www.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/
License: MIT License
The Official PHP MongoDB ORM/ODM
Home Page: https://www.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/
License: MIT License
In certain PHPDoc blocks for functions, the @return type is not of the right type. This causes auto-completion issues in various IDEs (I'm using PhpStorm).
For example, in \Doctrine\ODM\MongoDB\DocumentManager on line #341 the ->createQueryBuilder($documentName = null) function.
....
/**
Create a new Query instance for a class.
*
@param string $documentName The document class name.
@return Document\ODM\MongoDB\Query <--------------------------- MUST BE Query\Builder !
*/
public function createQueryBuilder($documentName = null)
....
Similarly, there are such issues in other parts of the code. Is there a place where I can list them down as and when I find them and someone can fix it in the repository? (Unfortunately, I'm not yet a git user and due to time constraints, I can't fork and commit)
I have some problems wth circulare references. I have a Post and Category enties. So when i get the Post i get the post and his categories but when i get a category it has no posts.
example enties
namespace Documents\Blog;
/**
@Index(keys={"createdAt"="desc"})
}
namespace Documents\Blog;
/**
@Index(keys={"title"="desc"}, options={"unique"=true})
We're seeing that a PreUpdate hook is causing the document not to update embedded documents without errors - even if array('safe' => true) is used on the flush.
An example:
/** @PreUpdate */
public function incrementUpdatedAt() {
$this->updatedAt = new \DateTime();
}
Query by array of Id
$this->createQueryBuilder()->field('obj.id')->in( [ 'abcddc...', '123....' ] );
query that is pass to mongo is this.
db.document.find({"obj.$id": { "$in": ObjectId("abcddc...") }}
should be
db.document.find({"obj.$id": { "$in": [ObjectId("abcddc..."), ObjectId("123....")] }}
If you have a base class that is not abstract, and set the MappedSuperclass attribute for it, other classes that inherit from it will not get propagated lifecycle callbacks.
When using the YAML style description together with the new embedMany functionality of mixed documents, you get a PHP notice error every time you create a new model.
Because when you have mixed documents, you don't specify a targetDocument, and therefore the YAML Driver can not find an element in the array that describes the targetDocument.
If I try simple tutorial http://symfony.com/doc/current/bundles/DoctrineMongoDBBundle/index.html
then in step "Generating Getters and Setters" I get:
[ErrorException]
Catchable Fatal Error: Argument 1 passed to Doctrine\ODM\MongoDB\Mapping\Driver\YamlDriver::addFieldMapping() must be an instance of Doctrine\ODM\MongoDB\Mapping\ClassMetadata, instance of Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo given, called in /z/public_html/mongo/vendor/doctrine-mongodb-odm/lib/Doctrine/ODM/MongoDB/Mapping/Driver/YamlDriver.php on line 104 and defined in /z/public_html/mongo/vendor/doctrine-mongodb-odm/lib/Doctrine/ODM/MongoDB/Mapping/Driver/YamlDriver.php line 136
If I change ClassMetadata into ClassMetadataInfo in YamlDriver.php, it works.
But because of:
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo;
I don't know which occurences of ClassMetadata are in purpose...
Scenario: Before deleting an embedded collection, the original collection shall be backuped.
The script is listening for the onFlush Event.
For Updates this works fine:
foreach ($uow->getScheduledCollectionUpdates() AS $col) {
$col->getSnapshot(); # gives me the original collection -> works as expected
}
However this does not work for Deletions:
foreach ($uow->getScheduledCollectionDeletions() AS $col) {
$col->getSnapshot(); # is allways empty. -> does NOT work as expected
# Also empty (which I consider to be really strange: as OriginalDocumentData is documented as "The original data is the data that was present at the time the document was reconstituted from the database"):
$org = $uow->getOriginalDocumentData( $col->getOwner() );
$mapping = $col->getMapping();
$org[$mapping["fieldName"]]; # empty; but it should have the original collection, which is going to be deleted
}
Any Ideas?
When a MapReduce is performed in MongoDb, it returns some very useful and important statistics about the command execution like time taken, input, emit, output (look at the example output below). The ODM has completely hidden access to this result object. It would be a good feature to give access to this result object.
Read more on result object here: http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-Resultobject
array
'result' => string 'tmp.mr.ActiveUsers_foo' (length=22)
'timeMillis' => int 194
'counts' =>
array
'input' => int 1431
'emit' => int 1431
'output' => int 1064
'ok' => float 1
Sometimes I have this error, why and when he comes, I can not say unfortunately.
"E_WARNING Invalid argument supplied for foreach()
in /var/www/kiss_dev/vendor/doctrine-mongodb-odm/lib/Doctrine/ODM/MongoDB/Persisters/PersistenceBuilder.php on line 226"
Please add query logging support. I need for analysis and optimization.
Hi,
I found this weird issue where by I added another embedded document into a existing document it break down my embedded into two parts.
Here's an example class
PurchaseOrder
-———————————
/** * @MongoDB\Document(collection="PurchaseOrder") */ class PurchaseOrder { /** /** * @MongoDB\Id(strategy="auto") */ protected $id; /** * @MongoDB\EmbedMany(targetDocument="Order") */ protected $purchaseOrder; /** * Add order * * @param Cereals\ProductBundle\Document\Order\Order $order */ public function addPurchaseOrder(\Cereals\ProductBundle\Document\Order\Order $order) { $this->order[] = $order; } /** * Get order * * @return Doctrine\Common\Collections\Collection $order */ public function getOrder() { return $this->order; } }
Order
-———————————
/** * @MongoDB\EmbeddedDocument */ class Order { /** * @MongoDB\ReferenceOne(targetDocument="Test\VendorBundle\Document\Vendor") */ protected $vendor; /** * @MongoDB\String * @var String */ protected $vendorName; /** * @MongoDB\EmbedMany(targetDocument="OrderItem") */ protected $orderItems=array(); /** * Add orderItems * * @param Cereals\ProductBundle\Document\Order\OrderItem $orderItems */ public function addOrderItems(\Cereals\ProductBundle\Document\Order\OrderItem $orderItems) { $this->orderItems[] = $orderItems; } /** * Get orderItems * * @return Doctrine\Common\Collections\Collection $orderItems */ public function getOrderItems() { return $this->orderItems; } }
I'm running Symfony2. So here's an what I run with the code below.
-———————————
$dm = $this->get('doctrine.odm.mongodb.document_manager'); $purchaseOrder = new PurchaseOrder(); $order = new Order(); $order->setVendorName("....."); $orderItem = new OrderItem(); $order->addOrderItem($orderItem); $purchaseOrder->addOrder($order); $dm->persist($purchaseOrder); $dm->flush();
The above give the result below, which is right.
db.PurchaseOrder.update({ "_id": ObjectId("4e3ed35d4fcfa90a08020000") }, { "$pushAll": { "order": [ { "vendor": { "$ref": "Vendor", "$id": ObjectId("4e3eb4a04fcfa9c005070000"), "$db": "test" }, "vendorName": "drugCompany" } ] } }); db.PurchaseOrder.update({ "_id": ObjectId("4e3ed35d4fcfa90a08020000") }, { "$pushAll": { "order.0.orderItems": [ {"productName": "Bifen Suspension", "productId": ObjectId("4e3eb4a04fcfa9c005090000") } ] } });
But If i add another embedded document with this code.
$dm = $this->get('doctrine.odm.mongodb.document_manager'); $purchaseOrder = $dm->getRepository('TestProductBundle:PurchaseOrder')->find("4e3ed35d4fcfa90a08020000"); $order = new Order(); $order->setVendorName("....."); $orderItem = new OrderItem(); $order->addOrderItem($orderItem); $purchaseOrder->addOrder($order); $dm->persist($purchaseOrder); $dm->flush();
It give a wrong order of execution of query.
db.PurchaseOrder.update({ "_id": ObjectId("4e3ed35d4fcfa90a08020000") }, { "$pushAll": { "order.1.orderItems": [ { "productName": ".....", "productSn": "....", "productId": ObjectId("4e3eb4a04fcfa9c0050a0000") } ] } }); db.PurchaseOrder.update({ "_id": ObjectId("4e3ed35d4fcfa90a08020000") }, { "$pushAll": { "order": [ { "vendor": { "$ref": "Vendor", "$id": ObjectId("4e3eb4a04fcfa9c005080000")}, "vendorName": "Health" } ] } });
Under PurchaseOrder embedded document for order has the follow.
Fatal error: Declaration of Doctrine\ODM\MongoDB\DocumentRepository::findBy() must be compatible with that of Doctrine\Common\Persistence\ObjectRepository::findBy() in ../vendor/doctrine-mongodb-odm/lib/Doctrine/ODM/MongoDB/DocumentRepository.php on line 39
see commit: doctrine/common@5a28553#diff-3
- public function findBy(array $criteria);
+ public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null);
People complaining that download of the library here - http://www.doctrine-project.org/projects/mongodb_odm/download is unusable because the mongodb library is not included. Jon, please update the build script to include it.
I'm experiencing a problem when trying to embed documents and specify my own discriminatorMap and Field.
This is the code I have:
/** @Document(collection = "ticket") */
class App_Model_Ticket extends App_Model_Abstract
{
/**
* @EmbedMany(
* discriminatorField = "type",
* discriminatorMap={
* "twitter"="App_Model_Ticket_Twitter",
* "email"="App_Model_Ticket_Email"
* })
*/
protected $messages = array();
// [...]
}
App_Model_Abstract is a MappedSuperClass.
App_Model_Ticket_Email and App_Model_Ticket_Twitter pretty much look alike right now:
/** @EmbeddedDocument */
class App_Model_Ticket_Email extends App_Model_Ticket_Message
{
}
and App_Model_Ticket_Message is another MappedSuperClass that extends App_Model_Abstract.
Now, whenever I create a new model and persist it to mongoDB, the entry gets created and looks like this:
[_id] => MongoId Object (
)
[messages] => Array (
[0] => Array (
[message] => Lorem ipsum
[subject] => Ich bin ein Berliner22
[dateSent] => MongoDate Object (
[sec] => 1280909855
[usec] => 0
)
[_doctrine_class_name] => App_Model_Ticket_Twitter
)
[1] => Array (
[message] => Lorem ipsum
[subject] => Ich bin ein Berliner22
[dateSent] => MongoDate Object (
[sec] => 1280909855
[usec] => 0
)
[_doctrine_class_name] => App_Model_Ticket_Email
)
)
[subject] => Ich bin ein Berliner22
[dateCreated] => MongoDate Object (
[sec] => 1280909855
[usec] => 0
)
[dateLastMessage] => MongoDate Object (
[sec] => 1280909855
However, as you can see no type field for my embedded documents, it still uses _doctrine_class_name.
But when I try to fetch this object, I get an exception saying "Class not found".
I think this is because right now Doctrine ODM does not write into the custom discriminatorField with embedded documents, but reads from it.
Hello,
I can manipulate Mongo Documents.
But when I want to query (using find) some documents, with :
$users = $dm->getRepository('User')->findBy(array('name' => 'toto'));
I get this error :
class_parents(): Class User does not exist and could not be loaded in .../mongodb_odm/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataFactory.php on line 336
Please, help me.
Yaml::parse() should be used instead of Yaml::load() in /lib/Doctrine/ODM/MongoDB/Mapping/Driver/YamlDriver.php since symfony beat5 release.
Attempting to load a collections of documents with embedded files (MongoGridFSFile) will results in the following error:
Fatal error: Cannot use object of type MongoGridFSFile as array in Doctrine/ODM/MongoDB/UnitOfWork.php on line 2267
The $data variable in UnitOfWork::getOrCreateDocument is expected to be an array but instead is given an instance of \MongoGridFSFile.
I temporarily fixed the issue by adding the following to the getOrCreateDocument() method:
if($data instanceof \MongoGridFSFile){
$data = $data->file;
}
... however, I'm sure there is a better way to fix the issue.
To replicated, create an Image document like in the Reference Guide, in Storing files with MongoGridFS. Add some records and then try and load them in any fashion, like findAll() on the repository class.
I have the following collection named Isboo_Item :
{
"_id": ObjectId("4d3d02fec9fa877d44a36978"),
"author": null,
"backpack": null,
"itemType": 1,
"owner": "4d3cf450b532519765080000",
"place": null,
"quality": null,
"quantity": 1,
"value": null
}
and have a PHP class :
/**
@document(db="Isboona", collection="Isboo_Item")
*/
class Isboo_Item extends Isboo_Db
{
}
(...)
When I'm trying :
$dm->findOne($collection, array('_id' => $id));
I get :
Fatal error: Uncaught exception 'ReflectionException' with message 'Class 4 does not exist' in /users/developpement/www/library/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php:285
However the same works fine with another collection :
{
"_id": ObjectId("4d3cf450b532519765080000"),
"characs": {
"mana": 64,
"strenght": 83,
"agility": 69,
"dexterity": 88,
"constitution": 94,
"culture": 79,
"vivacity": 57,
"eloquence": 64,
"intellect": 74,
"willpower": 88,
"empathy": 96,
"charisma": 83
},
"name": "Krok",
"position": {
"IDplace": 0,
"posX": 0,
"posY": 0,
"posLocalX": 0,
"posLocalY": 0
},
"refFather": {
"$ref": "Isboo_Character",
"$id": ObjectId("4d3cf450b532519765090000"),
"$db": "Isboona"
},
"refMother": {
"$ref": "Isboo_Character",
"$id": ObjectId("4d3cf450b5325197650a0000"),
"$db": "Isboona"
}
}
Originally created at https://github.com/symfony/DoctrineMongoDBBundle/issues/39
Note: this "bug" was found using Symfony2.
Start with these two Documents:
namespace My\XBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* @MongoDB\Document
* @MongoDB\InheritanceType("COLLECTION_PER_CLASS")
*/
abstract class AbstractFoo
{
/**
* @MongoDB\Id
*/
protected $id;
/**
* @MongoDB\String
*/
protected $displayName;
}
namespace My\XBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* @MongoDB\Document
*/
class SubFoo extends AbstractFoo
{
/**
* @MongoDB\String
*/
protected $value;
}
Now, when you run mongodb:generate:documents My\XBundle
, you will end up with this in the subclass:
namespace My\XBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* @MongoDB\Document
*/
class SubFoo extends AbstractFoo
{
/**
* @MongoDB\String
*/
protected $value;
/**
* @var $id
*/
protected $id;
/**
* @var string $displayName
*/
protected $displayName;
/**
* Set value
*
* @param string $value
*/
public function setValue($value)
{
$this->value = $value;
}
/**
* Get value
*
* @return string $value
*/
public function getValue()
{
return $this->value;
}
/**
* Get id
*
* @return id $id
*/
public function getId()
{
return $this->id;
}
/**
* Set displayName
*
* @param string $displayName
*/
public function setDisplayName($displayName)
{
$this->displayName = $displayName;
}
/**
* Get displayName
*
* @return string $displayName
*/
public function getDisplayName()
{
return $this->displayName;
}
}
I'm facing this critical issue on all my Documents which have either an @odm\UniqueIndex, @odm\InheritanceType, @odm\DiscriminatorField, etc field defined for. Basically, if there's anything more than an @odm\Document annotation for the class, I get the error below while trying to retrieve a document using the DocumentManager:
$dm->find('Document\User', '4e283aabc2749a4b7d0001dd')
<?php
namespace Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
/**
* @ODM\Document
* @ODM\UniqueIndex(keys={"mobile"="asc"})
*/
class User extends \Document\AbstractDocument
{
/**
* @var string
* @ODM\Id
*/
protected $id;
/**
* @var string
* @ODM\String
*/
protected $mobile;
}
Fatal error: Access to undeclared static property: Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver::$�S�� in /home/dayson/projects/www/textme/ninja/library/Doctrine/ODM/MongoDB/Mapping/Driver/AnnotationDriver.php on line 146
Call Stack
# Time Memory Function Location
.....
6 0.0037 1319032 Doctrine\ODM\MongoDB\DocumentManager->find( ) ../Test.php:34
7 0.0038 1322736 Doctrine\ODM\MongoDB\DocumentManager->getRepository( ) ../DocumentManager.php:574
8 0.0038 1322736 Doctrine\ODM\MongoDB\DocumentManager->getClassMetadata( ) ../DocumentManager.php:474
9 0.0038 1322736 Doctrine\ODM\MongoDB\Mapping\ClassMetadataFactory->getMetadataFor( ) ../DocumentManager.php:273
10 0.0038 1322736 Doctrine\ODM\MongoDB\Mapping\ClassMetadataFactory->loadMetadata( ) ../ClassMetadataFactory.php:180
11 0.0050 1495432 Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver->loadMetadataForClass( ) ../ClassMetadataFactory.php:243
For some reason it's trying to access a static property with weird characters like $D7��1, etc.
What's happening? Could someone please help me resolve this as we've hit a roadblock in our project due to this. The latest master branch is being used.
Hello,
we are using the current versions of
doctrine-mongodb
doctrine-mongodb-odm
DoctrineMongoDBBundle
installed on the latest symfony2-standard package.
Our server is running the 1.4.4 version of mongoDB-server.
The odm is configured using annotations.
The second request to a page, which relies on database-request throws following exception:
Doctrine\ODM\MongoDB\MongoDBException: Class _\DataBundle\Document\Form is not a valid document or mapped super class. (uncaught exception) at /home/_/project/symfony/vendor/doctrine-mongodb-odm/lib/Doctrine/ODM/MongoDB/MongoDBException.php line 141
After clearing the cache, the first request is successful, the next fails again.
We have tried different workarounds:
None of them worked.
I've noticed this when playing around with the sandbox and references:
(output of mongo shell)
db.testcollection.findOne().references[0]
{ "$ref" : "testreference", "$id" : "4c3f0b456cc8849c17ab0000" }
The $id of the dbref here is a string, but I would expect it to be an ObejctId (a MongoId in PHP), like so:
db.testcollection.findOne().references[0]
{ "$ref" : "testreference", "$id" : ObjectId("4c3f0b456cc8849c17ab0000") }
This allows for...
db.testcollection.findOne().references[0].fetch()
{ ... referenced document here ... }
I couldn't find a note if this was intended by the odm or not, but an ObjectId is the proper format, here:
Because of this error i'm unable to generate entities with Doctrine ODM (coupled with Symfony 2) :
~/Documents/workspace/winiti(master) $ php app/console doctrine:mongodb:generate:documents MyBundle
[ErrorException]
Catchable Fatal Error: Argument 1 passed to Doctrine\ODM\MongoDB\Event\LoadClassMetadataEventArgs::__construct() must be an instance of Doctrine\ODM\MongoDB\Mapping\ClassMetadata, instance of Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo given, called in /Users/dunglas/Documents/workspace/winiti/vendor/doctrine-mongodb-odm/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataFactory.php on line 273 and defined in /Users/dunglas/Documents/workspace/winiti/vendor/doctrine-mongodb-odm/lib/Doctrine/ODM/MongoDB/Event/LoadClassMetadataEventArgs.php line 41
doctrine:mongodb:generate:documents [--document[="..."]] bundle
Exchange
and a subclass PersonalMessage
in two different namespaces.Here's my example parent document and inherited document in two different namespaces:
_My Parent Class in the '\Document' namespace_
<?php
namespace Document;
/**
*
* @abstract
* @Document
* @InheritanceType("SINGLE_COLLECTION")
* @DiscriminatorField(fieldName="type")
* @DiscriminatorMap({"p"="\Document\Exchange\PersonalMessage","s"="\Document\Exchange\Share"})
*/
abstract class Exchange
{
/**
* @Id
*/
protected $id;
/**
* Time of exchange
*
* @var \Datetime
* @Date
*/
protected $time;
public function setTime($time)
{
$this->time = $time;
}
}
_Example subclass in the '\Document\Exchange' namespace_
<?php
namespace Document\Exchange;
/**
* Document for Personal Messages (extended from Exchange document)
*
* @Document
*/
class PersonalMessage extends \Document\Exchange
{
/**
* @var String
* @String
*/
protected $foo;
public function setFoo($foo)
{
$this->foo = $foo;
}
}
If I want a specific field name you want in a property, he always removed from the query.
Example:
/** @Document(collection="users") */
class User {
/** @Id */
protected $id;
/** @String(name="usernameee") */
protected $username;
// ...
}
$user = new User();
$user->setUsername("Tecbot");
$dm->persist($user);
$dm->flush();
username does not exist then the query!!
Error could be corrected:
Class: ClassMetadata
Function: mapField
public function mapField(array $mapping)
{
$fieldName = $mapping['fieldName']; // Save fieldName tmp
//...
if ($this->reflClass->hasProperty($mapping['fieldName']) {
$reflProp = $this->reflClass->getProperty($mapping['fieldName']);
$reflProp->setAccessible(true);
$this->reflFields[$mapping['fieldName']] = $reflProp;
}
// change to !
if ($this->reflClass->hasProperty($fieldName)) {
$reflProp = $this->reflClass->getProperty($fieldName);
$reflProp->setAccessible(true);
$this->reflFields[$mapping['fieldName']] = $reflProp;
}
// ...
}
ClassMetadataInfo::getIdentifierValue($document)
use property reflection to retrieve the document identifier property value.
This is possible because ClassMetadata::mapField
call setAccessible(true)
on all $document
properties.
When $document
is a Doctrine\ODM\MongoDB\Proxy\Proxy
that hasn't been loaded yet, all the document properties are empty and getIdentifierValue
return NULL.
It should be the same with ClassMetadataInfo::getFieldValue
that also use reflection property.
I keep getting an undefined index of repositoryMethod in $mapping array when calling associations. Currently using 1.0.0BETA3.
Full details here: http://groups.google.com/group/doctrine-user/browse_thread/thread/bac2ce8c1b702dec
If a listener resets a document to its previous state, a Fatal Error is raised when instantiating the PreUpdateEventArgs.
The same issue was reported in the ORM as (DDC-1173)[http://www.doctrine-project.org/jira/browse/DDC-1173] and fixed here: doctrine/orm@ddb647f
Hi,
if you setup mongodb-odm with symfony2 rc4 the annotation classes are not correctly autoloaded even you add the
Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver::registerAnnotationClasses();
to autoload.php. For some reason the registered custom autoload function is not triggered and the annotation classes are not loaded.
In AnnotationDriver::loadMetadataForClass():
$this->reader->getClassAnnotations($reflClass) returns an incomplete class.
This is happens, because the FQN of the Annotation is mapped to vendor/doctrine-mongodb-dm/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/xxxxAnnotationClassNamexxxxx.php.
whereas the annotation class definitions are in a single file!
It looks like the repositoryClass isn't being picked up anymore - so functions on custom Repositories for a document aren't available.
Not 100% sure but I suspect the problem is in ClassMetadataFactory::getMetadataFor
findAndModify()
doesn't work as documented. From what I can tell, it should be findAndUpdate()
, however, queries executed with that option return a bool (not the document). When I tried getSingleResult()
instead of execute()
, a 'query does not return iterator' exception was thrown.
Presently, there's no support for storing the ObjectId (aka MongoId)
type in a field. This makes it difficult to maintain references manually. I have the option of storing the _id I want to reference as a @string (for e.g - "4e18e625c2749a260e000024" ), but that takes twice the amount of space for the field as well as the indexes.
I believe there's a strong need to support the @ObjectId
type just like how the MongoDate and MongoBinData are supported. Another solution would be to just allow support for the @Id
type to be used multiple times.
An example temporary implementation would be like below:
/**
* Custom Data type to support the MongoId data type in fields
*/
class ObjectId extends \Doctrine\ODM\MongoDB\Mapping\Types\Type
{
public function convertToDatabaseValue($value)
{
if ($value === null) {
return null;
}
if ( ! $value instanceof \MongoId) {
$value = new \MongoId($value);
}
return $value;
}
public function convertToPHPValue($value)
{
return $value !== null ? (string)$value : null;
}
}
There are a lot more use cases for NOT using DBRef than to use it. You can read more about the advantages here:
I have a document with an @Id(strategy="NONE")
for the $id field and if I set the value of this field to a type other than string, for example $document->setId(new \MongoBinData(md5(time())));
. When I persist this document, I get the following warning
Warning: Illegal offset type in ...../Doctrine/ODM/MongoDB/UnitOfWork.php on line 1334
If I set the id to a string, then there's no such warning. Why is this happening? I want to have my _id field of a type other than MongoId (for example, I might want to store a binary hash here instead?)
On the master branch, a notice is thrown on line 531 of the DocumentPersister for an undefined index 'criteria'. This is when using the Yaml driver.
Full notice:
Notice: Undefined index: criteria in /Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php on line 531
PHP Warning: array_merge(): Argument #2 is not an array in /Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php on line 532
Warning: array_merge(): Argument #2 is not an array in /Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php on line 532
PHP Catchable fatal error: Argument 1 passed to Doctrine\MongoDB\Collection::find() must be an array, null given, called in Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php on line 533 and defined in Doctrine/MongoDB/Collection.php on line 169
Catchable fatal error: Argument 1 passed to Doctrine\MongoDB\Collection::find() must be an array, null given, called in Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php on line 533 and defined in /Doctrine/MongoDB/Collection.php on line 169
Hello,
I make a query :
$users = $dm->getRepository('Documents\User')->findBy(array('username' => 'toto'));
if I make that :
while($users->hasNext())
{
$user = $users->getNext();
print_r($user);
}
The print_r shows me an array and not a User Document. Where is the problem ?
Please, help me.
From the documentation it can be extracted that if you wan to modify fields in the preUpdate event you need to call the UnitOfWork::recomputeSingleDocumentChangeSet() method, but calling this apparently it will always duplicate the record.
This is the relevant code:
$document = $eventArgs->getDocument();
$document->setUsername('other');
$dm = $eventArgs->getDocumentManager();
$uow = $dm->getUnitOfWork();
$class = $dm->getClassMetaData(get_class($document));
$uow->recomputeSingleDocumentChangeSet($class, $document);
After saving, I see two records, one with the old name and other with the new one
$document = new Familio\CoreBundle\Document\Document; $formBuilder->add('file')->getForm();
Exception : No mapping found for field 'file' in class 'Familio\CoreBundle\Document\Document'.
I fixed this bug :
namespace Symfony\Bundle\DoctrineMongoDBBundle\Form;
use Symfony\Component\Form\FormTypeGuesserInterface;
use Symfony\Component\Form\Guess\Guess;
use Symfony\Component\Form\Guess\TypeGuess;
use Symfony\Component\Form\Guess\ValueGuess;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\MongoDBException;
/**
-
Tries to guess form types according to ODM mappings
*
@author Thibault Duplessis [email protected]
/
class DoctrineMongoDBTypeGuesser implements FormTypeGuesserInterface
{
/*
- The Doctrine MongoDB document manager
- @var DocumentManager
*/
protected $documentManager = null;
public function __construct(DocumentManager $documentManager)
{
$this->documentManager = $documentManager;
}
/**
-
@inheritDoc
*/
public function guessType($class, $property)
{
if ($this->isMappedClass($class)) {
$metadata = $this->documentManager->getClassMetadata($class);
if ($metadata->hasAssociation($property)) {
$multiple = $metadata->isCollectionValuedAssociation($property);
$mapping = $metadata->getFieldMapping($property);
return new TypeGuess(
'document',
array(
'document_manager' => $this->documentManager,
'class' => $mapping['targetDocument'],
'multiple' => $multiple,
'expanded' => $multiple
),
Guess::HIGH_CONFIDENCE
);
} else {
try {
$fieldMapping = $metadata->getFieldMapping($property);
switch ($fieldMapping['type'])
{
case 'collection':
return new TypeGuess(
'Collection',
array(),
Guess::MEDIUM_CONFIDENCE
);
case 'boolean':
return new TypeGuess(
'checkbox',
array(),
Guess::HIGH_CONFIDENCE
);
case 'date':
case 'timestamp':
return new TypeGuess(
'datetime',
array(),
Guess::HIGH_CONFIDENCE
);
case 'float':
return new TypeGuess(
'number',
array(),
Guess::MEDIUM_CONFIDENCE
);
case 'int':
return new TypeGuess(
'integer',
array(),
Guess::MEDIUM_CONFIDENCE
);
case 'string':
return new TypeGuess(
'text',
array(),
Guess::MEDIUM_CONFIDENCE
);
}
} catch (MongoDBException $e) {
// not an entity or mapped super class
}
}
}
return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE);
}
/**
-
@inheritDoc
*/
public function guessRequired($class, $property)
{
if ($this->isMappedClass($class)) {
$metadata = $this->documentManager->getClassMetadata($class);
if ($metadata->hasField($property)) {
if (!$metadata->isNullable($property)) {
return new ValueGuess(
true,
Guess::HIGH_CONFIDENCE
);
}
return new ValueGuess(
false,
Guess::MEDIUM_CONFIDENCE
);
}
}
}
/**
-
@inheritDoc
*/
public function guessMaxLength($class, $property)
{
if ($this->isMappedClass($class)) {
$metadata = $this->documentManager->getClassMetadata($class);
if (!$metadata->hasAssociation($property)) {
$mapping = $metadata->getFieldMapping($property);
if (isset($mapping['length'])) {
return new ValueGuess(
$mapping['length'],
Guess::HIGH_CONFIDENCE
);
}
}
}
}
public function guessMinLength($class, $property)
{
}
/**
- Returns whether Doctrine 2 metadata exists for that class
*
- @param string $class
@return Boolean
*/
protected function isMappedClass($class)
{
return !$this->documentManager->getConfiguration()->getMetadataDriverImpl()->isTransient($class);
}
}
I'm trying to use strategy INCREMENT to create numeric identifiers, but every time I get MongoDB id presentation.
Code is:
/**
* @odm\Id(strategy="INCREMENT")
*/
private $id;
Maybe I missing something or this is a bug in current development version?
While doing an ->update()
using the QueryBuilder
, if I set the upsert to true using ->upsert(true)
, it does not work. I've to additionally also do a ->getQuery(array('upsert') => true)
before I ->execute(). This behavior is unexpected and undocumented. It defeats the purpose of having the ->upsert(true) function.
$dm->createQueryBuilder('\Document\Foo')
->update()
->upsert(true)
->field('a')->equals('5783b417a6da7e6d77426428ab48e5f7')
->field('b')->equals('foo)
->field('count')->set(5)
->getQuery(array('upsert' => true)) // why is this required?
->execute();
Doctrine seems to correctly store ObjectId's. However, when retrieving them back out of the database doctrine returns plain strings. This is a problem when using these ObjectIds in queries because if you query on an ObjectId and pass in a string it will not match and you'll get no result.
I know you can just do a new \MongoId(ObjectIdString) but what about when you're storing an array of ObjectId's? For instance an array of ObjectIds a user is following. Then in ->getFollowing() you must loop through each string and create a MongoId before returning the array of following ObjectIds. This is a practical case that I'm running into right now while trying to create a whereIn query. I need ObjectIds to do it, not strings.
Thoughts?
On developers machines we have PHP 5.3.5 and everything works fine. But on test server we have 5.3.2 and we have a lot of problems.
So, is 5.3.2 is not so good for ODM?
If so, maybe you can write notice somewhere what better to use 5.3.5 and latest versions?
When using ReferenceOne or ReferenceMany , doctrine will create fully-qualified reference to the object (with all fields: '$id', '$ref', '$db') even when reference is within same $db.
This affects maintenance and some special cases, since you cannot copy / rename database without additional overhead.
Is it possible to omit $db part when referencing document from same db?
Seems to only happen on windows OS, here is the error:
Happens when you try to convert this date:
converting DateTime Object ( [date] => 1890-01-01 00:00:00 [timezone_type] => 3 [timezone] => UTC )
Which converts to false and then is passed to the MongoDate object.
Changing DataType.php function to this fixes the issue:
public function convertToDatabaseValue($value)
{
if ($value instanceof \DateTime) {
$value = $value->getTimestamp();
}
if (is_string($value)) {
$value = strtotime($value);
}
if (!$value) {
return null;
}
return new \MongoDate($value);
}
I have a problem with DoctrineMongoDBBundle
I have a document in my bundle that works fine without Index
but when I add index to the document's field , the app/console doctrine:mongodb:generate:documents throws exception
thanks
Saleh
<?php
namespace <Bundle>\Document;
use \Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* @MongoDB\Document
*/
class Users
{
/**
* @MongoDB\Id
*/
protected $id;
/**
* @MongoDB\Int @MongoDB\Index
*/
public $uid;
...
the error
[ErrorException] &nbs p; &nbs p; &nbs p;
Catchable Fatal Error: Argument 1 passed to Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver::addIndex() must be an instance of Doctrine\ODM\MongoDB\Mapping\ClassMetadata, instance of Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo given, called in <PATH>/vendor/doctrine-mongodb-odm/lib/Doctrine/ODM/MongoDB/Mapping/Driver/AnnotationDriver.php on line 226 and defined in <PATH>/vendor/doctrine-mongodb-odm/lib/Doctrine/ODM/MongoDB/Mapping/Driver/AnnotationDriver.php line 260
&n bsp; &n bsp; &n bsp;
doctrine:mongodb:generate:documents [--document[="..."]] bundle
First query properly returns only the week field
$result = $dm->createQueryBuilder(__CLASS__)
->select('aField')
->getQuery()->getSingleResult();
Second query:
$result = $dm->createQueryBuilder(__CLASS__)
->select('anotherField')
->getQuery()->getSingleResult();
When ran after the first query, the return document only selected 'aField'. When ran standalone it properly selected 'anotherField'
This is using ALPHA3 from PEAR. Let me know if I can help by providing any further info.
The following query only works if I put an 'underscore' before 'id':
$query = $manager->createQueryBuilder('iMARKET\GeoBundle\Document\ServiceAreaMap')
->sort('_id', 'asc')
->getQuery();
It should be:
$query = $manager->createQueryBuilder('iMARKET\GeoBundle\Document\ServiceAreaMap')
->sort('id', 'asc')
->getQuery();
Andras
I'm trying to perform a mapreduce in which the output is stored to another collection. I've set the configuration for the 'out' option. The mapreduce works fine when I run execute, but what seems to happen is that it also tries to _find / retrieve_ the results from the results collection after executing the map/reduce. This is an unnecessary overhead.
Ideally, it should simply run the mapreduce and do nothing or return the statistics of the mapreduce (time taken, emits, etc). Instead, it queries for all the results of the mapreduce.
<?php
// $qb is the query builder
$qb->map('function(){
emit(this.from.userId, {
sex: this.from.sex,
circle: this.from.circle,
age: this.from.age
});
}')
->reduce('function(k, values){
return values[values.length - 1];
}')
->out(array('replace' => 'tmp.mr.ActiveUsers_foo'));
$query = $qb->getQuery();
var_dump($query->execute()); // is a LoggableCursor, why?
If I log the commands / queries executed, there's a MapReduce command _followed by a "find" on the collection tmp.mr.ActiveUsers_foo_. The second query shouldn't happen. Is this an intentional behavior? If so, how do I prevent it from happening?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.