Мне нужно ограничить объем данных, возвращаемых запросом доктрины 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"
номер перед рукой, чтобы я мог запросить это.
Итак, я ищу построителя запросов доктрины Монго БД, который способен возвращать только те сущности, которые на самом деле содержат значения с номерами атрибутов 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 в своей коллекции «значений», а также только данные этих атрибутов?
Примечание. Один и тот же идентификатор атрибута может использоваться несколько раз на разных языках. Я хотел бы иметь возможность ограничить результат также указанными языками.
Вы пробовали учение Агрегационный строитель ?
Это может быть началом решения, особенно с размотать функция, которая может сгладить ваш ценности сделать запрос легче построить.
https://doctrine-mongodb-odm.readthedocs.io/en/latest/reference/aggregation-builder.html
Надеюсь, это поможет вам!
Других решений пока нет …