Sorry if this has been asked before. I couldn't find a definitive answer. Can I query on a mongodb index if my query contains the $or operator? My query looks something like this:
// find everything in the collection
$cursor = $collection->find(array(
'$or' => array(
array('album_id' => array(
'$in' => $this->my_album_ids
),
'type' => array(
'$in' => array('like','comment')
)
),
array(
'user_id' => (int)session_item('user_id'),
'type' => 'message',
'reply' => 'no'
)
),
'timestamp' => array('$gt' => (int)$since)))->sort(array('timestamp'=>-1))->skip($start)->limit($amount);
The Example is in PHP, but I guess this is applicable to any language.
Update:
The following are my indexes, but the above query does not use them. It looks right to me though.
$collection->ensureIndex(array(
'album_id' => 1,
'type' => 1,
'timestamp' => -1,
));
$collection->ensureIndex(array(
'user_id' => 1,
'type' => 1,
'reply' => 1,
'timestamp' => -1,
));
Here is my explain()
Array
(
[cursor] => BasicCursor
[nscanned] => 12
[nscannedObjects] => 12
[n] => 6
[scanAndOrder] => 1
[millis] => 0
[nYields] => 0
[nChunkSkips] => 0
[isMultiKey] =>
[indexOnly] =>
[indexBounds] => Array
(
)
[allPlans] => Array
(
[0] => Array
(
[cursor] => BasicCursor
[indexBounds] => Array
(
)
)
)
[oldPlan] => Array
(
[cursor] => BasicCursor
[indexBounds] => Array
(
)
)
)
MongoDB provides different types of logical query operators and $or operator is one of them. This operator is used to perform logical OR operation on the array of two or more expressions and select or retrieve only those documents that match at least one of the given expression in the array.
Generally, MongoDB only uses one index to fulfill most queries. However, each clause of an $or query may use a different index, and in addition, MongoDB can use an intersection of multiple indexes.
Indexes are special data structures [1] that store a small portion of the collection's data set in an easy to traverse form. The index stores the value of a specific field or set of fields, ordered by the value of the field.
MongoDB uses multikey indexes to index the content stored in arrays. If you index a field that holds an array value, MongoDB creates separate index entries for every element of the array. These multikey indexes allow queries to select documents that contain arrays by matching on element or elements of the arrays.
Yes, an $or query will use indexes as appropriate. For example :
> db.test.ensureIndex({a:1})
> db.test.ensureIndex({b:1})
> db.test.find({$or:[{a:1}, {b:2}]}).explain()
{
"clauses" : [
{
"cursor" : "BtreeCursor a_1",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"a" : [
[
1,
1
]
]
}
},
{
"cursor" : "BtreeCursor b_1",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 1,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"b" : [
[
2,
2
]
]
}
}
],
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 1
}
Mongo use no IndexBounds on an sorted OR Query. Try
db.test.find({$or:[{a:1}, {b:2}]}).sort(somesort).explain();
and IndexBounds use with $minElement
and $maxElement
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With