首頁  >  文章  >  資料庫  >  MongoDB中數組類型的操作(程式碼範例)

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

不言
不言轉載
2019-01-30 10:26:333828瀏覽

這篇文章帶給大家的內容是關於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: { <field1>: <value1>, ... } }

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

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 一起使用。 <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是$pop的複雜形式。使用$pull,可以透過值精確指定要刪除的元素。

語法格式

{ $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 移除陣列中符合指定條件

的元素
假如我們有一個 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 }   ]}

需求是将 <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 }   ]}

3.2.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 } ] }
   ]
}

4.$addToSet

4.1 语法及功能描述

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

{ $addToSet: { <field1>: <value1>, ... } }

4.2 操作案例

假如有一个集合 <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" ]}

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刪除