MongoDB:添加sort()以查询$和查询的废结果集

时间:2017-02-17 09:47:25

标签: javascript mongodb sorting

我偶然发现了MongoDB的一些非常奇怪的行为。对于我的测试用例,我有一个包含9个文档的MongoDB集合。所有文档都具有完全相同的结构,包括字段expired_at: Datelocation: [lng, lat]

我现在需要查找尚未过期且位于边界框内的所有文档;我在地图上显示匹配文件。为此,我设置了以下查询:

var qExpiry = {"expired_at": { $gt : new Date() } };
var qLocation = { "location" : { $geoWithin : { $box : [ [ 123.8766, 8.3269 ] , [ 122.8122, 8.24974 ] ] } } };
var qFull = { $and: [ qExpiry, qLocation ] };

由于过去的过期日期很长,当我将边界框设置得足够大时,以下查询会按预期为我提供所有9个文档:

db.docs.find(qExpiry);
db.docs.find(qLocation);
db.docs.find(qFull);
db.docs.find(qExpiry).sort({"created_at" : -1});
db.docs.find(qLocation).sort({"created_at" : -1});

现在这里有交易:以下查询返回0个文件:

db.docs.find(qFull).sort({"created_at" : -1});

只需在AND查询中添加排序就会破坏结果(请注意我要排序,因为我也有一个限制,以避免在较大比例上混乱地图)。按其他字段排序会产生相同的空结果。这里发生了什么?

(实际上甚至更奇怪:当我放大我的地图时,我有时会得到qFull的结果,即使是排序。有人可能会说qLocation有问题。但是当我只使用{{1结果始终是正确的。无论如何,qLocation始终适用于所有文档。

2 个答案:

答案 0 :(得分:2)

您可能希望尝试使用聚合框架 $match $sort 管道运行相同的查询:

db.docs.aggregate([
    { "$match": qFull },
    { "$sort": { "created_at": -1 } }
]);

或通过指定以逗号分隔的表达式列表隐式使用 $and

db.docs.aggregate([
    { 
        "$match": {
            "expired_at": { "$gt" : new Date() },
            "location" : { 
                "$geoWithin" : { 
                    "$box" : [ 
                        [ 123.8766, 8.3269 ], 
                        [ 122.8122, 8.24974 ] 
                    ] 
                } 
            }
        } 
    },
    { "$sort": { "created_at": -1 } }
]);

不确定为什么失败了find()

答案 1 :(得分:1)

使用MongoDB聚合框架的chridam建议被证明是可行的方法。我现在的工作查询如下所示:

db.docs.aggregate(
    [ 
      { $match : { $and : [qExpiry, qLocation]} },
      { $sort: {"created_at": -1} }.
      { $limit: 50 }.
    ]
);

尽管如此,如果有人能指出我的第一种方法不起作用,那将非常有用。只需将sort()添加到非空查询中,就不应该突然返回0个文档。只是要添加,因为我仍然尝试了一点,.sort({})返回所有文档,但不是很有用。其他一切都失败了,包括.sort({'_id': 1})