Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MongoDB

จับคู่และจัดกลุ่มสมาชิกอาร์เรย์ด้วยค่าสูงสุดใน MongoDB Aggregation

เพื่อจับคู่และจัดกลุ่มสมาชิกในอาร์เรย์โดยใช้ค่าสูงสุด (max value) ให้ใช้ $group ร่วมกับ $max ใน MongoDB Aggregation Pipeline มาสร้างข้อมูลตัวอย่าง

> db.demo510.insertOne({
...   details: [
...     { Name: "Chris", Score: 56 },
...     { Name: "David", Score: 45 }
...   ]
... });
{ "acknowledged" : true, "insertedId" : ObjectId("5e8845fa987b6e0e9d18f582") }
> db.demo510.insertOne({
...   details: [
...     { Name: "Chris", Score: 56 },
...     { Name: "David", Score: 47 }
...   ]
... });
{ "acknowledged" : true, "insertedId" : ObjectId("5e8845fb987b6e0e9d18f583") }
> db.demo510.insertOne({
...   details: [
...     { Name: "Chris", Score: 45 },
...     { Name: "David", Score: 91 }
...   ]
... });
{ "acknowledged" : true, "insertedId" : ObjectId("5e8845fb987b6e0e9d18f584") }

แสดงข้อมูลทั้งหมด:

> db.demo510.find();
{ "_id" : ObjectId("5e8845fa987b6e0e9d18f582"), "details" : [ { "Name" : "Chris", "Score" : 56 }, { "Name" : "David", "Score" : 45 } ] }
{ "_id" : ObjectId("5e8845fb987b6e0e9d18f583"), "details" : [ { "Name" : "Chris", "Score" : 56 }, { "Name" : "David", "Score" : 47 } ] }
{ "_id" : ObjectId("5e8845fb987b6e0e9d18f584"), "details" : [ { "Name" : "Chris", "Score" : 45 }, { "Name" : "David", "Score" : 91 } ] }

คิวรี Aggregation สำหรับหาค่าสูงสุดของแต่ละคน

> db.demo510.aggregate([
...   { "$project": {
...     "details": {
...       "$arrayElemAt": [
...         { "$filter": {
...           "input": "$details",
...           "as": "res",
...           "cond": {
...             "$eq": [
...               "$$res.Score",
...               { "$max": {
...                 "$map": {
...                   "input": "$details",
...                   "as": "out",
...                   "in": "$$out.Score"
...                 }
...               }}
...             ]
...           }
...         }},
...         0
...       ]
...     }
...   }},
...   { "$group": {
...     "_id": "$details.Name",
...     "Name": { "$first": "$details.Name" },
...     "count": { "$sum": 1 }
...   }}
... ]);

ผลลัพธ์ - แสดงชื่อและจำนวนครั้งที่ได้คะแนนสูงสุด:

{ "_id" : "David", "Name" : "David", "count" : 1 }
{ "_id" : "Chris", "Name" : "Chris", "count" : 2 }

คำอธิบาย

  • $project + $filter + $max: กรองเฉพาะสมาชิกที่มีคะแนนเท่ากับค่าสูงสุดในอาร์เรย์ details ของแต่ละเอกสาร
  • $group: จัดกลุ่มตามชื่อและนับจำนวนครั้งที่แต่ละคนได้คะแนนสูงสุด

หมายเหตุ: คิวรีนี้ซับซ้อนเพื่อสาธิตการใช้ $filter, $map, $max ร่วมกัน ในทางปฏิบัติอาจใช้ $unwind ก่อนแล้วค่อย $sort และ $group จะเข้าใจง่ายกว่า