4

I am trying to use only the index while reading data from a collection in MongoDB, because I have some big documents, while for this query I need only one field.

It turns out that I cannot have indexOnly = true if the index is a multiKey index.

Here is the test I made:

db.test.drop()
db.test.insert({a:1})
db.test.ensureIndex({a:1})
db.test.find({a:1}, {_id:0, a:1}).explain()

-> indexOnly = true, isMultiKey = false

db.test.insert({a : [2,3]})
db.test.find({a:1}, {_id:0, a:1}).explain()

-> indexOnly = false, isMultiKey = true

The documentation mentions some limitations of the multikey indexes, but not this one. Does anybody have an idea how to use both multikey and indexonly?

1

2 Answers 2

6

From: http://docs.mongodb.org/manual/tutorial/create-indexes-to-support-queries/#create-indexes-that-support-covered-queries

An index cannot cover a query if any of the indexed fields in any of the documents in the collection includes an array. If an indexed field is an array, the index becomes a multi-key index index and cannot support a covered query.

You are inserting an array into your test collection, so when mongo is creating the index, it has to create a MultiKey index (it means it is creating the index for each item of the array).

Sign up to request clarification or add additional context in comments.

2 Comments

i think the question was why there is such a limitation.
Thanks. That answers it. I will probably create another collection as a "custom index" to minimize disk reads. I hoped mongo can do this for me :).
2

Note that when you have an indexOnly query, the returned document must be synthesized out of the information in the index only. That means that without looking at the document, the correct exact document must be returned.

In case of multiKey index, the query doesn't know whether to return
{ "a" : 1 }
or
{ "a" : [ 1 ] }

All it can tell is that "a" has value 1 and index is of type multiKey. It needs to look in the document to tell whether the type of "a" is an array or number.

5 Comments

So it isn't something that will be worked around in later versions? since if there is multiple values for a field in the index for a single _id it is safe to assume that it should be returning an array. Edit: actually I know the full problem now
if there is multiple values, then yes. if there is one, then we don't know. but index is traversed by values, not by document so the order is wrong to use this information, much simpler to look at the document.
Yeah that last bit was what went through my mind after posting the comment :)
That was a good suggestion. However I just made that test: db.test.drop() db.test.insert({a:[2,1], b:1}) db.test.ensureIndex({a:1, b:1}) db.test.find({a:1}, {_id:0, b:1}).explain() still -> multi = true, index only = false
this is because of you are searching on a and returning b. the value for b is not in the index that's only one a!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.