How to index dynamic attributes in MongoDB I have following kind of data (simplified a bit from my real case) in MongoDB:

{
    "name":"some name",
    "attrs":[
        {"n":"subject","v":"Some subject"},
        {"n":"description","v":"Some great description"},
        {"n":"comments","v":"Comments are here!"},
        ]
}


The attrs array is a container for dynamic attributes, i.e. I don't beforehand know what kind of attributes are put there. n stands for name and v stands for value.

The MongoDB In Action book describes this as a solution for having dynamic attributes in the case where the attributes are completely upredictable. It also describes that you can index it like this:

db.mycollection.ensureIndex({"attrs.n":1, "attrs.v":1})


Queries can then be done like this:

db.mycollection.find({attrs: {$elemMatch: {n: "subject", v: "Some subject"}}})


When i test this, I get very poor performance. I tested with mycollection having 2 million documents and having no index seems to perform better.

So, the question goes, is there a way to index this kind of dynamic attribute setting so that the indexing gives good performance? In my case, it is not feasible to just have keys like "subject" and "description" and index them all...
I also asked this same question (in a bit expanded form) on the mongodb-user mailing list, where I got an answer. Read from there to get more details. The short answer is, that the strategy used in the question should work fine, but there's an issue that makes it very inefficient. Hopefully, the issue will be fixed soon.

For my case, I only need to query for exact matches for the tuple {n,v}, so I can create a multikey index:

db.mycollection.ensureIndex({"attrs":1})


and make they query like this:

db.mycollection.find({"attrs": {n: "subject", v: "Some subject"}})


which works great and uses the index very effectively.