MongoDB學習之路 (五):更新操作符(Update Operators).2nd


  本文地址:http://www.cnblogs.com/egger/archive/2013/05/01/3053617.html   歡迎轉載 ,請保留此鏈接๑•́ ₃•̀๑!  

  通常文檔只會有一部分要更新。利用原子的更新修改器,可以使得這種部分更新極為髙效。更新修改器是種特殊的鍵,用來指定復雜的更新操作,比如調整、增加或者刪除鍵,還可能是操作數組或者內嵌文檔。

字段更新操作符 Field Update Operators

  $set

  "$set"用來指定一個鍵的值。如果這個鍵不存在,則創建它。

  我們往下面的一條用戶資料添加“興趣”信息,

db.users.insert({"name":"egger", "age": 28, "sex" : "male"})

   

  運行下面的代碼,將該用戶的興趣設置為“讀書”並添加至文檔中(此時文檔中“hobby”鍵是不存在,該條文檔就會創建它):

db.users.update({"_id" : ObjectId("51826852c75fdd1d8b805801")},
  {"$set" : {"hobby" :"read"}} )

  

  當想更改用戶的興趣資料時,使用"$set" 然后將要更新的內容作為鍵“hobby”的值(下面的示例中將數組作為鍵值):

db.users.update({"_id" : ObjectId("51826852c75fdd1d8b805801")},
    {"$set" : {"hobby" :["swimming","basketball"]}} )

  用"$set"甚至可以修改鍵的數據類型

db.users.update({"_id" : ObjectId("51826852c75fdd1d8b805801")},{"$set" : {"sex" :1 }} )

  執行結果如下:  

  

  使用"$set"修改內嵌文檔:

  

  該文檔中的作者信息為內嵌文檔,我們將其內容全部更改:

db.posts.update({"author.name":"egger"},{"$set":{"author.name":"mongo","author.age":18}})

  

  

  $unset

  從文檔中移除指定的鍵。  

  若要完全刪除鍵“hobby”,使用“$unset”即可:

db.users.update({"_id" : ObjectId("51826852c75fdd1d8b805801")},{"$unset" : {"hobby" :1 }} )

  

 

  $inc

  "$inc"修改器用來增加已有鍵的值,或者在鍵不存在時創建一個鍵。$inc就是專門來增加(和減少)數字的。"$inc"只能用於整數、長整數或雙精度浮點數。要是用在其他類型的數據上就會導致操作失敗。

  例如毎次有人訪問該博文,該條博文的瀏覽數就加1,用鍵"pageviews"保存瀏覽數信息。

  

  下面使用"$inc”修改器增加"pageviews"的值

db.posts.update({"_id" : ObjectId("5180f1a991c22a72028238e4")}, {"$inc":{"pageviews":1}})

  

  上面執行update時如果將鍵值設置為n,那么就表示該鍵的值增加n(n可以為負數)。

db.posts.update({"_id" : ObjectId("5180f1a991c22a72028238e4")}, {"$inc":{"pageviews":-100}})

  

  

  

  $rename

語法: {$rename: { <old name1>: <new name1>, <old name2>: <new name2>, ... } }

  $rename操作符可以重命名字段名稱,新的字段名稱不能和文檔中現有的字段名相同。

  如果文檔中存在A、B字段,將B字段重命名為A,$rename會將A字段和值移除掉,然后將B字段名改為A.

  集合students中的一條文檔數據:

{ "_id": 1,
  "nickname": [ "The American Cincinnatus", "The American Fabius" ],
  "cell": "555-555-5555",
  "name": { "first" : "george", "last" : "washington" }
}

  將集合中"nickname"字段名重命名為“alias”、"cell"字段名重命名為"mobile":

db.students.update( { _id: 1 }, { $rename: { 'nickname': 'alias', 'cell': 'mobile' } } )

  

  執行下面的更新操作,集合中已存在name字段,將會刪除“name”字段,將“alias”字段名重命名為“name”

db.students.update( { _id: 1 }, { $rename: { "alias": "name" } } )

  

  當重命名子文檔字段名時需要使用"."操作符,格式:值為該子文檔的字段名.子文檔中字段名。

db.students.update( { _id: 1 }, { $rename: { "name.first": "name.fname" } } )

  執行上面的更新操作將name字段的值中first字段重命名為fname.

  

  $rename操作符也可以將子文檔中鍵值移到其他子文檔中。

db.students.update( { _id: 1 }, { $rename: { "name.last": "contact.lname" } } )

  我們將名為name的子文檔中的last字段,重名為“lname”,同時將其移動到子文檔contact中,若contact字段不存在,數據庫會新建該字段。

  

  若指定的字段在集合中不存在,$rename操作符將不會有任何影響。

db.students.update( { _id: 1 }, { $rename: { 'wife': 'spouse' } } )

  若指定的多個字段在集合中都不存在,$rename操作符將不會有任何影響。

db.students.update( { _id: 1 }, { $rename: { 'wife': 'spouse', 'vice': 'vp',  'office': 'term' } } )

  集合中不存在上面語句中指定的wife、vice、office字段,所以上述的更新操作無任何影響。

  若指定的多個字段中,有的在集合中存在,有的不存在,$rename操作符執行下列操作:

  •  存在的字段按照上面的規則重命名為新的名稱。
  •  不存在的字段對數據無任何影響。

  

db.students.update( { _id: 1 }, { $rename: { 'wife': 'alias', 'mobile': 'cell' } } )                             

  執行上述更新操作,文檔中只有“mobile”字段被替換為“cell”。  

  

 


  upsert

  upsert是一種特殊的更新操作,不是一個操作符。(upsert = up[date]+[in]sert

  update() 方法的三個參數是upsert,這個參數是個布爾類型,默認是false。當它為true的時候,update方法會首先查找與第一個參數匹配的記錄,在用第二個參數更新之,如果找不到與第一個參數匹配的的記錄,就會以這個條件和更新文檔為基礎創建一個新的文檔。如果找到了匹配的文檔,則正常更新。upsert非常方便,不必預置集合,同一套代碼可以既創建又更新文檔。

db.users.remove()
db.users.update({age :25}, {$inc :{"age" :3}}, true)
db.users.findOne()

  我們將users集合清空,執行upsert操作,查詢出age字段值為25的文檔,然后將該字段值增加3.

  由於我們先清空了集合,所以update操作將執行insert操作,先創建一個鍵“age”的值為25的文檔,然后在將這個值增加3,即鍵“age”的值為28,如圖所示.

  

   $setOnInsert

  當update方法使用upsert選項執行insert操作時,$setOnInsert操作符給相應的字段賦值。類似sql中update 語句的set。

 

db.collection.update( <query>,
                      { $setOnInsert: { <field1>: <value1>, ... } },
                      { upsert: true }   //{ upsert: true }可以用true替換
                    )

 

  示例:products集合無任何文檔,執行下列語句,將插入一條文檔"{ "_id" : 1, "defaultQty" : 100 }":

db.products.update(
                    { _id: 1 },
                    { $setOnInsert: { defaultQty: 100 } },
                    { upsert: true }
                  )

  

 

  若update方法執行的update操作而不是insert操作,那么$setOnInsert操作符將無效。

  集合中有如下一條文檔:  { "_id" : 1, "defaultQty" : 100 }

 

  下面的update方法將執行update操作:

db.products.update(
                    { _id: 1 },
                    { $setOnInsert: { defaultQty: 500, inStock: true },
                      $set: { item: "apple" } },
                    { upsert: true }
                  )

 

  更新結果,$setOnInsert沒有任何影響。

  

 


 

數組更新操作符 Array Update Operators

  只能用在鍵值為數組的鍵上的數組操作。  

  $ (query)

語法: { "<array>.$" : value }

  當對數組字段進行更新時,且沒有明確指定的元素在數組中的位置,我們使用定位操作符("$")標識一個元素,數字都是以0開始的。


  和update()一起使用:

  • 定位操作符("$")作為第一個匹配查詢條件的元素的占位符,也就是在數組中的索引值。
  • 數組字段必須出現查詢文檔中。

  集合students中有兩條文檔:

{ "_id" : 1, "grades" : [ 78, 88, 88 ] }
{ "_id" : 2, "grades" : [ 88, 90, 92 ] }

  執行下列語句創建集合文檔數據:

db.students.remove();
db.students.insert({ "_id" : 1, "grades" : [ 78, 88, 88 ] });
db.students.insert({ "_id" : 2, "grades" : [ 88, 90, 92 ] });

  執行下列操作:

//查詢匹配的文檔中,數組有2個88,只更新第一個匹配的元素,也就是"grades.1"
db.students.update( { _id: 1, grades: 88 }, { $set: { "grades.$" : 82 } }) ;
//查詢文檔中沒有出現grades字段,查詢報錯
db.students.update( { _id: 2 }, { $set: { "grades.$" : 82 } } );

  

  "$push"修改器

  如果指定的鍵已經存在,會向已有的數組末尾加入一個元素,要是沒有就會創建一個新的數組。

  下面是一條文章內容的文檔數據:

  

  我們將使用"$push"對該文檔添加一條評論信息。。

db.posts.update({"title":"MongoDB"},{$push:{"comments":{"name":"egger","content":"thks!"}}})

  $push 沒有使用雙引號。文檔將會增加一個"comments"(評論)鍵且鍵值是數組類型的。

  繼續添加一條評論信息,該信息將添加至鍵值數組的末尾。

db.posts.update({"title":"MongoDB"},{$push:{"comments":{"name":"egger","content":"thks 2!"}}})

  

 

  $pull

語法:db.collection.update( { field: <query> }, { $pull: { field: <query> } } );

   $pull操作符移除指定字段值為數組,且匹配$pull語句聲明的查詢條件的所有元素。

//插入一條文檔
db.profiles.insert({ votes: [ 3, 5, 6, 7, 7, 8 ] });
//移除數組中所有元素7
db.profiles.update( { votes: 3 }, { $pull: { votes: 7 } } );
//移除數組中所有大於6的元素
db.profiles.update( { votes: 3 }, { $pull: { votes: { $gt: 6 } } } );

//Result
{ votes: [ 3, 5, 6, 8 ] }

{ votes: [ 3, 5, 6 ] }

 

  

 

 

內容參考:

1.http://docs.mongodb.org/manual/reference/operator/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM