了解mongodb索引:索引经常查询的链接文档

时间:2016-11-19 19:06:47

标签: mongodb mongodb-query mongodb-indexes

以下是我的应用程序进行查询的一个简单示例

所以你有一个记事本和笔记集。使用notepadId将便笺文档链接到记事本文档。

因此,典型的查询如下:

Notes.find({notepadId: notepad._id})

用户每个记事本可以有数百个笔记。它们经常在记事本之间切换。用户还可以在笔记本上进行协作。

我还有一种机制可以计算页面加载时服务器上记事本中的所有注释。这是因为我需要知道自从使用分页以来要显示的页数。

Notes.find({notepadId: notepad._id}).count()

我对MongoDB索引不是很熟悉,并且尝试搜索“索引链接文档”,但找不到索引链接文档的任何信息。

这是将链接文档字段编入索引的常见做法吗?

所以在这种情况下,我想在Notes

字段上的notepadId集合上设置索引

好主意,坏主意,为什么?

2 个答案:

答案 0 :(得分:1)

文档仅在应用程序层上“链接”。 mongodb本身的notepadId字段没什么特别之处。通过此字段建立索引将使计数非常有效,因为它是covered query,不需要磁盘IO。

答案 1 :(得分:0)

那些(索引覆盖查询)被讨论过的答案,忘了告诉,为了得到完全索引覆盖的结果,你必须做一些不包括_id -field的投影。

让我解释一下。

在完全索引覆盖的查询中,我们只读取索引而不是磁盘中的任何其他内容。如果我们有f.ex. Notes.createIndex({notepadId:1,archived:1})(覆盖这两个查询的内容),我们做了Notes.find({notepadId:notepad._id})。count()会有两个不同的动作。首先,“找到”收集结果集的内容,然后“计算”计算结果集中有多少文档的数量。

如果未在投影中排除,则查找ALWAYS包含(在其结果集中)“_ id”字段。因为我们的索引没有_id -field,只有指向文档磁盘位置的指针,find首先使用索引查找所需文档,然后跳转到索引条目指向的磁盘位置,以读取文档的_id。不是我们想要的。为了防止这种情况,我们需要投影。所以查询:

Notes.find({notepadId: notepad._id},{"_id":0, "notepadId":1}).count()

将返回(在查找部分中)仅“notepadId”的列表,而不是其他任何内容。

另一个查询是:Notes.find({notepadId:notepad._id,archived:false},{“_ id”:0,“notepadId”:1,archived:1})。count()

您可以轻松地测试这两个不同的查询:

Notes.find({notepadId: notepad._id}).explain()
Notes.find({notepadId: notepad._id},{"_id":0, "notepadId":1}).explain()

并比较结果。