Как найти документы по нескольким условиям для одного поля с помощью QueryBuilderAPI в Doctrine MongoDB? - PullRequest
4 голосов
/ 17 апреля 2011

У меня есть модель данных в MongoDB, которую я могу успешно запрашивать с помощью собственных запросов MongoDB.Однако я не могу выразить их с помощью Query Builder API Doctrine MongoDB ODM.

Вот так выглядит моя модель в MongoDB (это пример JSON-кода):

{ "name": "ArticleName", 
  "features": {
    { "type": "color",
      ...
      "values": {
        { "value": "RED", 
          "label": "red",
          ....
        },

        { "value": "GREEN", 
          "label": "green" }
      } 
    },
    { "type": "width",
      "values": {
        { "value": "40"}
      } 
    }
  }
}

Я хочу найти статьи путем поиска различных комбинаций значений и характеристик , например, я хочу найти статью с цветом = зеленый и шириной = 40.

Однако я не смог создать запрос для этого с помощью Doctrine MongoDB ODM Query Builder API **?Вот что я пробовал:

# Document/ArticleRepository.php    

$features = array('color'=>'RED', 'width'=>'40');
$qb = $this->createQueryBuilder('CatalogBundle:Article'); // I use symfony 2
foreach ($features as $type => $value)
{
    $qb->field('features')->elemMatch(
        $qb->expr()->field('type')->equals($type)->field('values')->elemMatch(
            $qb->expr()->field('value')->equals($value)
        )
    );
}
return $qb->getQuery()->execute();

Однако это приводит к запросу, который содержит только одно условие.Другое условие, кажется, перезаписано.Это запрос , сгенерированный Query Builder :

db.articles.find({ "features": { "$elemMatch": { "type": "width", "values": { "$elemMatch": { "value": 40 } } } } })

Есть ли способ решить мой сценарий использования с API MongoDB ODM Query Builder?

1 Ответ

5 голосов
/ 28 апреля 2011

Тем временем я решил свою проблему с помощью $ all-Operator . Я строю массив выражений, которые передаются в Doctrine MongoDB all() -Metod. Стратегия с $elemMatch, которую я пробовал выше, даже не работала бы с MongoDB. Вы должны добавить -> getQuery () в конце, чтобы иметь возможность записать выражение в массив. По некоторым причинам выражения еще не документированы , однако их функциональность можно проверить в исходном коде .

# Document/ArticleRepository.php

$features = array('color'=>'RED', 'width'=>'40');
$qb = $this->createQueryBuilder('CatalogBundle:Article');
$all_features[] = array();

foreach ($features as $templateID => $value)
{
    # Add expression as a subquery to array
    $all_features[] = $qb->expr()->elemMatch(
        $qb->expr()->field('templateID')->equals($templateID)->field('values')->elemMatch(
            $qb->expr()->field('value')->equals($value)
        )
    )->getQuery();
}
# Add expressions to query
$qb->field('features')->all($all_features);

Выражение поддерживает практически все методы, которые вы можете использовать при построении запроса. Вы можете создать свой запрос MongoDB, чередуя несколько выражений. Это позволяет вам строить сложные запросы MongoDB , которые вы могли бы построить иначе, только передав массив в findBy() -Metod. Однако в текущей версии (бета-версия 2) Doctrine ODM эта стратегия не позволит вам добавлять дополнительные методы в цепочку MongoDB, например .limit().

Таким образом, выражения выглядят как лучшая стратегия для построения сложных запросов с Doctrine MongoDB.

...