การลบออบเจกต์ออกจากอาร์เรย์ซ้อน 2 ระดับ (Sub of Sub-array) ใช้ $pull ร่วมกับ Positional Operator $
> db.demo679.insertOne({
... id: 1,
... "details": [
... {
... CountryName: "US",
... "information": [
... {"Name": "Chris", "FirstName": "Name=Chris"},
... {"Name": "Bob", "FirstName": "Name=Bob"}
... ]
... },
... {
... CountryName: "UK",
... "information": [
... {"Name": "Robert", "FirstName": "Name=Robert"},
... {"Name": "Sam", "FirstName": "Name=Sam"}
... ]
... }
... ]
... });
{ "acknowledged" : true, "insertedId" : ObjectId("5ea442cf04263e90dac943fd") }
แสดงข้อมูล:
> db.demo679.find();
คิวรีลบ Bob ออกจาก information ของ CountryName = "US"
> db.demo679.update( ... {"details.CountryName": "US"}, ... {$pull: {"details.$.information": {"Name": "Bob", "FirstName": "Name=Bob"}}} ... ); WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })ผลลัพธ์ - Bob หายจาก US, UK คงเดิม:
คำอธิบาย
- Query: {"details.CountryName": "US"} - หาเอกสารที่มี details.CountryName = US
- Positional $: details.$.information - อ้างอิง information array ภายใน details object ที่ match
- $pull: {...} - ลบออบเจกต์ที่ match เงื่อนไขทั้งหมดใน information array
ข้อจำกัด Positional $
- อัปเดตได้แค่ 1 ระดับ (ไม่สามารถ $pull ใน details.$.information.$.deepArray ได้)
- Match ได้แค่ ออบเจกต์แรก ใน details array ที่ตรง CountryName = US
- MongoDB 3.6+ ใช้
arrayFiltersสำหรับ multi-level update
ArrayFilters (Modern Way)
db.demo679.updateOne(
{},
{$pull: {"details.$[outer].information": {Name: "Bob"}}},
{arrayFilters: [{"outer.CountryName": "US"}]}
);