MongoDB/doctrine: can't nest $or in $and
Asked Answered
B

2

6

I'm having trouble nesting multiple two-operand $or operations within an $and operation. The conclusion of this discussion sounds similar what I need, but I'm unable to get it to work. Here's JavaScript of what I'm trying to do:

db.Business.find(
  {
    $and:
      [
        { $or: [{nm: /American/}, {dsc: /American/}] },
        { $or: [{nm: /Mega/}, {dsc: /Mega/}] }
      ]
  }
)

That works in the MongoDB interactive shell.

And here's some PHP that looks ok to me but doesn't work (causes infinite recursion where indicated):

$q = $doctrineOdm->createQueryBuilder('Business');
foreach (array('American','Mega') as $keyword) {
  $r = new \MongoRegex('/'.$keyword.'/i');
  $q->addAnd(
    $q->addOr($q->expr()->field('nm')->equals($r))
      ->addOr($q->expr()->field('dsc')->equals($r))
  );
}
print_r($q->getQuery()->getQuery()); // infinite recursion
$cursor = $q->getQuery()->execute();

Any ideas?

Crossposted here.

Basis answered 11/4, 2012 at 23:19 Comment(0)
H
11

It sounds like you need to build a separate subquery before adding it to $q.

$q->addAnd(...) is evaluated immediately and adds itself to $q, but you want it to wait.

I don't have this package installed so I can't test, but this is just a hunch. Hope it helps.

$q = $doctrineOdm->createQueryBuilder('Business');
foreach (array('American','Mega') as $keyword) {
  $r = new \MongoRegex('/'.$keyword.'/i');
  $q->addAnd(
    $q->expr()->addOr($q->expr()->field('nm')->equals($r))
              ->addOr($q->expr()->field('dsc')->equals($r))
  );
}
print_r($q->getQuery()->getQuery()); // infinite recursion
$cursor = $q->getQuery()->execute();
Hm answered 12/4, 2012 at 2:4 Comment(1)
That was it exactly! Thank you! Adding ->expr() indeed delays adding the $or expression until the appropriate time.Basis
H
0

You can try as follows:

$filters = array(
     new \MongoRegex('/American/i'),
     new \MongoRegex('/Mega/i')
);
$q = $doctrineOdm->createQueryBuilder('Business')
                 -> field('nm')  ->in($filters)
                 -> field('dsc') ->in($filters);

print_r($q->getQuery()->getQuery()); // infinite recursion
$cursor = $q->getQuery()->execute();
Herr answered 21/8, 2015 at 8:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.