$max 运算符似乎不起作用

$max operator does not seem to be working

我有一个名为 "snapshots" 的集合,它的索引定义如下:

{ systemSnapshotsId: 1, dataType: 1, startFrame: -1 }

我正在尝试使用 $max 运算符创建一个查询来为查询定义该索引的上限,但它似乎没有任何效果。

如果我在不使用 max 的情况下执行以下查询,我会得到 469461 个文档的计数。

db.snapshots.find({systemSnapshotsId: ObjectId("---"), dataType: "blah"}).count()

当我使用以下查询添加 max() 运算符时,我得到了 469461 个文档的计数。

db.snapshots.find({systemSnapshotsId: ObjectId("---"), dataType: "blah"}).max({systemSnapshotsId: <sameId>, dataType: "blah", startFrame: 500}).count()

我希望第二个查询的计数为 500,如果倒退的话,我希望计数为 468961(总计数减去 500)。

那是因为您确实按照定义索引的方式倒退了它。快速举例说明。假设你有这个 collection:

{ "_id" : ObjectId("54c035bd2f63310180151870"), "a" : 1, "b" : 2, "c" : 1 }
{ "_id" : ObjectId("54c035c92f63310180151871"), "a" : 1, "b" : 2, "c" : 2 }
{ "_id" : ObjectId("54c035cc2f63310180151872"), "a" : 1, "b" : 2, "c" : 3 }
{ "_id" : ObjectId("54c035cf2f63310180151873"), "a" : 1, "b" : 2, "c" : 4 }
{ "_id" : ObjectId("54c035d32f63310180151874"), "a" : 1, "b" : 2, "c" : 5 }

然后你定义你的索引:

db.minmax.ensureIndex({ "a": 1, "b": 1, "c": -1 })

然后你 运行 这个查询,结果:

db.minmax.find({ "a": 1, "b": 2, "c": { "$lte": 3 } })

{ "_id" : ObjectId("54c035cc2f63310180151872"), "a" : 1, "b" : 2, "c" : 3 }
{ "_id" : ObjectId("54c035c92f63310180151871"), "a" : 1, "b" : 2, "c" : 2 }
{ "_id" : ObjectId("54c035bd2f63310180151870"), "a" : 1, "b" : 2, "c" : 1 }

然后尝试使用 $max 修饰符:

db.minmax.find({ "a": 1, "b": 2 }).max({ "a": 1, "b": 2, "c": 3 })

{ "_id" : ObjectId("54c035d32f63310180151874"), "a" : 1, "b" : 2, "c" : 5 }
{ "_id" : ObjectId("54c035cf2f63310180151873"), "a" : 1, "b" : 2, "c" : 4 }

倒过来了,因为你的索引是按照"c"的"highest"值排在第一位的。所以你想要的是 "reverse" 即 $min:

db.minmax.find({ "a": 1, "b": 2 }).min({ "a": 1, "b": 2, "c": 3 })

{ "_id" : ObjectId("54c035cc2f63310180151872"), "a" : 1, "b" : 2, "c" : 3 }
{ "_id" : ObjectId("54c035c92f63310180151871"), "a" : 1, "b" : 2, "c" : 2 }
{ "_id" : ObjectId("54c035bd2f63310180151870"), "a" : 1, "b" : 2, "c" : 1 }

但实际上,尝试使用 $lte or $gte 运算符而不是限制索引边界。这也是避免索引排序方向逻辑混乱的可靠方法。