Mongodb:没有map/reduce的每个数组位置的整数聚合数组
Mongodb: aggregate array of integers for each array position without map/reduce
我是 MongoDB 的新手。我想知道是否可以聚合数组中的每个 "column"。假设我们有以下文件:
db.test.insert([{"player": "A", "year": 2010, "value": [1, 1 ]},
{"player": "A", "year": 2011, "value": [2, 1 ]},
{"player": "A", "year": 2012, "value": [2, 1 ]},
{"player": "B", "year": 2010, "value": [1, 2 ]}])
预期的结果应该是这样的:
[
{
"player": "A",
"sum_result": [
5,
3
]
},
{
"player": "B",
"sum_result": [
1,
2
]
}
]
是否可以不使用 Map/Reduce 来做到这一点?下面 link 显示了一个 map/reduce 解决方案,但我正在寻找一种替代方法来实现相同的目标。谢谢!
Mongodb: aggregate array of integers for each array position
只有当文档中涉及的元素可以通过路径名到达时,大多数问题才能在聚合中得到解决。
在此示例中,values
数组元素 无法通过路径 values.0
或 values.1
到达 。
因此,要解决此类问题,您需要选择 map-reduce
,这提供了更大的灵活性。
不幸的是,在这种情况下,您无法使用聚合获得所需的输出,除非您更改架构。一个这样的例子是制作 values
字段 - 一个文档数组。这里值数组中的所有元素都可以通过 路径名 到达,例如 values.c1
(表示列 1
中的值)
db.t.insert([
{"player":"A","year":2010,"value":[ {"c1":1}, {"c2":1}]},
{"player":"A","year":2011,"value":[ {"c1":2}, {"c2":1}]},
{"player":"A","year":2012,"value":[ {"c1":2}, {"c2":1}]},
{"player":"B","year":2010,"value":[ {"c1":1}, {"c2":2}]}
])
然后您可以将其汇总如下:
db.t.aggregate([
{$unwind:"$value"},
{$group:{"_id":"$player",
"c1":{$sum:"$value.c1"},
"c2":{$sum:"$value.c2"}}},
{$group:{"_id":"$_id",
"c1":{$push:{"c1":"$c1"}},
"c2":{$push:{"c2":"$c2"}}}},
{$project:{"value":{$setUnion:["$c1","$c2"]}}}
])
o/p:
{ "_id" : "A", "value" : [ { "c1" : 5 }, { "c2" : 3 } ] }
{ "_id" : "B", "value" : [ { "c2" : 2 }, { "c1" : 1 } ] }
由于该解决方案涉及 $unwind 操作,成本很高,我建议您根据您的数据集衡量这两种解决方案的性能,然后选择最适合您的应用程序的解决方案。
感谢您的回复。更改架构可能是解决此问题的最佳方法。正如您所指出的, $unwind 操作的成本可能很高。我最终决定使用以下解决方案。
修改后的文档:
db.test.insert([{"player": "A", "year": 2010, "values": {"v1":1, "v2":1 }},
{"player": "A", "year": 2011, "values": {"v1":2, "v2":1 }},
{"player": "A", "year": 2012, "values": {"v1":2, "v2":1 }},
{"player": "B", "year": 2010, "values": {"v1":1, "v2":2 }}])
查询语句:
db.test.aggregate([
{$group:{"_id":"$player",
"v1":{$sum:"$values.v1"},
"v2":{$sum:"$values.v2"}}},
{$project:{"values":{"v1":"$v1","v2":"$v2"}}}
])
输出:
{
"result": [{
"_id": "B",
"values": {
"v1": 1,
"v2": 2
}
}, {
"_id": "A",
"values": {
"v1": 5,
"v2": 3
}
}],
"ok": 1
}
我是 MongoDB 的新手。我想知道是否可以聚合数组中的每个 "column"。假设我们有以下文件:
db.test.insert([{"player": "A", "year": 2010, "value": [1, 1 ]},
{"player": "A", "year": 2011, "value": [2, 1 ]},
{"player": "A", "year": 2012, "value": [2, 1 ]},
{"player": "B", "year": 2010, "value": [1, 2 ]}])
预期的结果应该是这样的:
[
{
"player": "A",
"sum_result": [
5,
3
]
},
{
"player": "B",
"sum_result": [
1,
2
]
}
]
是否可以不使用 Map/Reduce 来做到这一点?下面 link 显示了一个 map/reduce 解决方案,但我正在寻找一种替代方法来实现相同的目标。谢谢!
Mongodb: aggregate array of integers for each array position
只有当文档中涉及的元素可以通过路径名到达时,大多数问题才能在聚合中得到解决。
在此示例中,values
数组元素 无法通过路径 values.0
或 values.1
到达 。
因此,要解决此类问题,您需要选择 map-reduce
,这提供了更大的灵活性。
不幸的是,在这种情况下,您无法使用聚合获得所需的输出,除非您更改架构。一个这样的例子是制作 values
字段 - 一个文档数组。这里值数组中的所有元素都可以通过 路径名 到达,例如 values.c1
(表示列 1
中的值)
db.t.insert([
{"player":"A","year":2010,"value":[ {"c1":1}, {"c2":1}]},
{"player":"A","year":2011,"value":[ {"c1":2}, {"c2":1}]},
{"player":"A","year":2012,"value":[ {"c1":2}, {"c2":1}]},
{"player":"B","year":2010,"value":[ {"c1":1}, {"c2":2}]}
])
然后您可以将其汇总如下:
db.t.aggregate([
{$unwind:"$value"},
{$group:{"_id":"$player",
"c1":{$sum:"$value.c1"},
"c2":{$sum:"$value.c2"}}},
{$group:{"_id":"$_id",
"c1":{$push:{"c1":"$c1"}},
"c2":{$push:{"c2":"$c2"}}}},
{$project:{"value":{$setUnion:["$c1","$c2"]}}}
])
o/p:
{ "_id" : "A", "value" : [ { "c1" : 5 }, { "c2" : 3 } ] }
{ "_id" : "B", "value" : [ { "c2" : 2 }, { "c1" : 1 } ] }
由于该解决方案涉及 $unwind 操作,成本很高,我建议您根据您的数据集衡量这两种解决方案的性能,然后选择最适合您的应用程序的解决方案。
感谢您的回复。更改架构可能是解决此问题的最佳方法。正如您所指出的, $unwind 操作的成本可能很高。我最终决定使用以下解决方案。
修改后的文档:
db.test.insert([{"player": "A", "year": 2010, "values": {"v1":1, "v2":1 }},
{"player": "A", "year": 2011, "values": {"v1":2, "v2":1 }},
{"player": "A", "year": 2012, "values": {"v1":2, "v2":1 }},
{"player": "B", "year": 2010, "values": {"v1":1, "v2":2 }}])
查询语句:
db.test.aggregate([
{$group:{"_id":"$player",
"v1":{$sum:"$values.v1"},
"v2":{$sum:"$values.v2"}}},
{$project:{"values":{"v1":"$v1","v2":"$v2"}}}
])
输出:
{
"result": [{
"_id": "B",
"values": {
"v1": 1,
"v2": 2
}
}, {
"_id": "A",
"values": {
"v1": 5,
"v2": 3
}
}],
"ok": 1
}