mongodb - 获取 MongoDB 聚合管道中 $group 之后的输入文档中的字段

标签 mongodb mongodb-query aggregation-framework

我面临的问题是如何在一次分组操作后访问原始文档,并在MongoDB中的聚合管道中携带$group后面的字段。

例如:[分组、展开、分组]

原始文件是:

{
"_id" : ObjectId("361de42f1938e89b179dda42"),
"user_id" : ObjectId("9424021bafbde55512e39b83"),
"candidate_id" : ObjectId("54f65356294160421ead3ca1")
"OVERALL_SCORE" : 150,
"SCORES" : [ 
    { "NAME" : "asd", "OBTAINED_SCORE" : 28}, { "NAME" : "acd", "OBTAINED_SCORE" : 36 }, { "NAME" : "abc", "OBTAINED_SCORE" : 40}
 ]
}

聚合函数:

 db.coll.aggregate([ $group : { _id : { user_id : "$user_id"}, BEST_SCORE : { $max : "$OVERALL_SCORE"}, AVG_SCORE : { $avg : "$OVERALL_SCORE" }}} ])

以下是示例输出(第一组之后):

{
"result" : [ 
    {
        "_id" : {
            "user_id" : ObjectId("9424021bafbde55512e39b83")
        },
        "BEST_SCORE" : 150,
        "AVG_SCORE" : 132
    }
],
"ok" : 1
 }

问题是:(不知道是否可以实现) 我想要原始文档中的字段(聚合的输入)。

例如: 1) 展开原始文档中的“SCORES”,并按“candidate_id”、“user_id”展开下一组。

2) 我希望“BEST_SCORE”、“AVG_SCORE”(第一组之后)字段也能在第二组中访问。

聚合函数应如下所示:

   db.coll.aggregate([ $group : { _id : { user_id : "$user_id"}, BEST_SCORE : { $max : "$OVERALL_SCORE"}, AVG_SCORE : { $avg : "$OVERALL_SCORE" }}}, { $unwind : "$SCORES"}, /*problem is--after group operation "SCORES" field which is in original document not available */ { $group : _id : { NAME: "$SCORES.NAME"}, AVG_OBTAINED_SCORE: { $avg : "$SCORES.OBTAINED_SCORE"}} **/*problem is--this is also in the original document*/** ])

输出应如下所示:

   "BEST_SCORE": 150,                     //after 1st group
  "AVG_SCORE": 132,                       //after 1st group
  "SCORES": [                             //problem --- unwind "SCORES" and then group which is actually will not be available after 1st group (get this from original document)
    {
      "NAME": "abc",
      "AVG_OBTAINED_SCORE": 25.5
    },
    {
      "NAME": "asd",
      "AVG_OBTAINED_SCORE": 24
    },
    {
      "NAME": "acd",
      "AVG_OBTAINED_SCORE": 32
    }
  ]

谁能帮帮我。

谢谢

最佳答案

当您想要保留组中所有考虑文档的值时,您需要使用 $push 。问题是,这是一个数组。所以你处理$unwind两次,也有两个$group阶段:

db.coll.aggregate([
    {  "$group" : { 
        "_id": "$user_id", 
        "BEST_SCORE": { "$max": "$OVERALL_SCORE" },
        "AVG_SCORE": { "$avg": "$OVERALL_SCORE" },
        "SCORES": { "$push": "SCORES" }
    }}, 

    // SCORES in an array of arrays. Unwind twice
    { "$unwind": "$SCORES" },
    { "$unwind": "$SCORES" },

    // Group for averages on elements
    { "$group": {
        "_id": {
            "user_id": "$_id",
            "NAME": "$SCORES.name"
        },
        "BEST_SCORE": { "$first": "$BEST_SCORE" },
        "AVG_SCORE": { "$first": "$AVG_SCORE" }
        "AVG_OBTAINED_SCORE": { "$avg": "$SCORES.OBTAINED_SCORE" } 
    }},

    // Group to user_id
    { "$group": {
        "user_id": "$_id.user_id",
        "BEST_SCORE": { "$first": "$BEST_SCORE" },
        "AVG_SCORE": { "$first": "$AVG_SCORE" }
        "SCORES": { "$push": {
            "NAME": "$_id.NAME",
            "AVG_OBTAINED_SCORE": "$AVG_OBTAINED_SCORE"
        }}     
    }}
])

您可能会考虑在第一个 $group 之前使用 $unwind,但如果这样做,计算出的平均值将受到中存在的元素数量的影响正在“解绕”的数组。所以这里“double $unwind”是一个必要的过程。

关于mongodb - 获取 MongoDB 聚合管道中 $group 之后的输入文档中的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28979272/

相关文章:

mongodb - 如何在mongodb中对map reduce结果执行mapreduce

mongodb - mongodb 中数组元素的搜索查询

javascript - 持久化对象之间的 MongoDB 原型(prototype)继承

node.js - 查询名字、姓氏作为全名

mongodb - 如何在mongodb中获取两个日期的差异总和

java - 如何将 Sum SQL 与 Spring Data MongoDB 一起使用?

具有来自多个文档的数组对象值总和的 MongoDB 聚合

mongodb - mongodb写锁发生在什么级别?

mongodb - 如何找出 MongoDB 稀疏索引中包含多少个对象?

node.js - 我收到 Mongoose 未定义的错误