這篇文章帶給大家的內容是關於MongoDB中陣列類型的操作(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
在MongoDB的模式中,我們經常將一些資料儲存到陣列類型中,也就是我們常見的巢狀模式設計的一種實作方式。數組的這種設計實作方式在關聯式資料庫中是沒有或說不常見的。所以,透過本文我們來梳理一下MongoDB的陣列的相關操作。關於數組的操作可以分成兩類,一類是數組運算符,另一個是數組運算修飾符。
陣列運算子
#運算子 | |
#根據查詢選擇器定位要更新的文件 | |
加入值到陣列中 | #$pushAll |
$addToSet | |
#加入值到陣列中,重複了也不處理 | |
從陣列中刪除第一個或最後一個值。 |
從陣列中刪除符合查詢條件的值。
陣列運算修飾符 | |
與$push和$addToSet一起使用來操作多個值。 |
1.$push運算子
$push 主要用來在陣列中加入元素。
語法:
{ $push: { <field1>: <value1>, ... } }
預設情況下,它會在陣列尾部新增一個單獨的元素。
假如我們有一個學生成績的集合studentscore,其文件格式如下:
##
{ "_id" : 1, "name" : "xiaoming", "score" : [ { "math" : 99, "english" : 89 } ] } { "_id" : 2, "name" : "xiaohong", "score" : [ { "math" : 98, "english" : 96 } ] }#其中的需求為,更新_id 為1的文檔記錄,在分數數組的字段上,添加物理學的成績,修改代碼為##
db.studentscore.update({_id:1},{$push: {score:{"physics":100}}})
修改後,結果查詢如下:
{ "_id" : 1, "name" : "xiaoming", "score" : [ { "math" : 99, "english" : 89 }, { "physics" : 100 } ] } { "_id" : 2, "name" : "xiaohong", "score" : [ { "math" : 98, "english" : 96 } ] }
1.3 結合$each修飾符,批次插入
$each 一起使用。 <span class="pre"></span>
例如,我們將小紅的(_id =2)的物理成績、化學成績、生物成績一起加入文件。執行的語句如下:<span class="pre"></span>
db.studentscore.update({ _id: 2 }, { $push: { score: { $each: [{ "physics": 100 }, { "chemistry": 90 }, { "biology": 99 }] } } } )
#查詢的結果如下:
##
{ "_id" : 1, "name" : "xiaoming", "score" : [ { "math" : 99, "english" : 89 }, { "physics" : 100 } ] } { "_id" : 2, "name" : "xiaohong", "score" : [ { "math" : 98, "english" : 96 }, { "physics" : 100 }, { "chemistry" : 90 }, { "biology" : 99 } ] }
#1.4 陣列修飾符 $sort 和$slice的使用前面講了$each 陣列運算修飾符,那我們再舉一個例子,將剩餘的兩個修飾符一起講解好了($sort 和$slice)例如,我們有文件記錄如下:
{ "_id" : 5, "quizzes" : [ { "wk": 1, "score" : 10 }, { "wk": 2, "score" : 8 }, { "wk": 3, "score" : 5 }, { "wk": 4, "score" : 6 } ] }現在我們,有個需求,就是先向文件的quizzes數組字段,追加三個記錄,然後,我們再按照score排序,選取數組中的前三個元素。
db.students.update( { _id: 5 }, { $push: { quizzes: { $each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ], $sort: { score: -1 }, $slice: 3 } } } )更新後的結果顯示如下:
{ "_id" : 5, "quizzes" : [ { "wk" : 1, "score" : 10 }, { "wk" : 2, "score" : 8 }, { "wk" : 5, "score" : 8 } ]}$slice操作修飾符是在MongoDB 2.4 裡新增的,其目的是方便管理經常更新的陣列。當向數組添加值但是不想數組太大的時候,這個操作符非常有用。它必須與$push、$each運算元一起使用,允許用來剪短數組的大小、刪除舊的值。 與$slice操作修飾符很像,MongoDB 2.4 新增了$sort操作修飾符,幫助更新陣列。當使用$push和$slice時,有時候要先排序再刪除它們。 2. $pop 運算子2.1 語法及功能描述$pop運算子可以實現從陣列中刪除第一個或是最好一個元素。
{ $pop: { <field>: <-1 | 1>, ... } }參數為-1 ,代表要刪除陣列中的第一個元素;參數為1 ,代表要刪除陣列中的最後一個元素。 2.2 操作案例例如集合students 中有以下文件:
{ _id: 1, scores: [ 8, 9, 10 ] }我們的需求是要把數組中的第一個元素(成績為8)移除,SQL 語句如下:
db.students.update( { _id: 1 }, { $pop: { scores: -1 } } )更新後,文件如下
{ _id: 1, scores: [ 9, 10 ] }繼續示範,如果在現有的基礎上,我們需要進一步移除陣列的最後一個元素(成績為10),更新的sQL如下:
db.students.update( { _id: 1 }, { $pop: { scores: 1 } } )查詢結果如下:
{ _id: 1, scores: [ 9 ] }3. #$pull運算子
<span class="pre"></span>
#3.1 語法及功能描述{ $pull: { <field1>: <value|condition>, <field2>: <value|condition>, ... } }3.2 操作案例3.2.1 移除陣列中等於
{ _id: 1, fruits: [ "apples", "pears", "oranges", "grapes", "bananas" ], vegetables: [ "carrots", "celery", "squash", "carrots" ]} { _id: 2, fruits: [ "plums", "kiwis", "oranges", "bananas", "apples" ], vegetables: [ "broccoli", "zucchini", "carrots", "onions" ]}#操作要求是將陣列欄位fruits中的"apples "
and <span class="pre"></span>"oranges" 移除,也要移除vegetables陣列欄位中的"carrots" 移除,其更新語句如下:
<span class="pre"></span>
#
db.stores.update( { }, { $pull: { fruits: { $in: [ "apples", "oranges" ] }, vegetables: "carrots" } }, { multi: true } )更新後的結果如下:
{ "_id" : 1, "fruits" : [ "pears", "grapes", "bananas" ], "vegetables" : [ "celery", "squash" ]} { "_id" : 2, "fruits" : [ "plums", "kiwis", "bananas" ], "vegetables" : [ "broccoli", "zucchini", "onions" ]}此時,集合文件中,fruit的數組字段沒有apples也沒有
<span class="pre"></span>oranges,vegetables陣列欄位也沒有了carrots。
<span class="pre"></span>3.2.2 移除陣列中符合
指定條件
{ _id: 1, votes: [ 3, 5, 6, 7, 7, 8 ] }我們要把votes大於等於6的元素移除,其語句如下:
db.profiles.update( { _id: 1 }, { $pull: { votes: { $gte: 6 } } } )
更新後的結果如下:
{ _id: 1, votes: [ 3, 5 ] }
假设我们有一个关于 调查的集合 survey,其数据如下:
{ _id: 1, results: [ { item: "A", score: 5 }, { item: "B", score: 8, comment: "Strongly agree" } ]} { _id: 2, results: [ { item: "C", score: 8, comment: "Strongly agree" }, { item: "B", score: 4 } ]}
需求是将 <span class="pre">score 为</span>
<span class="pre">8</span>
并且 <span class="pre">item</span>
为 <span class="pre">"B"的元素移除</span>
db.survey.update( { }, { $pull: { results: { score: 8 , item: "B" } } }, { multi: true } )
更新后的文档如下:
{ "_id" : 1, "results" : [ { "item" : "A", "score" : 5 } ]} { "_id" : 2, "results" : [ { "item" : "C", "score" : 8, "comment" : "Strongly agree" }, { "item" : "B", "score" : 4 } ]}
此时就要用到 <span class="pre">$elemMatch操作符。</span>
例如 文档格式如下:
{ _id: 1, results: [ { item: "A", score: 5, answers: [ { q: 1, a: 4 }, { q: 2, a: 6 } ] }, { item: "B", score: 8, answers: [ { q: 1, a: 8 }, { q: 2, a: 9 } ] } ] } { _id: 2, results: [ { item: "C", score: 8, answers: [ { q: 1, a: 8 }, { q: 2, a: 7 } ] }, { item: "B", score: 4, answers: [ { q: 1, a: 0 }, { q: 2, a: 8 } ] } ] }
需要将 results数组字段 移除,移除的条件是 results数组字段中的answers字段,符合 <span class="pre">q</span>
为 <span class="pre">2</span>
and <span class="pre">a</span>
大于等于 <span class="pre">8。</span>
db.survey.update( { }, { $pull: { results: { answers: { $elemMatch: { q: 2, a: { $gte: 8 } } } } } }, { multi: true } )
更新后的数据如下:
{ "_id" : 1, "results" : [ { "item" : "A", "score" : 5, "answers" : [ { "q" : 1, "a" : 4 }, { "q" : 2, "a" : 6 } ] } ] } { "_id" : 2, "results" : [ { "item" : "C", "score" : 8, "answers" : [ { "q" : 1, "a" : 8 }, { "q" : 2, "a" : 7 } ] } ] }
使用$addToSet也会往数组后面添加值,但是它比较特殊:它只会添加数组里不存在的值。
{ $addToSet: { <field1>: <value1>, ... } }
假如有一个集合 <span class="pre">inventory</span>
格式如下
{ _id: 1, item: "polarizing_filter", tags: [ "electronics", "camera" ] }
我们希望向向字段 tags 数组 ,添加一个元素accessories,则更新语句如下:
db.inventory.update( { _id: 1 }, { $addToSet: { tags: "accessories" } } )
更新后的结果为
{ "_id" : 1, "item" : "polarizing_filter", "tags" : [ "electronics", "camera", "accessories" ] }
如果想批量的增加如果元素,我们可以结合 <span class="pre">$each 操作符一起使用。</span>
例如以下文档
{ _id: 2, item: "cable", tags: [ "electronics", "supplies" ] }
我们想在字段 tags 数组,添加元素 "camera", "electronics", "accessories",则更新语句如下:
db.inventory.update( { _id: 2 }, { $addToSet: { tags: { $each: [ "camera", "electronics", "accessories" ] } } } )
更新后的结果如下:
{ _id: 2, item: "cable", tags: [ "electronics", "supplies", "camera", "accessories" ]}
需要注意是,如果添加的元素是数组格式,则会将新添加的元素保留为数组(将会出现数组嵌套数组)
例如
{ _id: 1, letters: ["a", "b"] }
执行的语句如下:
db.test.update( { _id: 1 }, { $addToSet: {letters: [ "c", "d" ] } } )
查询结构显示为
{ _id: 1, letters: [ "a", "b", [ "c", "d" ] ] }
以上是MongoDB中數組類型的操作(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!