在多个字段上对mongo DB进行排序

Glo*_*ior 29 mongodb nosql

我在mongo中有一个查询,以便我想优先考虑第一个字段,然后是第二个字段.

说我必须查询这样

db.col.find({category: A}).sort({updated: -1, rating: -1}).limit(10).explain()
Run Code Online (Sandbox Code Playgroud)

所以我创建了以下索引

db.col.ensureIndex({category: 1, rating: -1, updated: -1})
Run Code Online (Sandbox Code Playgroud)

它只是根据需要扫描了多个对象,即10个

但现在我需要查询

db.col.find({category: { $ne: A}}).sort({updated: -1, rating: -1}).limit(10)
Run Code Online (Sandbox Code Playgroud)

所以我创建了以下索引

 db.col.ensureIndex({rating: -1, updated: -1})
Run Code Online (Sandbox Code Playgroud)

但这导致扫描整个文档和我创建时

 db.col.ensureIndex({ updated: -1 ,rating: -1})
Run Code Online (Sandbox Code Playgroud)

它扫描的文档数量较少

我只想要问清楚多个字段的排序以及这样做时要保留的顺序是什么.通过阅读mongo-DB文档,可以清楚地知道我们需要执行排序的字段应该是最后一个字段.这就是我在上面的$ ne查询中假设的情况.我做错了吗?

Ste*_*nie 37

MongoDB 查询优化器通过尝试不同的计划来确定哪种方法最适合给定查询.然后缓存该查询模式的获胜计划以用于下一个〜1,000个查询或直到您执行explain().

要了解考虑了哪些查询计划,您应该使用explain(1),例如:

db.col.find({category:'A'}).sort({updated: -1}).explain(1)
Run Code Online (Sandbox Code Playgroud)

allPlans细节将显示进行比较,所有的计划.

如果您运行的查询不是很有选择性(例如,如果许多记录符合您的标准{category: { $ne:'A'}}),MongoDB使用BasicCursor(表扫描)查找结果而不是匹配索引可能会更快.

查询中字段的顺序通常不会对索引选择产生影响(范围查询有一些例外).场中的顺序排序会影响该指数的选择.如果您的sort()条件与索引顺序不匹配,则必须在使用索引后重新排序结果数据(scanAndOrder:true如果发生这种情况,您应该在explain输出中看到).

值得注意的是,MongoDB 每个查询只使用一个索引($ors 除外).

因此,如果您尝试优化查询:

db.col.find({category:'A'}).sort({updated: -1, rating: -1})
Run Code Online (Sandbox Code Playgroud)

您将希望在索引中包含所有三个字段:

db.col.ensureIndex({category: 1, updated: -1, rating: -1})
Run Code Online (Sandbox Code Playgroud)

仅供参考,如果您想强制特定查询使用索引(通常不需要或推荐),hint()您可以尝试使用该选项.