MongoDB(12)- 查詢嵌入文件的陣列

小菠蘿測試筆記發表於2021-06-02

插入測試資料

db.inventory.insertMany( [
   { item: "journal", instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] },
   { item: "notebook", instock: [ { warehouse: "C", qty: 5 } ] },
   { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ] },
   { item: "planner", instock: [ { warehouse: "A", qty: 40 }, { warehouse: "B", qty: 5 } ] },
   { item: "postcard", instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }
]);

 後面的栗子都會用到這裡的測試資料

 

查詢巢狀在陣列中的文件

查詢 instock 陣列中包含  { warehouse: "A", qty: 5 }  的所有文件

> db.inventory.find( { "instock": { warehouse: "A", qty: 5 } } )
{ "_id" : ObjectId("60b6dbbf67b3da7412587546"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }

 

巢狀文件內的欄位,除了欄位名、欄位值一樣,順序也得一致,否則不匹配

 

精確匹配整個文件陣列的栗子

> db.inventory.find({instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ]})
{ "_id" : ObjectId("60b6dbbf67b3da7412587548"), "item" : "paper", "instock" : [ { "warehouse" : "A", "qty" : 60 }, { "warehouse" : "B", "qty" : 15 } ] }

 

在文件陣列中嵌入的欄位上指定查詢條件

在 instock 陣列中,至少有一個文件的 qty 欄位值是 ≤20 的

> db.inventory.find( { 'instock.qty': { $lte: 20 } } )
{ "_id" : ObjectId("60b6dbbf67b3da7412587546"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587547"), "item" : "notebook", "instock" : [ { "warehouse" : "C", "qty" : 5 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587548"), "item" : "paper", "instock" : [ { "warehouse" : "A", "qty" : 60 }, { "warehouse" : "B", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587549"), "item" : "planner", "instock" : [ { "warehouse" : "A", "qty" : 40 }, { "warehouse" : "B", "qty" : 5 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da741258754a"), "item" : "postcard", "instock" : [ { "warehouse" : "B", "qty" : 15 }, { "warehouse" : "C", "qty" : 35 } ] }

 

訪問陣列中文件的欄位,如果不知道文件的準確索引值,只能按照以下格式

陣列欄位名.文件欄位名
instock.qty

 

使用陣列索引查詢嵌入文件中的欄位

上面的栗子是直接根據欄位名查詢

 

在 instock 陣列中,第一個元素包含欄位 qty ,且值 ≤20 的文件

> db.inventory.find( { 'instock.0.qty': { $lte: 20 } } )
{ "_id" : ObjectId("60b6dbbf67b3da7412587546"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587547"), "item" : "notebook", "instock" : [ { "warehouse" : "C", "qty" : 5 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da741258754a"), "item" : "postcard", "instock" : [ { "warehouse" : "B", "qty" : 15 }, { "warehouse" : "C", "qty" : 35 } ] }

 

在文件陣列中的欄位指定組合(多個)查詢條件

栗子一

找到在 instock 陣列中【至少有一個嵌入文件包含 qty > 10,以及至少有一個嵌入文件(但不一定是同一個嵌入文件)包含 qty ≤20 】的文件

> db.inventory.find( { "instock.qty": { $gt: 10,  $lte: 20 } } )
{ "_id" : ObjectId("60b6dbbf67b3da7412587546"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587548"), "item" : "paper", "instock" : [ { "warehouse" : "A", "qty" : 60 }, { "warehouse" : "B", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587549"), "item" : "planner", "instock" : [ { "warehouse" : "A", "qty" : 40 }, { "warehouse" : "B", "qty" : 5 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da741258754a"), "item" : "postcard", "instock" : [ { "warehouse" : "B", "qty" : 15 }, { "warehouse" : "C", "qty" : 35 } ] }
  • 不需要在同一個文件同時滿足兩個條件(當然同一個文件同時滿足也可以)
  • 只要整個文件陣列中,兩個條件都至少有一個滿足的文件即可

 

栗子二

找到在 instock 陣列中【至少有一個嵌入文件包含 qty = 5,以及至少有一個嵌入文件(但不一定是同一個嵌入文件)包含 warehouse = A 】的文件:

> db.inventory.find( { "instock.qty": 5, "instock.warehouse": "A" } )
{ "_id" : ObjectId("60b6dbbf67b3da7412587546"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587549"), "item" : "planner", "instock" : [ { "warehouse" : "A", "qty" : 40 }, { "warehouse" : "B", "qty" : 5 } ] }

 

在文件陣列中單個巢狀文件滿足多個查詢條件

前言

上面的栗子都是單個巢狀文件或多個巢狀文件滿足多個查詢條件即可

 

如果想確保單個巢狀文件必須同時滿足多個查詢條件呢?

使用 $elemMatch 運算子!(前面講陣列的時候也提到過)

 

栗子一

找到在 instock 陣列【至少有一個包含 qty = 5 和 warehouse = A 的嵌入文件 】的文件

> db.inventory.find( { "instock": { $elemMatch: { qty: 5, warehouse: "A" } } } )
{ "_id" : ObjectId("60b6dbbf67b3da7412587546"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }

 

栗子二

找到在 instock 陣列【至少有一個包含 qty > 10 且 ≤ 20 的嵌入文件】的文件

> db.inventory.find( { "instock": { $elemMatch: { qty: { $gt: 10, $lte: 20 } } } } )
{ "_id" : ObjectId("60b6dbbf67b3da7412587546"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da7412587548"), "item" : "paper", "instock" : [ { "warehouse" : "A", "qty" : 60 }, { "warehouse" : "B", "qty" : 15 } ] }
{ "_id" : ObjectId("60b6dbbf67b3da741258754a"), "item" : "postcard", "instock" : [ { "warehouse" : "B", "qty" : 15 }, { "warehouse" : "C", "qty" : 35 } ] }

 

相關文章