1. 程式人生 > >MongoDB shell中執行更新

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" }
>