在一个查询中聚合多个组结果
Aggreage with many group results in one query
我想用 mongodb
中的一些数据填充 HTML table。即我有两列要填充。如何进行查询,即创建两列的聚合,即一个 $sum 第二个 $count,但 $count 应按 flag:0.
过滤
进行一次查询检索所有数据的方法是否正确?可能吗?
> db.test.find()
{ "_id" : ObjectId("55a"), "name" : "luk", "col1" : 1, "col2" : 4, "flag": 0}
{ "_id" : ObjectId("55b"), "name" : "luk", "col1" : 2, "col2" : 3, "flag": 0}
{ "_id" : ObjectId("55c"), "name" : "luk", "col1" : 2, "col2" : 5, "flag": 0}
{ "_id" : ObjectId("55d"), "name" : "luk", "col1" : 3, "col2" : 2, "flag": 1}
{ "_id" : ObjectId("56d"), "name" : "luk", "col1" : 3, "col2" : 2, "flag": 1}
{ "_id" : ObjectId("e5e"), "name" : "tom", "col1" : 2, "col2" : 1, "flag": 0}
{ "_id" : ObjectId("55f"), "name" : "tom", "col1" : 2, "col2" : 1, "flag": 0}
{ "_id" : ObjectId("660"), "name" : "tom", "col1" : 4, "col2" : 2, "flag": 1}
{ "_id" : ObjectId("561"), "name" : "tom", "col1" : 4, "col2" : 2, "flag": 1}
我要结果:
{ name:"luk", sumcol1:"11", count_col2:"3"},
{ name:"tom", sumcol1:"12", count_col2:"2"}
请注意,对于第一个分组 - sumcol1
我们获取所有文档,但是对于 count_col2
我们获取所有但未通过标志 过滤的文档(仅计算带有 flag:0 的文档)
在 SQL 中看起来像这样:
SELECT
name,
sum(col1) as suma_col1,
count(case when flag=0 then col2 end) as count_col2
FROM
table
group by name
或
select tab1.name, tab1.suma_col1, tab2.count_col2 FROM
(
SELECT
name,
sum(col1) as suma_col1
FROM
table
group by name
) as tab1
,
(
SELECT
name,
count(col2) as count_col2
FROM
table
where flag=0
group by name
) as tab2
where tab2.name = tab1.name
这可以使用 aggregation pipeline with $cond
实现。
db.test.aggregate([
{
'$group':
{
'_id': '$name',
'sumcol1': {'$sum': '$col1'},
'count_col2':
{
'$sum' :
{
$cond :
[
{$eq: [ "$flag", 0 ] },
1,
0
]
}
}
}
}
])
结果:-
{
"result" : [
{
"_id" : "tom",
"sumcol1" : 12,
"count_col2" : 2
},
{
"_id" : "luk",
"sumcol1" : 11,
"count_col2" : 3
}
],
"ok" : 1
}
我想用 mongodb
中的一些数据填充 HTML table。即我有两列要填充。如何进行查询,即创建两列的聚合,即一个 $sum 第二个 $count,但 $count 应按 flag:0.
进行一次查询检索所有数据的方法是否正确?可能吗?
> db.test.find()
{ "_id" : ObjectId("55a"), "name" : "luk", "col1" : 1, "col2" : 4, "flag": 0}
{ "_id" : ObjectId("55b"), "name" : "luk", "col1" : 2, "col2" : 3, "flag": 0}
{ "_id" : ObjectId("55c"), "name" : "luk", "col1" : 2, "col2" : 5, "flag": 0}
{ "_id" : ObjectId("55d"), "name" : "luk", "col1" : 3, "col2" : 2, "flag": 1}
{ "_id" : ObjectId("56d"), "name" : "luk", "col1" : 3, "col2" : 2, "flag": 1}
{ "_id" : ObjectId("e5e"), "name" : "tom", "col1" : 2, "col2" : 1, "flag": 0}
{ "_id" : ObjectId("55f"), "name" : "tom", "col1" : 2, "col2" : 1, "flag": 0}
{ "_id" : ObjectId("660"), "name" : "tom", "col1" : 4, "col2" : 2, "flag": 1}
{ "_id" : ObjectId("561"), "name" : "tom", "col1" : 4, "col2" : 2, "flag": 1}
我要结果:
{ name:"luk", sumcol1:"11", count_col2:"3"},
{ name:"tom", sumcol1:"12", count_col2:"2"}
请注意,对于第一个分组 - sumcol1
我们获取所有文档,但是对于 count_col2
我们获取所有但未通过标志 过滤的文档(仅计算带有 flag:0 的文档)
在 SQL 中看起来像这样:
SELECT
name,
sum(col1) as suma_col1,
count(case when flag=0 then col2 end) as count_col2
FROM
table
group by name
或
select tab1.name, tab1.suma_col1, tab2.count_col2 FROM
(
SELECT
name,
sum(col1) as suma_col1
FROM
table
group by name
) as tab1
,
(
SELECT
name,
count(col2) as count_col2
FROM
table
where flag=0
group by name
) as tab2
where tab2.name = tab1.name
这可以使用 aggregation pipeline with $cond
实现。
db.test.aggregate([
{
'$group':
{
'_id': '$name',
'sumcol1': {'$sum': '$col1'},
'count_col2':
{
'$sum' :
{
$cond :
[
{$eq: [ "$flag", 0 ] },
1,
0
]
}
}
}
}
])
结果:-
{
"result" : [
{
"_id" : "tom",
"sumcol1" : 12,
"count_col2" : 2
},
{
"_id" : "luk",
"sumcol1" : 11,
"count_col2" : 3
}
],
"ok" : 1
}