Question

I am making use of dynamic queries in mongoDB, by using them this way:

$query['clicks'] = array('$gt' => 6);
$query['lang'] = "de";

$cursor = $collection->find($query);

The question is pretty simple and straightforward: how can one add 'OR' conditionals? for example to have both 'lang' to be "de" OR "fr";

Because right now, Mongo implies that there is an AND between "clicks" and "lang". So how can i structure clicks > 6 && ( lang == 'de' || lang == 'fr' )

Was it helpful?

Solution

You can give try as below

$query['clicks'] = array('$gt' => 6);
$query['$or'] = array(array('lang' => 'de'), array('lang' => 'fr'));
$cursor = $collection->find($query);

How to add $in operator

$query['clicks'] = array('$gt' => 6);
$query['$or'] = array(array('lang' => 'de'), array('lang' => 'fr'));
$query['_id'] = array('$in' => array(new mongoId('506d95bc5c73952c14000002'), new mongoId('506d95bc5c73952c14000003')));

$cursor = $collection->find($query);

OTHER TIPS

          $cond=array();
          $cond=array_merge($cond,array("clicks" => array('$gt' =>6)));
          $cond=array_merge($cond,array("$or" => array(array("lang" =>'de'),array("lang" =>'fr'))));

    $cursor = $collection->find($cond);

----------------------------

    another way is : 
       $cond=array();
          $cond=array_merge($cond,array("clicks" => array('$gt' =>6)));
          $cond=array_merge($cond,array("$in" => array('de','fr')));

    $cursor = $collection->find($cond);

$or is good but not extremely index friendly especially when you start getting into more diverse ranges. A slightly more index friendly method is with $in:

$db->collection->find(array('clicks' => array('$gt' => 6), 
    'lang' => array('$in' => array('fr', 'de'))));

That tends to make more efficient use of indexes at times.

Also note that nested $ors do not currently use indexes however $or can use multiple index plans which means that a query like so:

$db->collection->find(array('clicks' => array('$gt' => 6), '$or' => array(
    array('lang' => 'fr'), arrray('lang' => 'de')
))

Would be able to use multiple indexes but in this case it is useless since it only going over one field so better to use $in.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top