mongoose:聚合和计数

我有一个NodeJS / MongoDB应用程序,其数据存储在一个名为"Feedback"的集合中。 数据如下所示:

 [ { "__v": 0, "_id": "57d6b2d09f46ca14440ac14e", "customerFeedback": [ { "_id": "57d6b2d09f46ca14440ac14f", "answer": [ { "_id": "57d6b2d09f46ca14440ac150", "answerValue": "cat", "answerWeight": 0 } ], "question": "What is your favourite thing about this shop?", "questionId": "57d65edc0132461120fa0afd" }, { "_id": "57d6b2d09f46ca14440ac151", "answer": [ { "_id": "57d6b2d09f46ca14440ac152", "answerValue": "Okay", "answerWeight": 0 } ], "question": "How was your experience today?", "questionId": "57d69ef6dbb25611e46e6bc9" } ], "shopId": "SH0001", "feedbackCreatedOn": "2016-09-12T13:51:12.703Z", "questionsForDay": "2016-09-12T00:00:00Z" }, { "__v": 0, "_id": "57d6b3389f46ca14440ac157", "customerFeedback": [ { "_id": "57d6b3389f46ca14440ac158", "answer": [ { "_id": "57d6b3389f46ca14440ac159", "answerValue": "cat", "answerWeight": 0 } ], "question": "What is your favourite thing about this shop?", "questionId": "57d65edc0132461120fa0afd" }, { "_id": "57d6b3389f46ca14440ac15a", "answer": [ { "_id": "57d6b3389f46ca14440ac15b", "answerValue": "Very Good", "answerWeight": 0 } ], "question": "How was your experience today?", "questionId": "57d69ef6dbb25611e46e6bc9" }, { "_id": "57d6b3389f46ca14440ac15c", "answer": [ { "_id": "57d6b3389f46ca14440ac15d", "answerValue": "Cost", "answerWeight": 0 } ], "question": "What would you like us to improve on?", "questionId": "57d6b32d9f46ca14440ac153" } ], "shopId": "SH0001", "feedbackCreatedOn": "2016-09-12T13:52:56.939Z", "questionsForDay": "2016-09-12T00:00:00Z" }, { "__v": 0, "_id": "57d6c8eb97157f10a4e5c2e7", "customerFeedback": [ { "_id": "57d6c8eb97157f10a4e5c2e8", "answer": [ { "_id": "57d6c8eb97157f10a4e5c2ea", "answerValue": "Customer Experience", "answerWeight": 0 }, { "_id": "57d6c8eb97157f10a4e5c2e9", "answerValue": "Others", "answerWeight": 0 } ], "question": "What would you like us to improve on?", "questionId": "57d6b7d99ee61e47f01e5334" } ], "shopId": "SH0003", "feedbackCreatedOn": "2016-09-12T15:25:31.724Z", "questionsForDay": "2016-09-12T00:00:00Z" } ] 

结果数组中有很多这样的条目,但是上面的数据用来说明它。

我的问题是,对于给定的shopIdquestionId ,我想要统计每个单独的answerValue发生的次数。 我该怎么做?

我能够使用find方法将结果过滤到所需的数据集(例如)

 db.Feedback.find({shopId:"SH0001",'customerFeedback.questionId':"57d65edc0132461120fa0afd"}) 

但我不知道如何将数据聚合到我想要的格式。

这条pipe道应该给你想要的结果

 db.getCollection("yourCollection").aggregate([ { $unwind: "$customerFeedback" }, { $unwind: "$customerFeedback.answer" }, { $group: { _id: { shopId: "$shopId", questionId: "$customerFeedback.questionId", answerValue: "$customerFeedback.answer.answerValue" }, count: { $sum: 1 } } } ]) 

为您的示例数据提供以下输出

 /* 1 */ { "_id" : { "shopId" : "SH0003", "questionId" : "57d6b7d99ee61e47f01e5334", "answerValue" : "Others" }, "count" : 1.0 } /* 2 */ { "_id" : { "shopId" : "SH0003", "questionId" : "57d6b7d99ee61e47f01e5334", "answerValue" : "Customer Experience" }, "count" : 1.0 } /* 3 */ { "_id" : { "shopId" : "SH0001", "questionId" : "57d65edc0132461120fa0afd", "answerValue" : "cat" }, "count" : 2.0 } /* 4 */ { "_id" : { "shopId" : "SH0001", "questionId" : "57d69ef6dbb25611e46e6bc9", "answerValue" : "Okay" }, "count" : 1.0 } /* 5 */ { "_id" : { "shopId" : "SH0001", "questionId" : "57d6b32d9f46ca14440ac153", "answerValue" : "Cost" }, "count" : 1.0 } /* 6 */ { "_id" : { "shopId" : "SH0001", "questionId" : "57d69ef6dbb25611e46e6bc9", "answerValue" : "Very Good" }, "count" : 1.0 } 

当然,如果您只是对特定值感兴趣,您可以使用额外的$匹配阶段过滤结果


更新由于评论:

要用$match过滤结果,可以在展开如此的客户反馈的嵌套数组之后使用它

 ... { $unwind: "$customerFeedback" }, { $match: { shopId: "SH0001", "customerFeedback.questionId": "57d65edc0132461120fa0afd" } }, { $unwind: "$customerFeedback.answer" }, { $group: { _id: { shopId: "$shopId", questionId: "$customerFeedback.questionId", answerValue: "$customerFeedback.answer.answerValue" }, count: { $sum: 1 } } } ... 

这将导致

 { "_id" : { "shopId" : "SH0001", "questionId" : "57d65edc0132461120fa0afd", "answerValue" : "cat" }, "count" : 2.0 } 

如果您在shopId和/或customerFeedback.questionId上有大量文档或索引,那么您可能希望将$match阶段复制到pipe道的前端,以便仅shopId相应商店的文档,并且至less一个所需问题的反馈。 所以,从正确的angular度来看(可选的优化),看起来是这样的

 ... { $match: { shopId: "SH0001", "customerFeedback.questionId": "57d65edc0132461120fa0afd" } }, { $unwind: "$customerFeedback" }, { $match: { shopId: "SH0001", "customerFeedback.questionId": "57d65edc0132461120fa0afd" } }, { $unwind: "$customerFeedback.answer" }, { $group: { _id: { shopId: "$shopId", questionId: "$customerFeedback.questionId", answerValue: "$customerFeedback.answer.answerValue" }, count: { $sum: 1 } } } ...