MongoDB shell中執行更新

shell中執行更新

標籤(空格分隔): MongoDB


參數

update()函數接受以下四個參數:

criteria : update的查詢條件,類似sql update查詢內where後面的。
objNew : update的對象和一些更新的操作符(如, inc…)等,也可以理解爲sql update查詢內set後面的
upsert : 這個參數的意思是,如果不存在update的記錄,是否插入objNew,true爲插入,默認是false,不插入。
multi : mongodb默認是false,只更新找到的第一條記錄,如果這個參數爲true,就把按條件查出來多條記錄全部更新。

1、強硬的文檔替換式更新

此種更新操作類似於把之前的老文檔刪除,然後替換爲更新的文檔,也就是用新文檔替換老文檔,如下圖:原文檔中根本不存在age這個key,但是執行替換式更新後,不管老文檔存在哪些key,更新最後都僅僅只會存在新的文檔中的那些key(原文檔的_id還會存在)。

> db.person.find()
{ "_id" : ObjectId("556c0b48361be67b8f01af2c"), "name" : "zhang" }
>
> db.person.update({name:"zhang"},{age:4})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.person.find()
{ "_id" : ObjectId("556c0b48361be67b8f01af2c"), "age" : 4 }
>

這個時候如果是真的只需要更新name鍵的值,可以使用如下的方式:但是這種方式要注意一個問題,就是變量p必須通過findOne()去獲得,如果通過find()方法獲得,則後面的update方法會報錯;而且因爲findOne方法僅會返回查詢文檔匹配的一條集合文檔,使用這種方式做update時,此處update滿足更新條件的文檔可能不止一條,那麼更新就會失敗,因爲會出現集合中”_id”鍵值重複的現象。

> db.person.find()
{ "_id" : ObjectId("556c0b48361be67b8f01af2c"), "age" : 4 }
>
> var p = db.person.findOne()
> p.age = 14;
14
> db.person.update({"_id" : ObjectId("556c0b48361be67b8f01af2c")},p)
>
> db.person.find()
{ "_id" : ObjectId("556c0b48361be67b8f01af2c"), "age" : 14 }
>

不可以更新“_id”這個key的值,而不管更新後的“_id”值是否已經存在

2、使用修改器進行局部更新

2.1 $set修改器

{$set:{key:value}},如果滿足更新條件的文檔中存在$set修改器中的key時,則進行更新,否則進行添加,如下:還是隻會對滿足條件的第一個文檔進行更新

> db.person.find()
{ "_id" : 1001, "name" : "eee" }
{ "_id" : 1002, "name" : "eee" }
>
> db.person.update({name:"eee"},{$set:{name:"aaa",age:23}})
> db.person.find()
{ "_id" : 1001, "name" : "aaa", "age" : 23 }
{ "_id" : 1002, "name" : "eee" }
>

2.2 $inc修改器

{\$inc:{key:value}},僅適用於數字類型,可以爲指定的key對應的數字類型的值進行加減操作,如下:

> db.person.find()
{ "_id" : 1001, "name" : "aaa", "age" : 23 }
{ "_id" : 1002, "name" : "eee" }
>
> db.person.update({name:"aaa"},{$inc:{age:2}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.person.find()
{ "_id" : 1001, "name" : "aaa", "age" : 25 }
{ "_id" : 1002, "name" : "eee" }
>
> db.person.update({name:"aaa"},{$inc:{age:-2}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.person.find()
{ "_id" : 1001, "name" : "aaa", "age" : 23 }
{ "_id" : 1002, "name" : "eee" }
>

2.3 $unset修改器

{\$unset:{key:value}},刪除指定的key,如下:

> db.person.find()
{ "_id" : 1001, "name" : "aaa", "age" : 23 }
{ "_id" : 1002, "name" : "eee" }
>
> db.person.update({name:"aaa"},{$unset:{age:23}})
> db.person.find()
{ "_id" : 1001, "name" : "aaa" }
{ "_id" : 1002, "name" : "eee" }
>

2.4 $push修改器

{\$push:{key:value}},如果指定的key是數組,則往該數組中追加新的元素;如果指定的key不是數組,則中斷操作;如果不存在指定的key,則創建,且類型爲數組類型,並加入新的元素;如下:

> db.person.find()
{ "_id" : 1001, "name" : "aaa" }
{ "_id" : 1002, "name" : "eee" }
>
> db.person.update({name:"aaa"},{$push:{name:"java"}})
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 0,
        "nModified" : 0,
        "writeError" : {
                "code" : 16837,
                "errmsg" : "The field 'name' must be an array but is of type Str
ing in document {_id: 1001.0}"
        }
})
> db.person.update({name:"aaa"},{$push:{books:"java"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.person.find()
{ "_id" : 1002, "name" : "eee" }
{ "_id" : 1001, "name" : "aaa", "books" : [ "java" ] }
> db.person.update({name:"aaa"},{$push:{books:"MongoDB"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.person.find()
{ "_id" : 1002, "name" : "eee" }
{ "_id" : 1001, "name" : "aaa", "books" : [ "java", "MongoDB" ] }
>

2.5 $pushAll修改器

{\$pushAll:{key:value}},與$push一樣,只是它可以一次性批量加入一個數組中的所有元素,如下圖:

> db.person.find()
{ "_id" : 1002, "name" : "eee" }
{ "_id" : 1001, "name" : "aaa", "books" : [ "java", "MongoDB" ] }
>
> db.person.update({name:"aaa"},{$pushAll:{books:["JavaEE","JSP"]}})
> db.person.find()
{ "_id" : 1002, "name" : "eee" }
{ "_id" : 1001, "name" : "aaa", "books" : [ "java", "MongoDB", "JavaEE", "JSP" ]
 }
>

2.6 $addToSet修改器

{\$addToSet:{key:value}},與$push一樣,只是當目標數組不存在該元素時才加入,如下圖:

> db.person.find()
{ "_id" : 1002, "name" : "eee" }
> db.person.update({name:"eee"},{$addToSet:{name:"java"}})
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 0,
        "nModified" : 0,
        "writeError" : {
                "code" : 16837,
                "errmsg" : "Cannot apply $addToSet to a non-array field. Field n
amed 'name' has a non-array type String in the document _id: 1002.0"
        }
})
>  db.person.update({name:"eee"},{$addToSet:{books:"Java"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.person.find()
{ "_id" : 1002, "name" : "eee", "books" : [ "Java" ] }
>
> db.person.update({name:"eee"},{$addToSet:{books:"Java"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
> db.person.find()
{ "_id" : 1002, "name" : "eee", "books" : [ "Java" ] }
>

2.7 $pop修改器

{$pop:{key:value}},從指定數組的頭或尾刪除一個元素,從頭刪除一個元素用小於0的值,從尾刪除一個元素用大於0的值,如下圖:

> db.person.find()
{ "_id" : 1001, "name" : "aaa", "books" : [ "java", "MongoDB", "JavaEE", "JSP","Spring" ] }
>
> db.person.update({_id:1001},{$pop:{books:-1}})
> db.person.find()
{ "_id" : 1001, "name" : "aaa", "books" : [ "MongoDB", "JavaEE", "JSP", "Spring] }
>
> db.person.update({_id:1001},{$pop:{books:-2}})
> db.person.find()
{ "_id" : 1001, "name" : "aaa", "books" : [ "JavaEE", "JSP", "Spring" ] }
>
> db.person.update({_id:1001},{$pop:{books:1}})
> db.person.find()
{ "_id" : 1001, "name" : "aaa", "books" : [ "JavaEE", "JSP" ] }
>
> db.person.update({_id:1001},{$pop:{books:2}})
> db.person.find()
{ "_id" : 1001, "name" : "aaa", "books" : [ "JavaEE" ] }
>

2.8 $pull修改器

{\$pull:{key:value}},從指定數組中刪除一個被指定的值,如下:

> db.person.find()
{ "_id" : 1001, "name" : "aaa", "books" : [ "JavaEE" ] }
> db.person.update({_id:1001},{$pull:{books:"JavaEE"}})
> db.person.find()
{ "_id" : 1001, "name" : "aaa", "books" : [ ] }
>

2.9 $pullAll修改器

{\$pullAll:{key:value}},從指定數組中一次性刪除多個被指定的值,如下:

> db.person.find()
{ "_id" : 1002, "name" : "eee", "books" : [ "Java", "JavaEE" ] }
>
> db.person.update({_id:1002},{$pullAll:{books:["JavaEE","Java"]}})
> db.person.find()
{ "_id" : 1002, "name" : "eee", "books" : [ ] }
>

2.10 數組定位器$

如果數組中有多個元素,需要對其中一部分進行更新,則可以使用定位器$。如下圖:可以發現它還是隻會對該文檔中books那個數組中滿足條件的第一個元素其作用,且注意:當使用了books.price這種方式時,一定要加上引號,不然會報錯。

> db.person.find()
{ "_id" : 1002, "books" : [ { "name" : "JSP", "price" : 23.5 }, 
                { "name" : "JAVA", "price" : 45.5 }, 
                { "name" : "Spring", "price" : 45.5 } ] }
>
> db.person.update({"books.price":45.5},{$set:{"books.$.author":"abc"}})
> db.person.find()
{ "_id" : 1002, "books" : [ { "name" : "JSP", "price" : 23.5 }, 
            { "name" : "JAVA", "price" : 45.5, "author" : "abc" },
            { "name" : "Spring", "price" : 45.5 } ] }
>

如果是知道數組元素索引,還可以通過索引的方式,比如把上面的books.$.author改爲:books.0.author。

2.11 $addToSet$each結合完成批量數組更新

如下:$each會循環後面的數組,把每個元素值進行$addToSet操作。

> db.person.find()
{ "_id" : 1001, "name" : "aaa", "books" : [ "Java" ] }
>
> db.person.update({_id:1001},{$addToSet:{books:{$each:["Java","JSP"]}}})
> db.person.find()
{ "_id" : 1001, "name" : "aaa", "books" : [ "Java", "JSP" ] }
>

2.12 $push$inc結合使用

比如要往文檔的books這個key(數組)中加入一個元素,同時該文檔的books_size這個key的大小加1,如下圖:這個方式和修改器$addToSet沒法配合使用,因爲無法判斷這個元素是否添加到了數組中

> db.person.find()
{ "_id" : 1002, "books" : [ "Java", "MongoDB" ], "books_size" : 2, "name" : "aaa" }
>
> db.person.update({_id:1002},{$push:{books: "JSP"}, $inc:{books_size:1}})
> db.person.find()
{ "_id" : 1002, "books" : [ "Java", "MongoDB", "JSP" ], "books_size" : 3, "name": "aaa" }
>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章