2017-12-18 228 views
0

我有如下嵌套的数据,MongoDB的总

{ 
"_id" : ObjectId("5a30ee450889c5f0ebc21116"), 
"academicyear" : "2017-18", 
"fid" : "be02", 
"fname" : "ABC", 
"fdept" : "Comp", 
"degree" : "BE", 
"class" : "1", 
"sem" : "8", 
"dept" : "Comp", 
"section" : "Theory", 
"subname" : "BDA", 
"fbValueList" : [ 
    { 
     "_id" : ObjectId("5a30eecd3e3457056c93f7af"), 
     "score" : 20, 
     "rating" : "Fair" 
    }, 
    { 
     "_id" : ObjectId("5a30eefd3e3457056c93f7b0"), 
     "score" : 10, 
     "rating" : "Fair" 
    }, 
    { 
     "_id" : ObjectId("5a337e53341bf419040865c4"), 
     "score" : 88, 
     "rating" : "Excellent" 
    }, 
    { 
     "_id" : ObjectId("5a337ee2341bf419040865c7"), 
     "score" : 75, 
     "rating" : "Very Good" 
    }, 
    { 
     "_id" : ObjectId("5a3380b583dde50ddcea350e"), 
     "score" : 72, 
     "rating" : "Very Good" 
    } 
] 
}, 
{ 
    "_id" : ObjectId("5a3764f1bc19b77dd9fd9a57"), 
    "academicyear" : "2017-18", 
    "fid" : "be02", 
    "fname" : "ABC", 
    "fdept" : "Comp", 
    "degree" : "BE", 
    "class" : "1", 
    "sem" : "5", 
    "dept" : "Comp", 
    "section" : "Theory", 
    "subname" : "BDA", 
    "fbValueList" : [ 
     { 
      "_id" : ObjectId("5a3764f1bc19b77dd9fd9a59"), 
      "score" : 88, 
      "rating" : "Excellent" 
     }, 
     { 
      "_id" : ObjectId("5a37667aee64bce1b14747d2"), 
      "score" : 74, 
      "rating" : "Good" 
     }, 
     { 
      "_id" : ObjectId("5a3766b3ee64bce1b14747dc"), 
      "score" : 74, 
      "rating" : "Good" 
     } 
    ] 
} 

我们正在尝试使用它进行聚合,

db.fbresults.aggregate([{$match:{academicyear:"2017-18",fdept:'Comp'}},{$group:{_id: {fname: "$fname", rating:"$fbValueList.rating"},count: {"$sum":1}}}]) 

,我们得到结果一样,

{ "_id" : { "fname" : "ABC", "rating" : [ "Fair","Fair","Excellent","Very Good", "Very Good", "Excellent", "Good", "Good" ] }, "count" : 2 } 

但我们期待的结果是,

{ "_id" : { "fname" : "ABC", "rating_group" : [ 
     { 
      rating: "Excellent" 
      count: 2 
     }, 
      { 
      rating: "Very Good" 
      count: 2 
     }, 
      { 
      rating: "Good" 
      count: 2 
     }, 
      { 
      rating: "Fair" 
      count: 2 
     }, 

    ] }, "count" : 2 } 

我们希望通过他们的名字获得个别教职人员小组,并根据他们的评级回应和评级数量在该小组内进行评估。

我们已经试过这一个,但我们没有结果。 Mongodb Aggregate Nested Group

+0

您正在使用哪个mongo版本? –

回答

2

这应该让你去:

db.collection.aggregate([{ 
    $match: { 
     academicyear: "2017-18", 
     fdept:'Comp' 
    } 
}, { 
    $unwind: "$fbValueList" // flatten the fbValueList array into multiple documents 
}, { 
    $group: { 
     _id: { 
      fname: "$fname", 
      rating:"$fbValueList.rating" 
     }, 
     count: { 
      "$sum": 1 // this will give us the count per combination of fname and fbValueList.rating 
     } 
    } 
}, { 
    $group: { 
     _id: "$_id.fname", // we only want one bucket per fname 
     rating_group: { 
      $push: { // we push the exact structure you were asking for 
       rating: "$_id.rating", 
       count: "$count" 
      } 
     }, 
     count: { 
      $avg: "$count" // this will be the average across all entries in the fname bucket 
     } 
    } 
}]) 
+0

感谢您的回答。它给了我想要的结果。再次感谢。 +1 –

0

这是一个长期聚集的管道,可能有一些聚集是联合国必要的,所以请检查并丢弃无论是无关紧要的。

注意:这将只适用于Mongo 3.4+

您需要使用$unwind,然后使用$group$push评级及其计数。

matchAcademicYear = { 
    $match: { 
     academicyear:"2017-18", fdept:'Comp' 
    } 
} 

groupByNameAndRating = { 
    $group: { 
     _id: { 
      fname: "$fname", rating:"$fbValueList.rating" 
     }, 
     count: { 
      "$sum":1 
     } 
    } 
} 

unwindRating = { 
    $unwind: "$_id.rating" 
} 

addFullRating = { 
    $addFields: { 
     "_id.full_rating": "$count" 
    } 
} 

replaceIdRoot = { 
    $replaceRoot: { 
     newRoot: "$_id" 
    } 
} 


groupByRatingAndFname = { 
    $group: { 
     _id: { 
      "rating": "$rating", 
      "fname": "$fname" 
     }, 
     count: {"$sum": 1}, 
     full_rating: {"$first": "$full_rating"} 
    } 
} 

addFullRatingAndCount = { 
    $addFields: { 
     "_id.count": "$count", 
     "_id.full_rating": "$full_count" 
    } 
} 

groupByFname = { 
    $group: { 
     _id: "$fname", 
     rating_group: { $push: {rating: "$rating", count: "$count"}}, 
     count: { $first: "$full_rating"} 
    }  
} 

db.fbresults.aggregate([ 
    matchAcademicYear, 
    groupByNameAndRating, 
    unwindRating, 
    addFullRating, 
    unwindRating, 
    replaceIdRoot, 
    groupByRatingAndFname, 
    addFullRatingAndCount, 
    replaceIdRoot, 
    groupByFname 
])