I have this doc structure:
{
"key": {
"a": Int32,
"b": String
}
}
with a unique index on key and indexes (non-unique) on key.a and key.b.
Yet, this query scans (slooow):
{"key.a": 456213154}
and this query does not:
{"key": {
"a": 456213154,
"b": {"$exists": true}
}}
Why is that necessary, and should it be?
(I should mention that this is v2.0.3)
EDIT: adding explain:
> db.collection.find({"key.a": 456213154}).explain()
{
"cursor" : "BtreeCursor key.a_1",
"nscanned" : 10962,
"nscannedObjects" : 10962,
"n" : 10962,
"millis" : 20,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"key.a" : [
[
456213154,
456213154
]
]
}
}
> db.collection.find({"key": {"a": 456213154, "b": {"$exists":true}}}).explain()
{
"cursor" : "BtreeCursor key_1",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"key" : [
[
{
"a" : 456213154,
"b" : {
"$exists" : true
}
},
{
"a" : 456213154,
"b" : {
"$exists" : true
}
}
]
]
}
}
EDIT: I tried removing the two non-unique indices (key.a_1 and key.b_1) to see if that perhaps was hurting the query. It was not:
> db.collection.find({"key.a": 456213154}).explain()
{
"cursor" : "BasicCursor",
"nscanned" : 23240518,
"nscannedObjects" : 23240518,
"n" : 10962,
"millis" : 15047,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
Your explain() outputs suggest that:
There are 10962 objects that have key.a : 456213154. Your db.collection.find({"key.a": 456213154}) query used the index on key.a, and returned 10962 objects.
There are 0 objects in your collection that have key.a : 456213154 and have key.b : { $exists : true }. The db.collection.find({"key": {"a": 456213154, "b": {"$exists":true}}}) query did use your index on key.
See the n value for each query - this is the number returned; and the cursor value - this is BtreeCursor if an index is used. In this case it would make sense why the first query takes much longer, because it has significantly more objects to return.
Are you sure that the documents with key.a : 456213154 values also have key.b values?
Edit:
The query with the $exists param is the wrong syntax for checking existence within embedded documents.
Try db.collection.find({ "key.a" : 456213154, "key.b" : { "$exists" : true } }).
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