Mongo在对象数组与对象上建立索引 [英] Mongo indexing on object arrays vs objects

查看:1030
本文介绍了Mongo在对象数组与对象上建立索引的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实现一个处理很多字段的联系人数据库.它们中的大多数是预定义的,可以认为是绑定的,但是有一些不是预定义的.我们将这些字段之一称为组".我们当前的实现方式是(每个文档/联系人都有组"字段):

'groups' : {
   152 : 'hi',
   111 : 'group2'
}

但是经过一番阅读,我似乎应该这样做:

'groups' : [
   { 'id' : 152, 'name' : 'hi' },
   { 'id' : 111, 'name' : 'group2' }
   ...
]

,然后应用索引db.contact.ensureIndex({'groups.id':1});

我的问题是关于功能的.这两种结构之间有什么区别,以及索引的实际构建方式(是在每个文档/联系人中简单地建立索引还是在构建包含所有文档/联系人中所有组的全面索引?).

我在某种程度上假设这是结构上最好的方法,但是如果我不正确,请告诉我.

解决方案

在第二种情况下,查询无疑会容易得多,其中组"是子文档的数组,每个子文档都有一个"id"和一个姓名'.

Mongo不支持通配符"查询,因此,如果您的文档是第一种结构的,并且您想查找值为"hi"的子文档,但又不知道键为152,则不会能够做到.使用第二种文档结构,您可以轻松查询{"groups.name":"hi"}.

有关查询嵌入式对象的更多信息,请参见标题为点表示法(到达对象)"的文档. http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-ValueinanArray

对于{'groups.id':1}上的索引,将为每个文档中每个"groups"数组中的每个"id"键创建一个索引条目.使用组"上的索引时,每个文档将仅创建一个索引条目.

如果您有第二种类型的文档,并且有组索引,则您的查询将必须匹配整个子文档才能使用索引.例如,给定文档:

{ "_id" : 1, "groups" : [ { "id" : 152, "name" : "hi" }, { "id" : 111, "name" : "group2" } ] }

查询

db.<collectionName>.find({groups:{ "id" : 152, "name" : "hi" }}) 

将使用索引,但查询

db.<collectionName>.find({"groups":{$elemMatch:{name:"hi"}}})

db.<collectionName>.find({"groups.name":"hi"})

不会.

您创建的索引应取决于您最常执行的查询.

您可以使用.explain()命令尝试使用哪些(如果有的话)索引来查询. http://www.mongodb.org/display/DOCS/Explain 第一行,光标"将告诉您您正在使用哪个索引. "cursor":"BasicCursor"表示正在执行完整的收集扫描.

文档中有更多有关索引的信息: http://www.mongodb.org/display/DOCS/Indexes

以上索引数组元素"部分链接到标题为多键"的文档: http://www.mongodb.org/display/DOCS/Multikeys

希望这将增进您对如何在嵌入式文档上进行查询以及如何使用索引的理解.如果您有任何后续问题,请告诉我们!

I'm implementing a contact database that handles quite a few fields. Most of them are predefined and can be considered bound, but there are a couple that aren't. We'll call one of these fields 'groups'. The way we currently implement it is (each document/contact has 'groups' field):

'groups' : {
   152 : 'hi',
   111 : 'group2'
}

but after some reading I've it would seem I should be doing it:

'groups' : [
   { 'id' : 152, 'name' : 'hi' },
   { 'id' : 111, 'name' : 'group2' }
   ...
]

and then apply the index db.contact.ensureIndex({'groups.id':1});

My question is in regard to functionality. What are the differences between the 2 structures and how is the index actually built (is it simply indexing within each document/contact or is it building a full-scale index that has all the groups from all the documents/contacts?).

I'm kind of going in under the assumption that this is structurally the best way, but if I'm incorrect, let me know.

解决方案

Querying will certainly be a lot easier in the second case, where 'groups' is an array of sub-documents, each with an 'id' and a 'name'.

Mongo does not support "wildcard" queries, so if your documents were structured the first way and you wanted to find a sub-document with the value "hi", but did not know that the key was 152, you would not be able to do it. With the second document structure, you can easily query for {"groups.name":"hi"}.

For more information on querying embedded objects, please see the documentation titled "Dot Notation (Reaching into Objects)" http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29 The "Value in an Array" and "Value in an Embedded Object" sections of the "Advanced Queries" documentation are also useful: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-ValueinanArray

For an index on {'groups.id':1}, an index entry will be created for every "id" key in every "groups" array in every document. With an index on "groups", only one index entry will be created per document.

If you have documents of the second type, and an index on groups, your queries will have to match entire sub-documents in order to make use of the index. For example, given the document:

{ "_id" : 1, "groups" : [ { "id" : 152, "name" : "hi" }, { "id" : 111, "name" : "group2" } ] }

The query

db.<collectionName>.find({groups:{ "id" : 152, "name" : "hi" }}) 

will make use of the index, but the queries

db.<collectionName>.find({"groups":{$elemMatch:{name:"hi"}}})

or

db.<collectionName>.find({"groups.name":"hi"})

will not.

The index(es) that you create should depend on which queries you will most commonly be performing.

You can experiment with which (if any) indexes your queries are using with the .explain() command. http://www.mongodb.org/display/DOCS/Explain The first line, "cursor" will tell you which index is being used. "cursor" : "BasicCursor" indicates that a full collection scan is being performed.

There is more information on indexing in the documentation: http://www.mongodb.org/display/DOCS/Indexes

The "Indexing Array Elements" section of the above links to the document titled "Multikeys": http://www.mongodb.org/display/DOCS/Multikeys

Hopefully this will improve your understanding of how to query on embedded documents, and how indexes are used. Please let us know if you have any follow-up questions!

这篇关于Mongo在对象数组与对象上建立索引的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆