Mongodb 多字段mongo DB排序

Mongodb 多字段mongo DB排序,mongodb,nosql,Mongodb,Nosql,我在mongo中有一个查询,因此我希望优先选择第一个字段,然后是第二个字段 说我不得不质疑这样的问题 db.col.find({category: A}).sort({updated: -1, rating: -1}).limit(10).explain() 因此,我创建了以下索引 db.col.ensureIndex({category: 1, rating: -1, updated: -1}) 它只需扫描所需数量的对象即可工作,即10 但现在我需要问一下 db.col.find({cat

我在mongo中有一个查询,因此我希望优先选择第一个字段,然后是第二个字段

说我不得不质疑这样的问题

db.col.find({category: A}).sort({updated: -1, rating: -1}).limit(10).explain()
因此,我创建了以下索引

db.col.ensureIndex({category: 1, rating: -1, updated: -1})
它只需扫描所需数量的对象即可工作,即
10

但现在我需要问一下

db.col.find({category: { $ne: A}}).sort({updated: -1, rating: -1}).limit(10)
因此,我创建了以下索引:

 db.col.ensureIndex({rating: -1, updated: -1})
但这会导致扫描整个文档,当我创建

 db.col.ensureIndex({ updated: -1 ,rating: -1})
它扫描的文档数量更少:


我只是想问清楚在多个字段上排序,以及这样做时要保留的顺序。通过阅读MongoDB文档,很明显我们需要对其执行排序的字段应该是最后一个字段。这就是我在上面的
$ne
查询中假设的情况。我做错了什么吗?

没错,但这里有两层排序,因为您是在复合索引上排序的

正如您所注意到的,当索引的第一个字段与排序的第一个字段匹配时,它工作了,并且可以看到索引。然而,当以另一种方式工作时,情况并非如此

因此,根据您自己的权限,需要保留的顺序是字段从第一个到最后一个的查询顺序。mongo Analyzer有时可以在字段之间移动以匹配索引,但通常它只会尝试匹配第一个字段,如果不能,它将跳过它。

MongoDB通过尝试不同的计划来确定哪种方法最适合给定的查询。然后,该查询模式的获胜计划将被缓存,用于下一个~1000个查询,或者直到您执行
explain()

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

allplan
详细信息将显示所有已比较的计划

如果您运行的查询不是很有选择性(例如,如果许多记录与您的
{category:{$ne:'a'}}}
条件匹配),MongoDB使用BasicCursor(表扫描)查找结果可能比根据索引匹配更快

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

另外值得注意的是,MongoDB将只使用(除了
$或
s)

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

db.col.find({category:'A'}).sort({updated: -1, rating: -1})
您将希望在索引中包括所有三个字段:

db.col.ensureIndex({category: 1, updated: -1, rating: -1})

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

尝试此代码,它将首先根据名称对数据进行排序,然后将“名称”保留在密钥持有者中,它将对“过滤器”进行排序

 var cursor = db.collection('vc').find({   "name" :   { $in: [ /cpu/, /memo/ ]   }     }, { _id: 0, }).sort( { "name":1  ,  "filter": 1 } );

这是如何回答这个问题的?您仍然无法确保按照“rating desc,updated desc”的顺序获得排序,而不是“updated desc,rating desc”@jobermark在原始问题中,查询条件是
类别
,复合排序顺序为
{updated:-1,rating:-1}
。索引中键的顺序(和方向)很重要;建议的索引将无法有效地支持对按
{rating:-1,updated:-1}
排序的
内容进行搜索。如果要在驱动程序中操作复合排序值,请使用有序哈希/字典以确保保留排序。有关更多信息,请参阅MongoDB文档中的。
 var cursor = db.collection('vc').find({   "name" :   { $in: [ /cpu/, /memo/ ]   }     }, { _id: 0, }).sort( { "name":1  ,  "filter": 1 } );