Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB indexes for $elemMatch

The indexes help page at http://www.mongodb.org/display/DOCS/Indexes doesn't mention $elemMatch and since it says to add an index on my 2M+ object collection I thought I'd ask this:

I am doing a query like:

{ lc: "eng", group: "xyz", indices: { $elemMatch: { text: "as", pos: { $gt: 1 } } } }

If I add an index

{lc:1, group:1, indices.text:1, indices.pos:1}

will this query with the $elemMatch component be able to be fully run through the index?

like image 959
Nic Cottrell Avatar asked Apr 18 '12 10:04

Nic Cottrell


People also ask

What does $elemMatch do in MongoDB?

Definition. The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria.

Can MongoDB use multiple indexes?

MongoDB can use the intersection of multiple indexes to fulfill queries. In general, each index intersection involves two indexes; however, MongoDB can employ multiple/nested index intersections to resolve a query.

Do indexes slow down inserts in MongoDB?

If every “the” and every “and” is indexed, this slows down your MongoDB instances because each time data is inserted into results, the indexes are updated. Also, while it's better than having no index at all, it can take longer for MongoDB to find what you're looking for and then everything slows down.


1 Answers

Based on your query, I imagine that your documents look something like this:

{
    "_id" : 1,
    "lc" : "eng",
    "group" : "xyz",
    "indices" : [
        {
            "text" : "as",
            "pos" : 2
        }, 
        {
            "text" : "text",
            "pos" : 4
        }
    ]
}

I created a test collection with documents of this format, created the index, and ran the query that you posted with the .explain() option.

The index is being used as expected:

> db.test.ensureIndex({"lc":1, "group":1, "indices.text":1, "indices.pos":1})
> db.test.find({ lc: "eng", group: "xyz", indices: { $elemMatch: { text: "as", pos: { $gt: 1 } } } }).explain()
{
    "cursor" : "BtreeCursor lc_1_group_1_indices.text_1_indices.pos_1",
    "isMultiKey" : true,
    "n" : NumberLong(1),
    "nscannedObjects" : NumberLong(1),
    "nscanned" : NumberLong(1),
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : NumberLong(0),
    "millis" : 0,
    "indexBounds" : {
        "lc" : [
            [
                "eng",
                "eng"
            ]
        ],
        "group" : [
            [
                "xyz",
                "xyz"
            ]
        ],
        "indices.text" : [
            [
                "as",
                "as"
            ]
        ],
        "indices.pos" : [
            [
                {
                    "$minElement" : 1
                },
                {
                    "$maxElement" : 1
                }
            ]
        ]
    },
    "server" : "Marcs-MacBook-Pro.local:27017"
}

The documentation on the .explain() feature may be found here: http://www.mongodb.org/display/DOCS/Explain

.explain() may be used to display information about a query, including which (if any) index is used.

like image 189
Marc Avatar answered Sep 21 '22 13:09

Marc