对象数组与对象上的 Mongo 索引

Posted

技术标签:

【中文标题】对象数组与对象上的 Mongo 索引【英文标题】:Mongo indexing on object arrays vs objects 【发布时间】:2012-03-24 07:04:33 【问题描述】:

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

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

但经过一些阅读后,我认为我应该这样做:

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

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

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

我假设这是结构上最好的方式,但如果我不正确,请告诉我。

【问题讨论】:

【参考方案1】:

在第二种情况下查询肯定会容易得多,其中“组”是一个子文档数组,每个子文档都有一个“id”和一个“名称”。

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

有关查询嵌入对象的更多信息,请参阅标题为“点表示法(到达对象)”的文档http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29 “高级查询”文档的“数组中的值”和“嵌入式对象中的值”部分也很有用: 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

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

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

【讨论】:

这是一个很好的答案,但前两个链接已损坏。我一直在搜索,但在网上找不到他们的新位置。有什么帮助吗? 您好,通过阅读您的回复,我想知道索引是否会用于查询,例如db.&lt;collectionName&gt;.find("groups":$elemMatch:"id":152) @portforwardpodcast 第一个链接似乎是docs.mongodb.com/manual/core/document/#dot-notation

以上是关于对象数组与对象上的 Mongo 索引的主要内容,如果未能解决你的问题,请参考以下文章

如何将一个对象插入到mongo数组中的另一个对象中

想要在 Mongo 中更新数组对象值的数组

Mongo - 通过_id更新嵌套的对象数组

如何在 mongo 存储库中过滤对象数组

使用节点将对象数组保存到 mongo 数据库,表达

在对象数组中,查找属性与搜索匹配的对象的索引的最快方法