Mongo Multikeys as a substitute for indexes?
I've noticed that for indexing Arrays, the MongoDB documentation suggests that Multikeys are what should be used. However it doesn't state anything about explicitly creating multikeys as indexes. It appears as though this is automatic. Is that correct? Do I not need to created indexes on array ele开发者_如何学Pythonments? Should I create an index on the parent field?
http://www.mongodb.org/display/DOCS/Indexes#Indexes-IndexingArrayElements http://www.mongodb.org/display/DOCS/Multikeys
Update
I should have added that the arrays I'm speaking of contain embedded documents. Here's a specific example of part of a document:
{
_a: [{
_aid: "4e5d43698d3a329553111227",
_an: true
_aim: "http://graph.facebook.com/7403766/picture"
_ana: "Nick ONeill"
},
{
_aid: "4e5d43698d3a329553111228",
_an: true
_aim: "http://graph.facebook.com/129312401/picture"
_ana: "Joe Peterson"
}]
}
An index on an array field, or one containing an array field, is automatically a multikey index. What this means is that in the index there will be multiple entries, one for each element of the array, and one for the array as a whole. This allows matching on individual array elements like:
db.foo.find({myArrayField: "bar"})
Which will match documents like:
{name: "whatever", myArrayField: ["foo", "bar", "baz"]}
When querying such a field, MongoDB ensures that any given document is only returned once, even if it matches multiple times:
> db.foo.find({myArrayField: {$in: ["foo", "bar"]}})
{"name" : "whatever", "myArrayField" : [ "foo", "bar", "baz" ]}
Edit: You can index an array which contains embedded documents as well as "primitive" types. When doing so, you might want to use the $elemMatch
operator to search for partial matches on the embedded documents:
(Note about edit: I've updated the example to demonstrate using $elemMatch
with multiple elements; when the query only uses one embedded document field, you do not need $elemMatch
)
> db.foo.save({name:"a", myArrayField: [{a:1, b:2}, {a:5, b:6}]})
> db.foo.save({name:"b", myArrayField: [{a:1, b:3}]})
> db.foo.save({name:"c", myArrayField: [{a:1, b:1}, {a:5, b:3}]})
> db.foo.find({myArrayField: {a: 1, b: 2}})
{name:"a", myArrayField: [{a:1, b:2}, {a:5, b:6}]}
> db.foo.find({myArrayField: {a: 1}})
// finds nothing, no document has a
// sub-document in myArrayField
// exactly equal to {a: 1}
> db.foo.find({"myArrayField.a": 1})
{name:"a", myArrayField: [{a:1, b:2}, {a:5, b:6}]}
{name:"b", myArrayField: [{a:1, b:3}]}
{name:"c", myArrayField: [{a:1, b:1}, {a:5, b:3}]}
> db.foo.find({myArrayFIeld: {$elemMatch: {a: 1, b: {$gt: 1}}}})
{name:"a", myArrayField: [{a:1, b:2}, {a:5, b:6}]}
{name:"b", myArrayField: [{a:1, b:3}]}
// this does not find document "b", since
// it does not have any sub-documents in
// myArrayField where a is 1 and b is
// greater than 1
精彩评论