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

ใช้ $addFields Pipeline ร่วม $filter Operator ใน MongoDB

การ filter array elements ใน MongoDB aggregate โดยเก็บ field อื่นๆ ไว้เหมือนเดิม ใช้ $addFields ร่วมกับ $filter แทน $project ที่ต้องระบุทุก field

สร้างคอลเลกชันและข้อมูลตัวอย่าง

> db.demo118.insertOne({
  "Id" : "101",
  "Name" : "Chris",
  "Subjects" : ["MySQL", "MongoDB", "Java"],
  "Details" : [
    { "Name" : "David", "S": "MongoDB" },
    { "Name" : "Bob", "S": "Python" }
  ]
});
{ "acknowledged" : true, "insertedId" : ObjectId("5e2f0c0cd8f64a552dae6364") }

แสดงข้อมูล

> db.demo118.find();

ผลลัพธ์: มี Subjects array และ Details array (มี field S)

Query Filter Details ให้เหลือเฉพาะที่ S อยู่ใน Subjects

> db.demo118.aggregate([
  {
    "$addFields": {
      "Details": {
        "$filter": {
          "input": "$Details",
          "as": "out",
          "cond": { "$in": ["$$out.S", "$Subjects"] }
        }
      }
    }
  }
]).pretty();

คำอธิบาย:

  • $addFields: แทนที่ field Details เดิมด้วยผลลัพธ์ที่ filter แล้ว คง field อื่นๆ ไว้ทั้งหมด (ต่างจาก $project)
  • $filter: วนลูป input array ($Details) ตัวแปร $$out
  • $in: ["$$out.S", "$Subjects"]: ตรวจสอบว่า field S ของ element อยู่ใน array Subjects หรือไม่

ผลลัพธ์

{ "_id" : ObjectId("5e2f0c0cd8f64a552dae6364"), "Id" : "101", "Name" : "Chris",
  "Subjects" : [ "MySQL", "MongoDB", "Java" ],
  "Details" : [ { "Name" : "David", "S" : "MongoDB" } ] }

เหลือเฉพาะ David (S="MongoDB" อยู่ใน Subjects) Bob ถูก filter ออก (S="Python" ไม่อยู่ใน Subjects)

เปรียบเทียบ $addFields vs $project

ใช้ $filter หลายเงื่อนไข

{ $addFields: {
  Details: {
    $filter: {
      input: "$Details",
      cond: {
        $and: [
          { $in: ["$$this.S", "$Subjects"] },
          { $ne: ["$$this.Name", "Bob"] }
        ]
      }
    }
  }
}}

Filter Array of Primitive Values

db.collection.aggregate([
  { $addFields: {
    numbers: {
      $filter: { input: "$numbers", cond: { $gt: ["$$this", 10] } }
    }
  }}
])

สรุป: $addFields + $filter = วิธีสะดวกที่สุดในการ filter array ใน pipeline โดยไม่สูญเสีย field อื่นๆ

Feature$addFields$project
คง field เดิม✓ อัตโนมัติ✗ ต้องระบุทุก field
เพิ่ม field ใหม่✓✓
ลบ field✗ (ต้อง $project ต่อ)✓ (0: false)
Rename field✗✓