查询 - 来自TABLE WHERE GROUP BY

时间:2016-04-09 00:11:17

标签: mongodb mongodb-query aggregation-framework

我是MongoDB的新手,并且有一个表BOXTABLE,如下所示

boxname
time_created
box_data

基本上我们正在记录哪个盒子在什么时间发送什么数据。假设该表具有以下数据,现在表示当前时间:

BoxA,Now,'AAA'
BoxB,Now,'AAA'
BoxC,Now,'AAA'
BoxA,Now,'AAA'
BoxA,Now,'AAA'
BoxB,Now,'AAA'
BoxA,Now,'AAA'
BoxC,Now,'AAA'
BoxA,Now,'AAA'
BoxB,Now,'AAA'

所以我需要得到这样的数据:

BoxA - 5
BoxB - 3
BoxC - 2

现在我的要求是在系统中创建一个警报,如果一个框发送的请求多于一个阈值,表明该框中可能存在错误或可疑内容。假设当前阈值为4 ,那么我应该收到BoxA的警告:

因此我的要求是执行类似这样的查询:

SELECT BOXNAME,COUNT(BOX_DATA) FROM BOXTABLE WHERE time_create >= now and time_create < now + 600 

我尝试了同样但不确定为什么它不起作用:

db.collection.aggregate([{"$group" : {"$id" : "$boxname", count:{"$box_data":1}}, time_created: {"$gte":start,"$lt":end}}])

开头和结尾如下所示:

start = int(time.time())
end = start + 600

我的代码是否正确 - 当我运行我得到以下错误

NameError: name 'count' is not defined

1 个答案:

答案 0 :(得分:1)

您需要$match来过滤范围以及此处的$group。并且正确地计算&#34;计算&#34;正在使用$sum,即{ "sum": 1 }用于每个&#34;分组&#34;值:

db.collection.aggregate([
    { "$match": {
      "time_created": { "$gte":start, "$lt":end }
    }},
    { "$group": {
        "_id": "$boxname",
        "count": { "$sum": 1 }
    }}
])

$match是&#34;过滤器&#34;,相当于"WHERE",因为$group"GROUP BY"

作为&#34;管道&#34;每个阶段按顺序将输出提供给下一个阶段。这是适应思维的主要观点。首先过滤,然后过滤&#34; group&#34;。

如果您例如想要一个"HAVING"条款,那么您将同样$match&#34;&#34; $group管道阶段。

db.collection.aggregate([
    { "$match": {
      "time_created": { "$gte":start, "$lt":end }
    }},
    { "$group": {
        "_id": "$boxname",
        "count": { "$sum": 1 }
    }},
    { "$match": { "count": { "$gt": 4 } } }
])

这与在SQL语句结尾处说"HAVING count > 4"相同。