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