Kaitsu
unread,Feb 23, 2012, 2:30:22 AM2/23/12Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Sign in to report message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to mongodb-user
I have following kind of data 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 design 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 about 2 million documents and having no index
seems to perform better. Here's the explain of the query, which shows
that only the n field is taken from the index:
{
"cursor" : "BtreeCursor attrs.n_1_attrs.v_1",
"nscanned" : 2000202,
"nscannedObjects" : 2000202,
"n" : 2,
"millis" : 4111,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : true,
"indexOnly" : false,
"indexBounds" : {
"attrs.n" : [
[
"a_id",
"a_id"
]
],
"attrs.v" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
}
}
If I use multikeys to index it like this:
db.mycollection.ensureIndex({"attrs":1})
and then search like this:
db.mycollection.find({"attrs": {n: "subject", v: "Some subject"}})
the search result is correct and the search uses the multikey index
just fine:
{
"cursor" : "BtreeCursor attrs_1",
"nscanned" : 2,
"nscannedObjects" : 2,
"n" : 2,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : true,
"indexOnly" : false,
"indexBounds" : {
"attrs" : [
[
{
"n" : "a_id",
"v" : "19"
},
{
"n" : "a_id",
"v" : "19"
}
]
]
}
}
So, the question goes: is the dynamic attribute example in the
"MongoDB in Action" wrong and my multikey solution correct? Or is
there some other way to solve 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 separately.