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

วิธีดึงเอกสารที่มีออบเจ็กต์เฉพาะในอาร์เรย์ด้วย MongoDB


ใช้ Dot Notation ใน find() สำหรับ Query อาร์เรย์ของออบเจ็กต์

MongoDB รองรับการ query เข้าถึงฟิลด์ภายในออบเจ็กต์ที่อยู่ในอาร์เรย์ได้โดยตรงด้วย dot notation

ตัวอย่างข้อมูล

> db.demo465.insertOne({
  id: 101,
  details: [
    { Name: "Chris", Info: { Subject: "MongoDB", Marks: 67 } },
    { Name: "David", Info: { Subject: "MySQL", Marks: 78 } }
  ]
});
> db.demo465.insertOne({
  id: 102,
  details: [
    { Name: "Bob", Info: { Subject: "Java", Marks: 45 } },
    { Name: "Carol", Info: { Subject: "C", Marks: 67 } }
  ]
});

Query หาเอกสารที่มี details.Name = "Bob"

> db.demo465.find({ "details.Name": "Bob" });

ผลลัพธ์

{ "_id": ObjectId(...), "id": 102, "details": [{ "Name": "Bob", "Info": { "Subject": "Java", "Marks": 45 } }, { "Name": "Carol", "Info": { "Subject": "C", "Marks": 67 } }] }

คำอธิบาย

  • "details.Name" - MongoDB จะค้นหาในทุกอิลิเมนต์ของอาร์เรย์ details
  • ถ้าอิลิเมนต์ไหนมี Name = "Bob" เอกสารทั้งฉบับจะถูกคืน (รวมอิลิเมนต์อื่นในอาร์เรย์ด้วย)
  • ใช้ index ได้หากสร้าง index บน "details.Name"

เปรียบเทียบกับ $elemMatch

Queryพฤติกรรม
{ "details.Name": "Bob" }คืนเอกสารทั้งฉบับ (รวมอิลิเมนต์อื่นใน details)
{ details: { $elemMatch: { Name: "Bob" } } }คืนเอกสารทั้งฉบับ (เหมือนกันสำหรับเงื่อนไขเดียว)
{ details: { $elemMatch: { Name: "Bob", "Info.Marks": { $gt: 50 } } } }คืนเฉพาะเอกสารที่มีอิลิเมนต์ เดียวกัน ตรงทั้ง 2 เงื่อนไข

หากต้องการคืนเฉพาะอิลิเมนต์ที่ match

// ใช้ aggregation $filter
db.demo465.aggregate([
  { $match: { "details.Name": "Bob" } },
  { $project: { details: { $filter: { input: "$details", as: "d", cond: { $eq: ["$$d.Name", "Bob"] } } } } }
]);