ใช้ $unwind แยกอาร์เรย์ แล้ว $group นับจำนวน แล้ว $match กรองที่มากกว่า 1 เพื่อหาค่าซ้ำใน inner array สร้างคอลเลกชันตัวอย่าง (มี Chris ซ้ำ 2 ครั้ง):
> db.demo347.insertOne({"details": {"details1": [{Name: "Chris", Age: 21}]}});
{ "acknowledged" : true, "insertedId" : ObjectId("5e5532eaf8647eb59e5620af") }
> db.demo347.insertOne({"details": {"details1": [{Name: "David", Age: 22}]}});
{ "acknowledged" : true, "insertedId" : ObjectId("5e55330af8647eb59e5620b0") }
> db.demo347.insertOne({"details": {"details1": [{Name: "Chris", Age: 21}]}});
{ "acknowledged" : true, "insertedId" : ObjectId("5e55331cf8647eb59e5620b1") }
แสดงข้อมูล:
> db.demo347.find();
คิวรีหาค่า Name ที่ซ้ำใน details.details1:
> db.demo347.aggregate([
{"$unwind": "$details"},
{"$unwind": "$details.details1"},
{"$group" : { "_id": "$details.details1.Name", "count": { "$sum": 1 } }},
{"$match": { "_id" :{ "$ne" : null } , "count" : { "$gt": 1} }}
])
ผลลัพธ์ (เจอ Chris ซ้ำ 2 ครั้ง):
{ "_id" : "Chris", "count" : 2 }
คำอธิบาย Pipeline
$unwind: "$details": แยกอาร์เรย์ details (แม้จะมี 1 สมาชิก)$unwind: "$details.details1": แยกอาร์เรย์ details1$group: จัดกลุ่มตาม Name นับจำนวนด้วย $sum: 1$match: กรองเฉพาะ count > 1 (ซ้ำ) และ _id ไม่เป็น null
ประโยชน์
วิธีนี้หาค่า duplicate ได้แม้ข้อมูลกระจายอยู่ในหลายเอกสาร และหลายระดับของอาร์เรย์