mongodb指数范围找到

时间:2014-02-06 06:07:21

标签: mongodb indexing mongodb-query

如果我有这些文档:

{"name": 1, "score": 2}
{"name": 1, "score": 4}
{"name": 2, "score": 2}
{"name": 2, "score": 4}

如果我确保索引:

db.test.ensureIndex({"name":1, "score":1})

然后我尝试找到():

db.test.find({"score": 4})

我使用explain(),发现这个查询不能使用索引,它会扫描所有四个文档。

我想知道为什么要扫描所有文档?

你知道,如果我枚举所有“名字”的价值(1和2):

db.test.find({"$or":["name":1, "name":2], "score":4})

它可以使用索引,只扫描了两个文档。

为什么mongodb不能为我做这件事?

3 个答案:

答案 0 :(得分:1)

您的索引未被使用的原因是因为$or排除运算符,这意味着它会或多或少地扫描所有内容以确定不是< / strong>匹配。

您真正想要使用的是$in。这会将匹配减少到仅 集合中包含的那些值。

db.test.find({"$in":["name":1, "name":2], "score":4})

由于这是包含,匹配可以应用于索引而无需进行完整扫描。

答案 1 :(得分:0)

一般的经验法则是:如果您有一个复合索引,并且您通过其中的字段进行搜索,则还必须在索引定义中指定其左侧的所有字段。

您可以这样考虑复合索引:文档按第一个字段编制索引/分组,然后在这些组中,它们由第二个字段编制索引。

因此,当您尝试使用第二个字段进行搜索而不指定第一个字段时,mongo将必须扫描整个索引,因为它无法有效地从遍历中排除项目。

db.test.find({"name": {"$in": [1, 2]}, "score": 4})

在这种情况下,它只会查看name = 1和name = 2索引条目,并在那里查找score = 4。如果您没有指定名称,它将扫描所有内容。效率不高。

答案 2 :(得分:0)

在mongoDB中,如果集合上有复合索引(如集合中的情况,复合索引是(名称,分数)),则索引字段的顺序非常重要。 MongoDB只能将复合索引用于包含索引字段前缀的查询。因此,在您的情况下,索引仅适用于包含以下内容的查询:
1)名称字段
2)姓名和得分字段。

对于任何其他查询,将不使用索引。这是因为mongoDB创建复合索引的方式。文档将首先按名称字段索引,然后按分数字段索引。如果查询仅包含得分字段,则mongoDB无法使用索引查找文档。

参考:http://docs.mongodb.org/manual/core/index-compound/#compound-index-prefix