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

在MongoDB的聚合管道中,获取输入文档中$group之后的字段,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我面临的问题是,如何在一次组操作之后访问原始文档,以及如何在MongoDB的聚合管道中携带$group之后的字段 例如:[组、展开、组] 原始文件为: { "_id" : ObjectId("361de42f1938e89b179dda42"), "user_id" : ObjectId("9424021bafbde55512e39b83"), "candidate_id" : ObjectId("54f65356294160421ead3ca1") "OVERALL_SCORE" : 150,

我面临的问题是,如何在一次组操作之后访问原始文档,以及如何在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" }}} ])
以下是样本输出(第一组之后):

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

例如: 1) 按“候选人id”、“用户id”展开原始文档和下一组中的“分数”

2) 我想在第二组中也访问“最佳分数”、“平均分数”(第一组后)字段

聚合函数应如下所示:

   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
    }
  ]
输出应如下所示:

   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
    }
  ]
谁能帮我一下吗


感谢您使用要保留组中所有需要使用的文档的值的内容进行分组。问题是,这是一个数组。因此,您需要进行两次处理,并且有两个阶段:

db.coll.aggregate([
{“$group”:{
“\u id”:“$user\u id”,
“最佳成绩”:{“$max”:“$totall_SCORE”},
“平均得分”:{“$AVG”:“$totall_SCORE”},
“分数”:{“$push”:“分数”}
}}, 
//数组中的分数。展开两次
{“$diswind”:“$SCORES”},
{“$diswind”:“$SCORES”},
//元素平均值分组
{“$组”:{
“_id”:{
“用户id”:“$\u id”,
“名称”:“$SCORES.NAME”
},
“最佳分数”:{“$first”:“$BEST_分数”},
“平均得分”:{“$first”:“$AVG_得分”}
“平均获得分数”:{“$AVG”:“$SCORES.获得分数”}
}},
//组到用户\u id
{“$组”:{
“用户id”:“$\u id.user\u id”,
“最佳分数”:{“$first”:“$BEST_分数”},
“平均得分”:{“$first”:“$AVG_得分”}
“得分”{“$push”:{
“名称”:“$\u id.NAME”,
“平均获得分数”:“$AVG_获得分数”
}}     
}}
])

你可能会考虑在第一个代码> $组< /代码>之前使用<代码> $< /COD> >,但是如果你这样做了,那么计算的平均值会受到数组中元素“unun-伤口”的影响。因此,“双倍$REWIND”在这里是一个必要的过程。

这没有多大意义。您只能真正地“保留”在“分组键”中的内容,或者由其中一个分组运算符保留,就像您对其他值所做的那样,或者可以选择使用$last或$push之类的内容。保留其他字段的意义何在?最终结果如何。
$$ROOT
仅在调用聚合阶段引用“整个文档”。因此,一旦您在一个阶段中更改了文档,
$$ROOT
的值就是在另一个阶段中访问时更改的表单。在进行其他更改之前,您无法看到文档的外观。正如我之前所建议的,您的预期结果并不十分清楚。如果你编辑你的问题以显示你的期望,那么人们可能会就达到目标的方法提出建议。。希望现在事情变得更清楚了。你正在失去我们的
“name”:“asd”
应该来自哪里。除非它是“分数”数组文档的一部分,否则您可能在这里运气不好。它真的是那些数组文档中的一个元素吗?我们不要聊天了。答案不是肯定就是否定。否则,请更改问题的详细信息,以解释数据应来自何处。如果要将任何字段转入下一个管道操作员,我们需要使用$push或$addToSet。@user3805045您需要执行一些操作,但是这些都适用于此用例。$push和$addToSet之间的主要区别在于push添加的元素保持其顺序(无论在前几个阶段是什么),而$addToSet添加的元素没有特定的顺序: