8

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...

asked Feb 22, 2012 at 15:25

2 Answers 2

5

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.

answered Feb 24, 2012 at 5:28
0

Same question was asked in here. Starting in 4.2 version of MongoDB, they announced wildcard indexes. Here is an example:

db.myCollection.createIndex( { "subdocument.$**": 1 } );
answered Jan 4, 2020 at 15:26

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.