Как запросить встроенные документы по ссылочному документу?

Я использую 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 позволяет напрямую возвращать встроенный документ.


person Cobby    schedule 18.03.2011    source источник


Ответы (1)


Если вы используете 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

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

person Andrew Orsich    schedule 01.06.2011
comment
Пожалуйста, есть ли обходной путь для запроса любого ссылочного поля, ожидающего идентификатора ссылки? В моем случае мне нужно что-то вроде $qb->field('permissions.group.id')->equals($id); Разрешения - это несколько полей embedMany и группировка эталонного - person Marcel Djaman; 19.04.2015