หา Group ของเอกสารที่ Share สมาชิกในอาร์เรย์
ใช้ $unwind แยกสมาชิก, $group รวม _id ตามสมาชิก, แล้ว $match หากลุ่มที่มีสมาชิกร่วมกันมากกว่า 1
ตัวอย่างข้อมูล
> db.demo456.insertOne({ _id: 101, StudentName: ["Chris", "David"] });
> db.demo456.insertOne({ _id: 102, StudentName: ["Mike", "Sam"] });
> db.demo456.insertOne({ _id: 103, StudentName: ["John", "Jace"] });
> db.demo456.insertOne({ _id: 104, StudentName: ["Robert", "John"] });
Query Aggregate หากลุ่มที่มีสมาชิกร่วม
> db.demo456.aggregate([
{ $unwind: "$StudentName" },
{ $group: { _id: "$StudentName", combine: { $addToSet: "$_id" }, size: { $sum: 1 } } },
{ $match: { size: { $gt: 1 } } },
{ $project: { _id: 1, combine: 1, size: 1, combine1: "$combine" } },
{ $unwind: "$combine" },
{ $unwind: "$combine1" },
{ $group: { _id: "$combine", l: { $first: "$_id" }, size: { $sum: 1 }, set: { $addToSet: "$combine1" } } },
{ $sort: { size: 1 } },
{ $group: { _id: "$l", combineIds: { $last: "$set" }, size: { $sum: 1 } } },
{ $match: { size: { $gt: 1 } } }
]);
ผลลัพธ์
{ "_id": "John", "combineIds": [103, 104], "size": 2 }
คำอธิบายตรรกะ
- แยก StudentName ทั้งหมด พร้อมเก็บ _id ของเอกสารต้นทาง
- จัดกลุ่มตาม StudentName หา combine (ชุด _id) และนับ size
- กรองเฉพาะชื่อที่ปรากฏในเอกสารมากกว่า 1 (size > 1)
- สร้างคู่ของ _id ที่ share ชื่อเดียวกัน
- จัดกลุ่มใหม่เพื่อหาชุด _id ที่เชื่อมต่อกัน (connected components)
การประยุกต์ใช้
เหมาะสำหรับ: การหา Community detection, Social network analysis, Duplicate detection, Graph traversal ในข้อมูลแบบ Document