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

การรวมค่าที่ไม่ซ้ำกันจากอาร์เรย์หลายชุดใน MongoDB ด้วย Aggregation

รวมค่า Unique จากอาร์เรย์หลายชุดในคอลเลกชันต่างกันด้วย $setUnion และ $addToSet

เมื่อต้องการรวมค่าที่ไม่ซ้ำกัน (Unique Values) จากอาร์เรย์ในหลายเอกสารหรือหลายฟิลด์ ให้ใช้ Aggregation Pipeline พร้อม $setUnion, $concatArrays, และ $addToSet

ตัวอย่างข้อมูลทดสอบ (2 เอกสาร ฟิลด์ต่างกัน)

> db.demo420.insert({ "details": [{ "Value1": 10, "Value2": 20, "Value3": 30 }] });
> db.demo420.insert({ "Info": [{ "Value1": 10, "Value2": 20, "Value3": 300 }] });

แสดงข้อมูล

> db.demo420.find();

ผลลัพธ์:

{ "_id": ObjectId("..."), "details": [{ "Value1": 10, "Value2": 20, "Value3": 30 }] }
{ "_id": ObjectId("..."), "Info": [{ "Value1": 10, "Value2": 20, "Value3": 300 }] }

คำสั่ง Aggregation รวมค่า Unique จากทั้งสองฟิลด์

> db.demo420.aggregate([
  { $project: {
    _id: 0,
    unique: {
      $filter: {
        input: {
          $setDifference: [
            { $concatArrays: ["$Info.Value1", "$Info.Value2", "$Info.Value3"] },
            []
          ]
        },
        cond: { $ne: ["$$this", ""] }
      }
    }
  }},
  { $unwind: "$unique" },
  { $group: { _id: null, uniqueArray: { $addToSet: "$unique" } } }
]);

ผลลัพธ์ที่ได้

{ "_id": null, "uniqueArray": [300, 20, 10] }

คำอธิบายขั้นตอน (ซับซ้อนเนื่องจากโครงสร้างข้อมูล)

  1. $concatArrays: รวมอาร์เรย์ Value1, Value2, Value3 ของฟิลด์ Info เข้าด้วยกัน
  2. $setDifference: [combined, []]: ลบค่าว่าง (แต่ที่นี่ไม่มีผลเพราะไม่มีค่าว่าง)
  3. $filter: กรองค่าว่าง (cond: $$this != "")
  4. $unwind: แยกอาร์เรย์ unique เป็นเอกสารต่อเอกสาร
  5. $group + $addToSet: รวมค่าที่ไม่ซ้ำกันกลับเป็นอาร์เรย์ uniqueArray

วิธีที่ง่ายกว่า (ถ้าข้อมูลอยู่ในฟิลด์เดียวกัน)

> db.collection.aggregate([
  { $unwind: "$arrayField" },
  { $group: { _id: null, uniqueValues: { $addToSet: "$arrayField" } } }
]);

ตัวดำเนินการเซต (Set Operators) สำหรับอาร์เรย์

ประโยชน์

เหมาะสำหรับการหาค่าที่ไม่ซ้ำรวมทั้งระบบ เช่น Tags ทั้งหมด, Categories ทั้งหมด, Unique Visitors ฯลฯ

Operatorคำอธิบาย
$setUnionรวมอาร์เรย์ทั้งหมด ไม่ซ้ำ (Union)
$setIntersectionค่าที่ซ้ำในทุกอาร์เรย์ (Intersection)
$setDifferenceค่าในอาร์เรย์แรก ที่ไม่อยู่ในอาร์เรย์อื่น (Difference)