Restrictions on indexed fields in embedded documents

62 views
Skip to first unread message

Gerold Böhler

unread,
May 23, 2016, 5:20:59 PM5/23/16
to mongodb-user
Hi all,


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 and cannot support a covered query.
  • any of the indexed fields in the query predicate or returned in the projection are fields in embedded documents.
I don't think i understand the second part correctly. Does this mean that indexes are not working on embedded fields?

Thanks for clarifying,
Gerold

Kevin Adistambha

unread,
May 31, 2016, 2:59:20 AM5/31/16
to mongodb-user

Hi Gerold,

I believe you are referring to the Covered Query section. The two restrictions you are referring to only relates to covered queries, and not general queries.

Covered queries are a special case of queries that could be answered by MongoDB using only an index. In short, MongoDB does not have to look at document contents to ensure that the returned documents satisfies the query. For example, if you have a collection:

> db.test.find()
{ "_id" : ObjectId("574d308119398907e9744d3d"), "x" : 0, "y" : 0 }
{ "_id" : ObjectId("574d308119398907e9744d3e"), "x" : 1, "y" : 1 }
{ "_id" : ObjectId("574d308119398907e9744d3f"), "x" : 2, "y" : 2 }
{ "_id" : ObjectId("574d308119398907e9744d40"), "x" : 3, "y" : 3 }
{ "_id" : ObjectId("574d308119398907e9744d41"), "x" : 4, "y" : 4 }

with an index:

> db.test.createIndex({x:1})

If you query this collection and specify that the output should only include the field x:

> db.test.find({x:{$gt:2}}, {_id:0, x:1})
{ "x" : 3 }
{ "x" : 4 }

then this is a covered query, since we have an index on field x, and we did not request any other field to be present in the result. Thus, MongoDB can satisfy this query by using only the {x:1} index to serve as the query index and also as the output. You can see that a query is a covered query by examining the explain('executionStats') output:

> db.test.explain('executionStats').find({x:{$gt:2}}, {_id:0, x:1})
...
"executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 2,
        "executionTimeMillis" : 0,
        "totalKeysExamined" : 2,
        "totalDocsExamined" : 0,
...

In this explain() output:

  • the nReturned (i.e. number of documents that satisify the query) is 2
  • the totalKeysExamined (i.e. index keys scanned) is 2
  • the totalDocsExamined (i.e. documents whose contents needs to be examined to ensure that it satisfies the query) is 0

The totalDocsExamined number will be larger than zero if it’s not a covered query.

There are restrictions on the indexes for a query to be covered queries:

  • It cannot be a multikey index (i.e. not an array)
  • It cannot be an embedded document (this is the restriction that you read in the documentation)

However, those indexes can still be used to find matching documents.

Best regards,
Kevin

Reply all
Reply to author
Forward
0 new messages