Almost none of Mongo's Advanced Queries work for References (probably Embedded as well) #283

Closed
kusmierz opened this Issue Mar 23, 2012 · 2 comments

Comments

Projects
None yet
2 participants

From advanced queries works only... $or and $and.

For example:

<?php
// # Acme\AcmeBundle\Document\Article
    /**
     * @MongoDB\ReferenceOne(targetDocument="Acme\AcmeBundle\Document\Category", simple=true, cascade={"all"}, nullable=true)
     */
    protected $category;

and the query

<?php
$this->createQueryBuilder()->find()
            ->field('category')->in((array) $ids)
            ->getQuery()
            ->execute();

I'm pretty sure it's because of vendor\doctrine-mongodb-odm\lib\Doctrine\ODM\MongoDB\Persisters\DocumentPersister.php at line 900:

<?php
if ($prepareValue === true && isset($mapping['reference']) && isset($mapping['simple']) && $mapping['simple']) {
        $targetClass = $this->dm->getClassMetadata($mapping['targetDocument']);
        $value = $targetClass->getDatabaseIdentifierValue($value); // this will convert our $in array into strange (?!) MongoId
}

Workaround? Maybe change it to:

diff --git a/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php b/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php
index 907d8df..a8aa512 100644
--- a/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php
+++ b/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php
@@ -898,8 +901,12 @@ class DocumentPersister
             $fieldName = $mapping['name'];

             if ($prepareValue === true && isset($mapping['reference']) && isset($mapping['simple']) && $mapping['simple']) {
-                $targetClass = $this->dm->getClassMetadata($mapping['targetDocument']);
-                $value = $targetClass->getDatabaseIdentifierValue($value);
+                if (is_array($value)) {
+                    $value = $this->prepareQuery($value);
+                } else {
+                    $targetClass = $this->dm->getClassMetadata($mapping['targetDocument']);
+                    $value = $targetClass->getDatabaseIdentifierValue($value);
+                }
             }

         // Process identifier

It also requires to resolve #250 issue as provided:

diff --git a/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php b/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php
index 907d8df..a8aa512 100644
--- a/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php
+++ b/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php
@@ -780,11 +780,13 @@ class DocumentPersister
         if (is_scalar($query) || $query instanceof \MongoId) {
             $query = array('_id' => $query);
         }
-        if ($this->class->hasDiscriminator() && ! isset($query[$this->class->discriminatorField['name']])) {
+        static $queryNestLevel = 0;
+        if (!$queryNestLevel && $this->class->hasDiscriminator() && ! isset($query[$this->class->discriminatorField['name']])) {
             $discriminatorValues = $this->getClassDiscriminatorValues($this->class);
             $query[$this->class->discriminatorField['name']] = array('$in' => $discriminatorValues);
         }
         $newQuery = array();
+        ++ $queryNestLevel;
         if ($query) {
             foreach ($query as $key => $value) {
                 if (isset($key[0]) && $key[0] === $this->cmd && is_array($value)) {
@@ -795,6 +797,7 @@ class DocumentPersister
             }
             $newQuery = $this->convertTypes($newQuery);
         }
+        -- $queryNestLevel;
         return $newQuery;
     }
Owner

jwage commented Mar 23, 2012

Can you make a failing phpunit test case and I can for sure fix it.

jwage closed this in 3df2858 Mar 23, 2012

Thanks :) but look at new tests, could you?

@jmikola jmikola added a commit that referenced this issue May 17, 2012

@rtens @jmikola rtens + jmikola Query preparation tests for simple references
This was originally included in PR #261. It tests the fixes for #250, #283 and #284.
fc3128c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment