PHP+MongoDB dynamic queries - adding conditional operators
-
05-07-2021 - |
Вопрос
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' )
Решение
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);
Другие советы
$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 $or
s 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
.