在查询之前排序

时间:2017-11-08 14:13:58

标签: mongodb

在运行过滤查询之前,是否可以对Mongo集合运行排序?我有一个较旧的代码,其中我使用的方法是从数据库中获取随机结果,方法是在0和1之间随机浮动,然后使用findOne查询以获得值更大的第一个文档而不是当时生成的随机浮动。样本集很小,所以当时没有注意到问题,但最近注意到,通过一个查询,我几乎总是得到相同的值。 "第一"文件随机> .9,所以几乎每个查询都首先匹配它。

我意识到,要使这个解决方案起作用,我需要随机排序,然后找到大于我随机的第一个值。据我了解,这不像过去那样是必要的解决方案,因为$sample存在于3.2,但我想知道如何做到这一点会很好吗?另外,我的理解是$sample可以多次返回同一文档(显然N> 1,因此不能直接适用于我的问题)。

例如,以下数据:

> db.links.find()
{ "_id" : ObjectId("553c072bc87652a80e00002a"), "random" : 0.9162904409691691 }
{ "_id" : ObjectId("553c3332c87652c80700002a"), "random" : 0.00427396921440959 }
{ "_id" : ObjectId("553c3c5cc87652a80e00002b"), "random" : 0.2409569111187011 }
{ "_id" : ObjectId("553c3c66c876521c10000029"), "random" : 0.35101076657883823 }
{ "_id" : ObjectId("553c3c6ec87652200700002e"), "random" : 0.3234482416883111 }
{ "_id" : ObjectId("553c68d5c87652a80e00002c"), "random" : 0.5221220930106938 }

任何尝试运行db.mycollection.findOne({'random': {'$gte': x}}),其中x是高达.91的任何值,总是返回第一个对象(_id 553c072)。任何更大的回报都没有。如果我可以按random值按升序排序然后过滤,它会继续搜索,直到找到正确的值。

1 个答案:

答案 0 :(得分:1)

我强烈建议您放弃自定义解决方案,只需切换到使用MongoDB内置$sample阶段,该阶段将从您的集合中返回随机结果。

根据您的评论

编辑

以下是您可以执行最初要求的方式:

db.links.find({ "random": { $gte: /* put your value here */ } })
.sort({ "random": 1 /* sort by "random" field in ascending order */ })
.limit(1)

您可以,但也不需要使用aggregation framework

db.links.aggregate({
    $match: {
        "random": {
            $gte: /* put your value here */ // filter the collection
        }
    }
}, {
    $sort: {
        "random": 1 // sort by "random" field in ascending order
    }
}, {
    $limit: 1 // return only the first element
})