如何在mongoDb中的查询中使用$ lt和$ gte

时间:2017-02-09 16:11:32

标签: php mongodb aggregation-framework

我有这个问题。我有这个数据库:

{
"_id" : ObjectId("58c1a000023409b3b4263c69"),
"nome" : "hotel",
"point" : [ 
    {
        "nome" : "hall",
        "wiFi" : [ 
            {
                "ssid" : "ssjjt",
                "bssid" : "c0:04:25:83:06:30",
                "rssid" : "-77",
            }, 
            {
                "ssid" : "spot",
                "bssid" : "b8:03:05:3a:80:af",
                "rssid" : "-34",
            }
        ]
    }, 
    {
        "nome" : "restorant",
        "wiFi" : [ 
            {
                "ssid" : "ssjjt",
                "bssid" : "c0:04:25:83:06:30",
                "rssid" : "-76",
            }
        ]
}

我在PHP中有以下rssid值,最大值和分钟如

min : -70
max : - 80

我想有一个查询,它给我一个值列表,其中包含我的两个值之间的调查。

我必须使用聚合查询。

非常感谢你们。

1 个答案:

答案 0 :(得分:1)

这里的问题是你在数据库中将rssids存储为字符串,你不能应用$ lt和$ gte来将它们与数值进行比较,因为Mongo对类型有严格的要求。

在聚合期间,也没有简单的方法将字符串转换为数字。例如,聚合期间不允许使用$ where子句。

实现您想要的第一种方法是修改数据库以将rssid保持为Numbers(或保留原始字符串并具有其他数字属性),然后运行这样的聚合。

db.getCollection('test').aggregate([
    {$unwind: '$point'},
    {$match: {'point.wiFi.rssid': {$gte: -80, $lt: -70}}},
    //You can omit grouping if you don't need them to be unique
    {$group: {_id: '$point.nome'}}
])

如果您无法修改数据库或添加属性,则第二种方法发挥作用。您可以使用mapReduce。例如:

db.getCollection('test').mapReduce(function () {
        this.point = this.point || [];
        this.point.forEach(function (point) {
            point.wiFi = point.wiFi || [];
            point.wiFi.forEach(function (wiFi) {
                var rssid = parseInt(wiFi.rssid);

                if (rssid >= -80 && rssid < -70) {
                    emit(point.nome, rssid);
                }
            })
        });
    },
    function (key) {
        return key;
    },
    {out: {inline: 1}}
);