Мне нужно ограничить объем данных, возвращаемых запросом доктрины mongoDB. Я мог бы использовать select
для проецирования на простые поля или даже простые встроенные поля массива, такие как normalizedData.ean
. Это работает отлично.
Однако у меня есть необходимые данные в форме, подобной следующей:
"values" : [
{
"_id" : ObjectId("59cbd73d83218bf7668b468d"),
"attribute" : NumberLong("1"),
"entity" : DBRef("pim_catalog_product", ObjectId("59148d2583218bf7508c1199"), "akeneo_pim"),
"varchar" : "10011060"
},
{
"_id" : ObjectId("59cbd73d83218bf7668b468e"),
"attribute" : NumberLong("207"),
"entity" : DBRef("pim_catalog_product", ObjectId("59148d2583218bf7508c1199"), "akeneo_pim"),
"varchar" : "PRO70"
},
{
"_id" : ObjectId("59cbd73d83218bf7668b468f"),
"attribute" : NumberLong("110"),
"entity" : DBRef("pim_catalog_product", ObjectId("59148d2583218bf7508c1199"), "akeneo_pim"),
"option" : NumberLong("1890")
}
]
Между прочим, фреймворк Akeneo PIM.
Итак, проблема здесь в том, что "values"
индексируются не с помощью уникальных идентификаторов, которые я мог бы использовать, а с помощью пронумерованных индексов. Я заранее знаю номер "attribute"
, поэтому я могу запросить его.
Итак, что я ищу, так это построитель запросов к базе данных Doctrin Mongo DB, способный возвращать только те сущности, которые на самом деле содержат значения с номерами атрибутов 110 и 207, плюс я хочу возвращать только данные в пределах этих значений.
У меня есть рабочий построитель запросов, который работает с уникальными (строковыми) индексами:
$query = $productRepository->createQueryBuilder()
->hydrate(false)
->select(array('normalizedData.sku'))
->field('_id')->in($entityIds)
->limit($limit)
->skip($offset);
РЕДАКТИРОВАТЬ: теперь я нашел способ запросить эти "values"
, но я не могу проецировать более одного атрибута с помощью этого запроса:
$qb = $productRepository->createQueryBuilder();
$query = $qb
->hydrate(false)
->select(array('normalizedData.sku'))
->selectElemMatch(
'values',
$qb->expr()->field('attribute')->in(array(117, 110))->addAnd(
$qb->expr()->field('locale')->in(array('it_IT', 'de_DE'))
))
->field('_id')->in($entityIds)
->field('values')->elemMatch($qb->expr()->field('attribute')->in(array(117, 110)))
->limit($limit)
->skip($offset);
Здесь я пытаюсь получить оба атрибута (117 и 110), но получаю только один. Кроме того, я получаю некоторые результаты, в которых отсутствует ни один из атрибутов, хотя я предполагал, что отфильтровал атрибуты с ->field('values')->elemMatch($qb->expr()->field('attribute')->in(array(117, 110)))
.
Очевидно, что есть еще некоторые основы, которые мне нужно понять о mongoDB. Любая помощь будет принята с благодарностью.
Как мне получить только те объекты, которые имеют атрибут 117 и/или 110 в своей коллекции «значений», а также получить только данные этих атрибутов?
Примечание. Один и тот же идентификатор атрибута можно использовать несколько раз для разных языков. Я хотел бы также иметь возможность ограничить результат указанными языками.