Как запросить встроенные документы по ссылочному документу? - PullRequest
3 голосов
/ 18 марта 2011

Я использую Doctrine ODM и у меня возникают проблемы с запросом встроенных документов по ссылочному документу.

Рассмотрим следующие документы:

<?php

/** @Document */
class TopCategory 
{

    /** EmbedMany(targetDocument="SubCategory") */
    private $subCategories;

}

/** @EmbeddedDocument */
class SubCategory 
{

    /** ReferenceMany(targetDocument="Product") */
    private $products;

}


/** @Document */
class Product
{

    /** @String */
    private $name;

}

Теперь мне интересно, как я могу найти TopCategory (или SubCategory) по продуктам, я пробовал несколько разных способов добиться этого, один метод работает, но немного хакерский.

Первый способ, не работает:

$category = $dm->createQueryBuilder('TopCategory')
    ->field('subCategories.products')->includesReferenceTo($someProduct)
    ->getQuery()->execute();
// ... gives Doctrine\ODM\MongoDB\MongoDBException: No mapping found for field 'subCategories.products' in class 'TopCategory'.'

Второй способ, не работает:

$category = $dm->createQueryBuilder('SubCategory')
    ->field('products')->includesReferenceTo($someProduct)
    ->getQuery()->execute();    
// ... returns null

В-третьих, рабочий обходной путь:

$category = $dm->createQueryBuilder('SubCategory')
    ->field('products.$id')->equals(new \MongoId($someProduct->getId()))
    ->getQuery()->execute();    
// .. works, but seems hackish

Я использую последние версии GitHub и MognoDB v1.8.0. Что с этим делать?

ПРИМЕЧАНИЕ. Интересно, как Doctrine ODM позволяет напрямую возвращать внедренный документ.

1 Ответ

7 голосов
/ 01 июня 2011

Если вы используете ReferenceMany или ReferenceOne, вы не можете выполнять запросы по любому полю справочного документа, кроме идентификатора справочного документа, поскольку в mongodb хранится справочный документ, например:

{
  $id: 'id',
  $db: 'referenced_doc_db_name',
  $ref: 'referenced_doc_collection_name'
}

ReferenceOne, ReferenceMany выполняется внутренне в драйвере, и при необходимости загрузить какой-либо документ, содержащий драйвер ссылки, отправляет дополнительные запросы для загрузки ссылочных документов.

Итак, следующий запрос не хакерский;):

$category = $dm->createQueryBuilder('SubCategory')
    ->field('products.$id')->equals(new \MongoId($someProduct->getId()))
    ->getQuery()->execute();    
// .. works, but seems hackish

Если вам нужен запрос к некоторому справочному полю (кроме идентификатора), вы должны использовать embedOne или embedMany вместо справки.

...