在mongo中搜索范围

时间:2013-04-20 01:02:58

标签: mongodb optimization database

当输入数据是单个值且集合数据包含最小/最大范围时,在Mongo中查找数据的最有效方法是什么? E.g:

record = { min: number, max: number, payload }

需要找到一个在记录的最小/最大范围内的数字的记录。范围永远不会相交。关于范围的大小没有可预测性。

该集合中有大约6M条记录。如果我解压缩范围(在范围内有每个值的记录),我会查看大约4B个记录。

我已经创建了{min:1,max:1}的复合索引,但尝试使用:

进行搜索
db.block.find({min:{$lte:value},max:{$gte:value})

......需要几到几十秒的时间。以下是explain()getIndexes()的输出。有什么技巧可以让搜索执行得更快吗?

NJmongo:PRIMARY> db.block.getIndexes()
[
    {
            "v" : 1,
            "key" : {
                    "_id" : 1
            },
            "ns" : "mispot.block",
            "name" : "_id_"
    },
    {
            "v" : 1,
            "key" : {
                    "min" : 1,
                    "max" : 1
            },
            "ns" : "mispot.block",
            "name" : "min_1_max_1"
    }
] 


NJmongo:PRIMARY> db.block.find({max:{$gte:1135194602},min:{$lte:1135194602}}).explain()
{
    "cursor" : "BtreeCursor min_1_max_1",
    "isMultiKey" : false,
    "n" : 1,
    "nscannedObjects" : 1,
    "nscanned" : 1199049,
    "nscannedObjectsAllPlans" : 1199050,
    "nscannedAllPlans" : 2398098,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 7534,
    "nChunkSkips" : 0,
    "millis" : 5060,
    "indexBounds" : {
            "min" : [
                    [
                            -1.7976931348623157e+308,
                            1135194602
                    ]
            ],
            "max" : [
                    [
                            1135194602,
                            1.7976931348623157e+308
                    ]
            ]
    },
    "server" : "ccc:27017"
}

1 个答案:

答案 0 :(得分:1)

如果block记录的范围从不重叠,那么您可以通过以下方式更快地完成此任务:

db.block.find({min:{$lte:value}}).sort({min:-1}).limit(1)

此查询几乎会立即返回,因为它可以在索引中通过简单查找找到记录。

您运行的查询速度很慢,因为这两个子句都匹配数百万条必须合并的记录。实际上,我认为您的查询在minmax上使用单独的索引会运行得更快(可能更快),因为复合索引的max部分只能用于给定{ {1}} - 不要搜索具有特定min的文档。