MongoDB范围查询中$ lt和$ gt的顺序

时间:2012-03-27 18:59:41

标签: mongodb

今天我注意到在MongoDB 2.0.2中,给出$ lt和$ gt运算符的顺序似乎很重要。

我有一个游戏数据库。 “player”是表示两个玩家的两个字符串的数组,“endedAtMS”是游戏结束时的时间戳。我创建了这个索引:

db.games.ensureIndex({player:1,endedAtMS:-1})

要获得30个在特定时间范围内完成的游戏,请在游戏结束时订购,我这样做:

db.games.find({ "player" : "Stefan" , 
                "endedAtMS" : { "$lt" : 1321284969946 , 
                                "$gt" : 1301284969946}}).
         sort({endedAtMS:-1}).
         limit(30).
         explain()

{
    "cursor" : "BtreeCursor player_1_endedAtMS_-1",
    "nscanned" : 30,
    "nscannedObjects" : 30,
    "n" : 30,
    "millis" : 0,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : true,
    "indexOnly" : false,
    "indexBounds" : {
        "player" : [
            [
                "Stefan",
                "Stefan"
            ]
        ],
        "endedAtMS" : [
            [
                1321284969946,
                -1.7976931348623157e+308
            ]
        ]
    }
}

一切似乎都很好。但是,当我在上面的查询中更改$ lt和$ gt的顺序时,我得到了这个:

db.games.find({ "player" : "Stefan" , 
                "endedAtMS" : { "$gt":1301284969946, 
                                "$lt" : 1321284969946}}).
         sort({endedAtMS:-1}).
         limit(30).
         explain()

{
    "cursor" : "BtreeCursor player_1_endedAtMS_-1",
    "nscanned" : 126,
    "nscannedObjects" : 126,
    "n" : 30,
    "millis" : 1,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : true,
    "indexOnly" : false,
    "indexBounds" : {
        "player" : [
            [
                "Stefan",
                "Stefan"
            ]
        ],
        "endedAtMS" : [
            [
                1.7976931348623157e+308,
                1301284969946
            ]
        ]
    }
}

正如您所见,需要扫描126个文档才能获得30个文档。如果你看看explain输出中的indexBounds,似乎只有第一个运算符用于限制索引中的搜索空间。

我想念什么?为什么Mongo只使用一个运算符来限制搜索空间?

2 个答案:

答案 0 :(得分:9)

这是一个已知问题。简短的回答是,它与使用多键索引这一事实有关(“播放器”是一个数组),并且索引不能在上限和下限都受到约束。

在Jira案例中对此进行了更详细的解释:https://jira.mongodb.org/browse/SERVER-4155 - “索引绑定不正确?”

有一个开放的Jira票证可以改善这种行为:https://jira.mongodb.org/browse/SERVER-4180 - “为日期范围查询选择错误的索引边界(回归)”,该版本将在2.1.2版本中发布(此版本受制于更改)。请投票支持!

答案 1 :(得分:0)

此问题已在版本“ 2.1.2”中修复。

按照:https://jira.mongodb.org/browse/SERVER-4180

真棒!