Can MongoDB use an index when checking for existence of a field with $exists operator?
Updated:
Seems $exists
queries use index properly now based on these tickets
$exists queries should use index & {$exists: false} will not use index
Old Answer:
No, there is no way to tell mongodb to use index for exists query. Indexing is completely related to data. Since $exists is only related to the keys (fields) it cant be used in indexes.
$exists just verifies whether the given key (or field) exists in the document.
$exist will not use index, but you can change your data structure to
photos: [
{id:123, url: '...', title: '...', ... },
{id:456, url: '...', title: '...', ... },
...
]
and then use
db.users.ensureIndex({photos.id:1})
to create index for photo id.
It seems I am wrong, in fact, you can force your $exists query to use your index. Let us go on using the above structure, but your photo id is not certainly contained , that is to say some docs will have the key 'id' and some will not. Then you can create sparse index on it:
db.users.ensureIndex({'photos.id': 1}, {'sparse': true})
then query like this:
db.users.find({'photos.id': {$exists: true}}).hint({'photos.id': 1})
you can add explain to see if the query is using index. Here is my result, my collection's mobile key is similar to your photos.id:
> db.test.count()
50000
> db.test.find({'mobile': {$exists: true}}).hint({'mobile': 1}).explain()
{
"cursor" : "BtreeCursor mobile_1",
"nscanned" : 49999,
"nscannedObjects" : 49999,
"n" : 49999,
"millis" : 138,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"mobile" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
}
}
> db.test.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "test.test",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"mobile" : 1
},
"ns" : "test.test",
"name" : "mobile_1",
"sparse" : true,
"background" : true
}
]
Hope to help!
Since MongoDB 2.0 $exists
queries should use an index. Unfortunately this fix has disappeared in the newest version and will be fixed in MongoDB 2.5