MongoDB-在一个查询中聚合多个字段
我正在为我们公司的生产系统开发一个监控系统。这意味着我将要存储的数据的性质是时间序列。在查看了其他几个数据库之后,我选择了MongoDB。 生产系统中的事件将一直到达,但我打算将事件存储在一个10分钟间隔的文档中。最终,集合中的文档将如下所示:MongoDB-在一个查询中聚合多个字段,mongodb,Mongodb,我正在为我们公司的生产系统开发一个监控系统。这意味着我将要存储的数据的性质是时间序列。在查看了其他几个数据库之后,我选择了MongoDB。 生产系统中的事件将一直到达,但我打算将事件存储在一个10分钟间隔的文档中。最终,集合中的文档将如下所示: { _id: '04/25/2015 13:00', event1_count : 130, event2_count : 50, event3_count : 200 }, { _id: '04/25/2015 13:
{
_id: '04/25/2015 13:00',
event1_count : 130,
event2_count : 50,
event3_count : 200
},
{
_id: '04/25/2015 13:10',
event1_count : 230,
event2_count : 20,
event3_count : 400
}
文档\u id:'04/25/2015 13:00'
简单地说,它包含了所有在04/25/2015 13:00和04/25/2015 13:10之间到达的事件
最终,我希望在数据上运行不同的报告。例如-过去20分钟内的事件计数。
在过去20分钟内,我希望得到的事件计数结果是:
{
event1_count : 360,
event2_count : 70,
event3_count : 600
}
我的问题-有没有一种方法可以在一个查询中聚合来自不同文档的多个字段
顺便说一句,对我来说,将数据保持在10分钟的间隔是很重要的,因为其他报告需要这种时间分辨率。是的,这确实是可能的。假设您的集合将在上述结构中存储文档,您可以通过添加另一个字段(如
date
)来修改该结构,该字段将_id存储为ISODate,而不是字符串时间戳,以便您可以使用进行聚合。要进行转换,可以使用mongo的游标方法对运算符进行原子更新:
db.collection.find().forEach(function (doc){
var dateObject = new Date(doc._id);
db.collection.update({_id: doc._id}, { $set: { date: dateObject } });
});
上述操作将在文档中创建一个额外字段date
,该字段包含\u id
字符串的ISODate对象表示形式
假设在上述更新之后,您的集合中现在有以下示例文档:
/* 0 */
{
"_id" : "04/25/2015 13:00",
"event1_count" : 130,
"event2_count" : 50,
"event3_count" : 200,
"date" : ISODate("2015-04-25T13:00:00.000Z")
}
/* 1 */
{
"_id" : "04/25/2015 13:10",
"event1_count" : 230,
"event2_count" : 20,
"event3_count" : 400,
"date" : ISODate("2015-04-25T13:10:00.000Z")
}
/* 2 */
{
"_id" : "04/25/2015 13:20",
"event1_count" : 240,
"event2_count" : 30,
"event3_count" : 350,
"date" : ISODate("2015-04-25T13:20:00.000Z")
}
/* 3 */
{
"_id" : "04/25/2015 13:30",
"event1_count" : 180,
"event2_count" : 60,
"event3_count" : 500,
"date" : ISODate("2015-04-25T13:30:00.000Z")
}
以下聚合管道将根据20分钟的间隔为您提供所需的结果:
var interval = 20,
pipeline = [
{
"$group": {
"_id": {
"year": { "$year": "$date" },
"dayOfYear": { "$dayOfYear": "$date" },
"interval": {
"$subtract": [
{ "$minute": "$date" },
{ "$mod": [{ "$minute": "$date" }, interval ] }
]
}
},
"event1_count": { "$sum": "$event1_count" },
"event2_count": { "$sum": "$event2_count" },
"event3_count": { "$sum": "$event3_count" }
}
},
{
"$project": {
"_id": 0,
"event1_count": 1,
"event2_count": 1,
"event3_count": 1
}
}
];
db.collection.aggregate(pipeline);
输出:
/* 0 */
{
"result" : [
{
"event1_count" : 420,
"event2_count" : 90,
"event3_count" : 850
},
{
"event1_count" : 360,
"event2_count" : 70,
"event3_count" : 600
}
],
"ok" : 1
}
在我的问题中,您可以看到2个文档。每个文档都有几个字段-event1\u count、event2\u count等。我想对两个文档中的event\u count1求和,event\u count2也是如此。所以结果应该是事件计数1的和,事件计数2的和,依此类推。我在一个查询中寻找实现这一点的方法,假设我还有很多其他事件,而不是像我的示例中那样只有3个。@assafm不用担心:-)