MongoDB聚合查询
在MongoDB中,我有一个收藏:MongoDB聚合查询,mongodb,output,aggregation-framework,Mongodb,Output,Aggregation Framework,在MongoDB中,我有一个收藏: Statistics { UserID: int //User id Url: string //Url Clicks: [DateTime] //A time array } 当用户单击url时,在clicks数组中添加click date的日期。我的问题是如何编写一个聚合查询,比如从[date1]到[date2]的点击次数以及按用户ID分组?如何将、输出到文件 谢谢 假设您有这
Statistics
{
UserID: int //User id
Url: string //Url
Clicks: [DateTime] //A time array
}
当用户单击url时,在clicks数组中添加click date的日期。我的问题是如何编写一个聚合查询,比如从[date1]到[date2]的点击次数以及按用户ID分组?如何将、输出到文件
谢谢 假设您有这样的数据(请参见底部的如何生成): 以下是聚合函数:
db.test.aggregate( {
$match: {
clickDate: { $gte: new Date(2012,8,30,12,0,0) }
}
},
{
$group: {
_id: "$userid",
clicks: { $sum: 1 }
}
}
);
确保在$group
之前有$match
。看
结果:
{
"result": [
{ "_id": 8,
"clicks": 1
},
{ "_id": 7,
"clicks": 2
},
{ "_id": 6,
"clicks": 2
},
{ "_id": 3,
"clicks": 2
},
{ "_id": 2,
"clicks": 2
},
{ "_id": 1,
"clicks": 2
},
{ "_id": 4,
"clicks": 2
},
{ "_id": 0,
"clicks": 2
},
{ "_id": 5,
"clicks": 2
},
{ "_id": 9,
"clicks": 1
}
],
"ok": 1
}
数据是通过此循环生成的:
// d=days, m=months (for ISODate months start from 0, while days from 1)
for (var i = 0, d = 1, m = 0, id = 0; i < 100; i++, d++, m++, id++) {
if (d > 30){
d=1;
}
if (m > 10){
m=0;
}
if (id > 9){
id=0;
}
db.test.insert({userid: id, url:"", clickDate: new Date(2012,m,d,12,1,0)});
}
//d=天,m=月(对于ISODate月,从0开始,而天从1开始)
对于(变量i=0,d=1,m=0,id=0;i<100;i++,d++,m++,id++){
如果(d>30){
d=1;
}
如果(m>10){
m=0;
}
如果(id>9){
id=0;
}
插入({userid:id,url:,clickDate:newdate(2012,m,d,12,1,0)});
}
假设您有这样的数据(请参见底部的“如何生成此数据”):
以下是聚合函数:
db.test.aggregate( {
$match: {
clickDate: { $gte: new Date(2012,8,30,12,0,0) }
}
},
{
$group: {
_id: "$userid",
clicks: { $sum: 1 }
}
}
);
确保在$group
之前有$match
。看
结果:
{
"result": [
{ "_id": 8,
"clicks": 1
},
{ "_id": 7,
"clicks": 2
},
{ "_id": 6,
"clicks": 2
},
{ "_id": 3,
"clicks": 2
},
{ "_id": 2,
"clicks": 2
},
{ "_id": 1,
"clicks": 2
},
{ "_id": 4,
"clicks": 2
},
{ "_id": 0,
"clicks": 2
},
{ "_id": 5,
"clicks": 2
},
{ "_id": 9,
"clicks": 1
}
],
"ok": 1
}
数据是通过此循环生成的:
// d=days, m=months (for ISODate months start from 0, while days from 1)
for (var i = 0, d = 1, m = 0, id = 0; i < 100; i++, d++, m++, id++) {
if (d > 30){
d=1;
}
if (m > 10){
m=0;
}
if (id > 9){
id=0;
}
db.test.insert({userid: id, url:"", clickDate: new Date(2012,m,d,12,1,0)});
}
//d=天,m=月(对于ISODate月,从0开始,而天从1开始)
对于(变量i=0,d=1,m=0,id=0;i<100;i++,d++,m++,id++){
如果(d>30){
d=1;
}
如果(m>10){
m=0;
}
如果(id>9){
id=0;
}
插入({userid:id,url:,clickDate:newdate(2012,m,d,12,1,0)});
}
您是指将行分组的“组”还是按用户id排序的“组”,以便按一个用户id排序的所有URL都位于结果集中的同一区域?我的意思是组与排序不同。这就像SQL命令GROUP BY。我认为您的一些模式在这里丢失了,因为:“获取从[date1]到[date2]的点击次数”但是您没有数字,您的点击字段是一个日期时间字段,而不是显示点击次数的整数字段,并且在此之后只有URL字段。日期字段的名称是什么?Sammaye,字段的名称是Clicks。点击次数-点击数组中项目的长度。这是一个非常奇怪的模式。通常情况下,在这种情况下,每次单击都会生成一个文档。嗯,这确实让它变得有点困难,因为你要在一个日期时间内在多个文档的子文档中的多个元素中绑定范围…我将进行一些讨论。你是说“组”是指对行进行分组,还是说“组”是指按用户id排序,以便按一个用户id排序的所有URL都在结果集中的同一区域?我是说,组与排序不同。这就像SQL命令GROUP BY。我认为您的一些模式在这里丢失了,因为:“获取从[date1]到[date2]的点击次数”但是您没有数字,您的点击字段是一个日期时间字段,而不是显示点击次数的整数字段,并且在此之后只有URL字段。日期字段的名称是什么?Sammaye,字段的名称是Clicks。点击次数-点击数组中项目的长度。这是一个非常奇怪的模式。通常情况下,在这种情况下,每次单击都会生成一个文档。嗯,这确实让它变得有点困难,因为你在许多文档的子文档中的许多元素中绑定了一个日期时间范围…我将进行一些讨论。不幸的是,如评论中所述,他的日期实际上是一个数组,所以他想匹配文档中数组中的日期,然后$unwind这些(很可能)然后计算匹配的金额,然后按userID计算$group。基本上只对日期数组中匹配的日期进行$求和。不幸的是,如注释中所述,他的日期实际上是一个数组,因此他希望在文档中匹配数组中的日期,然后$展开这些日期(最有可能),然后计算匹配的金额,然后按userID对其进行$分组。基本上只对日期数组中的匹配日期进行$sum。