单个文档如下所示:
{
row: [
{ identifier: 'a', value: '2000-01-01' },
{ identifier: 'b', value: 5 },
{ identifier: 'c', value: 99 },
]
}
我想按年分组。更确切地说:identifier
a
的值应该是年份,identifier
c
的值应该相加。所以,结果应该是:
[
{ x: '2000', y: 105 },
{ x: '2001', y: 67 },
{ x: '2002', y: 99 }
]
{
$unwind: '$row'
}, {
$match: {
$or: [
{'row.identifier': 'a'},
{'row.identifier': 'c'}
]
}
}, {
$project: {
x: {
$cond: {
if: {$eq: ['$row.identifier', 'a']},
then: '$row.value',
else: '$$REMOVE'
}
},
y: {
$cond: {
if: {
$eq: ['$row.identifier', 'c']
},
then: '$row.value',
else: '$$REMOVE'
}
}
}
}, {
$group: {
_id: {
x: { $substr : ['$x', 0, 4 ] }
},
y: {
$sum: '$y'
}
}
}
它不会返回想要的结果。我不知道如何再次x
之后合并y
和$project
。或者整个方法可能效率不高。
答案 0 :(得分:2)
使用以下聚合查询。
[
{"$unwind":"$row"},
{"$match":{
"$or":[
{"row.identifier":"a"},
{"row.identifier":"c"}
]
}},
{"$group":{
"_id":{
"x":{
"$cond":[
{"$eq":["$row.identifier","a"]},
{"$substr":["$row.value",0,4]},
null
]
}
},
"y":{
"$sum":{
"$cond":[
{"$eq":["$row.identifier","c"]},
"$row.value",
0
]
}
}
}}
]
答案 1 :(得分:1)
我在尝试展开后尝试使用a
和c
并使用db.stackoverflow.insert({ row: [ { identifier: 'a', value: '2001-01-01' }, { identifier: 'b', value: 5 }, { identifier: 'c', value: 100 } ] })
和 db.stackoverflow.find()
{ "_id" : ObjectId("5aa5440e3e2cfe6e23b2de47"), "row" : [ { "identifier" : "a", "value" : "2000-01-01" }, { "identifier" : "b", "value" : 5 }, { "identifier" : "c", "value" : 99 } ] }
{ "_id" : ObjectId("5aa544143e2cfe6e23b2de48"), "row" : [ { "identifier" : "a", "value" : "2000-01-01" }, { "identifier" : "b", "value" : 5 }, { "identifier" : "c", "value" : 1 } ] }
{ "_id" : ObjectId("5aa544223e2cfe6e23b2de49"), "row" : [ { "identifier" : "a", "value" : "2001-01-01" }, { "identifier" : "b", "value" : 5 }, { "identifier" : "c", "value" : 1 } ] }
{ "_id" : ObjectId("5aa544263e2cfe6e23b2de4a"), "row" : [ { "identifier" : "a", "value" : "2001-01-01" }, { "identifier" : "b", "value" : 5 }, { "identifier" : "c", "value" : 100 } ] }
{ "_id" : ObjectId("5aa545853e2cfe6e23b2de4b"), "row" : [ { "identifier" : "a", "value" : "2001-01-01" }, { "identifier" : "b", "value" : 5 }, { "identifier" : "c", "value" : 1 } ] }
过滤行,因为它已经准备好了,它会获得所需的结果。
第1步:插入一些您提供的文件:
db.stackoverflow.aggregate([
{$unwind: "$row"},
{$match:
{$or: [ {"row.identifier": "a" }, {"row.identifier": "c"}]}
},
{
$project: {
yearstring: {
$cond: {
if: {$eq: ['$row.identifier', 'a']},
then: '$row.value',
else: '$$REMOVE'
}
},
valueString: {
$cond: {
if: { $eq: ['$row.identifier', 'c']},
then: '$row.value',
else: '$$REMOVE'
}
}
}
},
{
$group: {
_id: "$_id",
"row": {
"$push": {
"year": "$yearstring",
"value": "$valueString"
}
}
}
},
{
$project: {
_id: "$_id",
year: { $arrayElemAt: [ "$row.year", 0 ] },
value: {$arrayElemAt: ["$row.value", 0] }
}
},
{
$project: {
_id: 1,
year: { $substr: [ "$year", 0, 4 ] },
value: 1
}
},
{
$group: {
_id: "$year",
y: {$sum: "$value"}
}
}
])
第2步:查看插入的所有元素
{ "_id" : "2000", "y" : 100 }
{ "_id" : "2001", "y" : 102 }
第3步:聚合逻辑,从您提供的代码中复制的过滤条件:
{{1}}
步骤4:输出上述聚合:
{{1}}
你可以减少一些阶段。希望您能获得如何获得结果的想法。
您可以在我的github repo
上获取所有代码