Jugal
Jugal

Reputation: 77

What index to be added in MongoDB to support $elemMatch query on embedded document

Suppose we have a following document

{
   embedded:[
   {
      email:"[email protected]",
      active:true
   },
   {
      email:"[email protected]",
      active:false
   }]
}

What indexing should be used to support $elemMatch query on email and active field of embedded doc.

Update on question :-

db.foo.aggregate([{"$match":{"embedded":{"$elemMatch":{"email":"[email protected]","active":true}}}},{"$group":{_id:null,"total":{"$sum":1}}}],{explain:true});

on querying this i am getting following output of explain on aggregate :-

{
"stages" : [
    {
        "$cursor" : {
            "query" : {
                "embedded" : {
                    "$elemMatch" : {
                        "email" : "[email protected]",
                        "active" : true
                    }
                }
            },
            "fields" : {
                "_id" : 0,
                "$noFieldsNeeded" : 1
            },
            "planError" : "InternalError No plan available to provide stats"
        }
    },
    {
        "$group" : {
            "_id" : {
                "$const" : null
            },
            "total" : {
                "$sum" : {
                    "$const" : 1
                }
            }
        }
    }
],
"ok" : 1
}

I think mongodb internally not using index for this query.

Thanx in advance :)

Update on output of db.foo.stats()

db.foo.stats()
{
    "ns" : "test.foo",
    "count" : 2,
    "size" : 480,
    "avgObjSize" : 240,
    "storageSize" : 8192,
    "numExtents" : 1,
    "nindexes" : 3,
    "lastExtentSize" : 8192,
    "paddingFactor" : 1,
    "systemFlags" : 0,
    "userFlags" : 1,
    "totalIndexSize" : 24528,
    "indexSizes" : {
        "_id_" : 8176,
        "embedded.email_1_embedded.active_1" : 8176,
        "name_1" : 8176
    },
    "ok" : 1
}


db.foo.getIndexes();
[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "test.foo"
    },
    {
        "v" : 1,
        "key" : {
            "embedded.email" : 1,
            "embedded.active" : 1
        },
        "name" : "embedded.email_1_embedded.active_1",
        "ns" : "test.foo"
    },
    {
        "v" : 1,
        "key" : {
            "name" : 1
        },
        "name" : "name_1",
        "ns" : "test.foo"
    }
]

Upvotes: 0

Views: 602

Answers (1)

mnemosyn
mnemosyn

Reputation: 46301

Should you decide to stick to that data model and your queries, here's how to create indexes that match the query:

You can simply index "embedded.email", or use a compound key of embedded indexes, i.e. something like

> db.foo.ensureIndex({"embedded.email" : 1 });
  - or -
> db.foo.ensureIndex({"embedded.email" : 1, "embedded.active" : 1});

Indexing boolean fields is often not too useful, since their selectivity is low.

Upvotes: 1

Related Questions