MongoDB中數組類型的操作(程式碼範例)

不言
發布: 2019-01-30 10:26:33
轉載
3716 人瀏覽過

這篇文章帶給大家的內容是關於MongoDB中陣列類型的操作(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

在MongoDB的模式中,我們經常將一些資料儲存到陣列類型中,也就是我們常見的巢狀模式設計的一種實作方式。數組的這種設計實作方式在關聯式資料庫中是沒有或說不常見的。所以,透過本文我們來梳理一下MongoDB的陣列的相關操作。關於數組的操作可以分成兩類,一類是數組運算符,另一個是數組運算修飾符。

陣列運算子

#實作功能 $ #根據查詢選擇器定位要更新的文件 #$push 加入值到陣列中 #$pushAll 加入陣列到一個陣列中。 (將被$rach取代) $addToSet $pop 從陣列中刪除第一個或最後一個值。 $pull
#運算子

#加入值到陣列中,重複了也不處理

從陣列中刪除符合查詢條件的值。

$pullAll 從陣列中刪除多個值。 陣列運算修飾符 修飾符 實作功能 #$each 與$push和$addToSet一起使用來操作多個值。 $slice
###與$push和$each一起使用來縮小更新後陣列的大小。 ############$sort######與$push、$each、$slice一起來排序陣列中的子文件。 ############

1.$push運算子

1.1 語法及功能描述

$push 主要用來在陣列中加入元素。

語法:

{ $push: { : , ... } }
登入後複製

預設情況下,它會在陣列尾部新增一個單獨的元素。

1.2 操作案例

假如我們有一個學生成績的集合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 一起使用。

例如,我們將小紅的(_id =2)的物理成績、化學成績、生物成績一起加入文件。執行的語句如下:

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: { : <-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運算子

#3.1 語法及功能描述

$pull是$pop的複雜形式。使用$pull,可以透過值精確指定要刪除的元素。

語法格式

{ $pull: { : , : , ... } }
登入後複製

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 "oranges" 移除,也要移除vegetables陣列欄位中的"carrots" 移除,其更新語句如下:#

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也沒有

oranges,vegetables陣列欄位也沒有了carrots。3.2.2 移除陣列中符合指定條件

的元素
假如我們有一個 profiles 的集合,其文件格式如下:

{ _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 ] }
登入後複製

3.2.3 移除数组中内嵌子文档(即此时数组元素是子文档,每一个{}中的内容是一个数组元素)

假设我们有一个关于 调查的集合 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 } ]}
登入後複製

需求是将score 为8并且item"B"的元素移除

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 } ]}
登入後複製

3.2.4 如果数组类型的元素还内嵌一个数组(数组包数组),就要特别小心了。

此时就要用到$elemMatch操作符。

例如 文档格式如下:

{ _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字段,符合q2anda大于等于8。

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 } ] } ] }
登入後複製

4.$addToSet

4.1 语法及功能描述

使用$addToSet也会往数组后面添加值,但是它比较特殊:它只会添加数组里不存在的值。

{ $addToSet: { : , ... } }
登入後複製

4.2 操作案例

假如有一个集合inventory格式如下

{ _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" ] }
登入後複製

如果想批量的增加如果元素,我们可以结合$each 操作符一起使用。

例如以下文档

{ _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" ]}
登入後複製

4.3 注意点

需要注意是,如果添加的元素是数组格式,则会将新添加的元素保留为数组(将会出现数组嵌套数组)

例如

{ _id: 1, letters: ["a", "b"] }
登入後複製

执行的语句如下:

db.test.update( { _id: 1 }, { $addToSet: {letters: [ "c", "d" ] } } )
登入後複製

查询结构显示为

{ _id: 1, letters: [ "a", "b", [ "c", "d" ] ] }
登入後複製

以上是MongoDB中數組類型的操作(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:cnblogs.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!