如何展平来自聚合输出的 JSON 结果
Posted
技术标签:
【中文标题】如何展平来自聚合输出的 JSON 结果【英文标题】:How to flatten JSON result from aggregation output 【发布时间】:2018-09-02 23:09:02 【问题描述】:使用 mongo db 聚合我编写了以下 NodeJs api。我得到了输出,但没有得到我的预期输出,那么如何做到这一点,谁能帮我解决这个问题?
app.get('/polute', function (req, res)
Light.aggregate([
$match:
CREATE_DATE:
$lte:new Date(),
$gte: new Date(new Date().setDate(new
Date().getDate()-120)
)
,
$group:
_id:
month: $month: "$CREATE_DATE" ,
year: $year: "$CREATE_DATE"
,
avgofozone:$avg:"$OZONE"
,
$sort: "year": -1 ,
$project:
year: '$_id.year',
avgofozone: '$avgofozone',
month: '$_id.month',_id:0
], function (err, polute)
console.log("naresh:" +JSON.stringify(polute));
res.json(polute);
);
);
实际输出:
[
"avgofozone" : 21.07777777777778, "year" : 2018, "month" : 2
"avgofozone" : 17.8, "year" : 2018, "month" : 3
"avgofozone" : 17.8, "year" : 2018, "month" : 1
]
预期输出:
[
"zone_type": "avgofozone",
"year": 2018,
"February": 21.07777777777778,
"March": 17.8,
"January": 17.8
]
【问题讨论】:
【参考方案1】:在 MongoDb 3.6 和更高版本中,您可以利用 $arrayToObject
运算符和 $replaceRoot
管道来获得所需的 JSON 输出。您需要运行以下聚合管道:
const monthsEnum =
"_id": "year",
"1": "January",
"2": "February",
"3": "March",
"4": "April",
"5": "May",
"6": "June",
"7": "July",
"8": "August",
"9": "September",
"10": "October",
"11": "November",
"12": "December"
;
Light.aggregate([
"$match":
"CREATE_DATE":
"$lte": new Date(),
"$gte": new Date(new Date().setDate(new Date().getDate()-120))
,
"$group":
"_id":
"month": "$month": "$CREATE_DATE" ,
"year": "$year": "$CREATE_DATE"
,
"avgofozone": "$avg": "$OZONE"
,
"$group":
"_id": "$year",
"avgs":
"$push":
"k": "$substr": ["$month", 0, -1 ] ,
"v": "$avgofozone"
,
"$replaceRoot":
"newRoot":
"$mergeObjects": [
"$arrayToObject": "$avgs" ,
"$$ROOT"
]
,
"$project": "avgs": 0
], (err, data) =>
console.log("naresh:" +JSON.stringify(data));
const polute = Object.keys(data).reduce((p, c) => (...p, monthsEnum[c]: data[c]), );
res.json(polute);
)
对于仅使用聚合管道进行整形,您可以使用 $let
运算符将月份索引映射到数组中的值。考虑运行以下管道:
const MONTHS = [, "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
Light.aggregate([
"$match":
"CREATE_DATE":
"$lte": new Date(),
"$gte": new Date(new Date().setDate(new Date().getDate()-120))
,
"$group":
"_id":
"month": "$month": "$CREATE_DATE" ,
"year": "$year": "$CREATE_DATE"
,
"avgofozone": "$avg": "$OZONE"
,
"$group":
"_id": "$year",
"avgs":
"$push":
"k":
"$let":
"vars": "monthsList": MONTHS ,
"in": "$arrayElemAt": ["$$monthsList", "$month"]
,
"v": "$avgofozone"
,
"$replaceRoot":
"newRoot":
"$mergeObjects": [
"$arrayToObject": "$avgs" ,
"$$ROOT"
]
,
"$project": "avgs": 0
], (err, data) =>
console.log("naresh:" +JSON.stringify(data));
res.json(data);
)
【讨论】:
@chridam 任何可能的总查询只写聚合请建议我 @VARUN 我可以,你能指出我的问题的全部细节吗? @chridam 你写的查询非常正确,但输出相同,我会检查 robomongo 我没有得到输出,所以如果你可以在聚合中编写总查询以上是关于如何展平来自聚合输出的 JSON 结果的主要内容,如果未能解决你的问题,请参考以下文章