开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜