插入文檔
使用insert
向集合中插入一個文檔:
1 2 3 4 | > db.test.insert({"name":"mrbird"}) WriteResult({ "nInserted" : 1 }) > db.test.findOne() { "_id" : ObjectId("58a99b8168e0d7b9f6992c69"), "name" : "mrbird" } |
插入的文檔沒有“_id”鍵的話,這個操作會自動爲文檔添加一個“_id”鍵。 批量插入文檔則需使用insertMany
函數,函數接收一個文檔數組:
1 2 3 4 5 6 7 8 9 10 11 12 | > db.test.insertMany([{"name":"Jane"},{"name":"KangKang"}]) { "acknowledged" : true, "insertedIds" : [ ObjectId("58a99d6468e0d7b9f6992c6b"), ObjectId("58a99d6468e0d7b9f6992c6c") ] } > db.test.find() { "_id" : ObjectId("58a99b8168e0d7b9f6992c69"), "name" : "mrbird" } { "_id" : ObjectId("58a99d6468e0d7b9f6992c6b"), "name" : "Jane" } { "_id" : ObjectId("58a99d6468e0d7b9f6992c6c"), "name" : "KangKang" } |
要查看一個文檔的大小,可以使用Object.bsonsize(doc)
函數(單位爲字節):
1 2 | > Object.bsonsize(db.test.find({"name":"mrbird"})) 1215 |
刪除文檔
刪除文檔使用remove
函數,接收一個查詢文檔,所有匹配的文檔都將會被刪除:
1 2 3 4 5 | > db.test.remove({"name":"mrbird"}) WriteResult({ "nRemoved" : 1 }) > db.test.find() { "_id" : ObjectId("58a99d6468e0d7b9f6992c6b"), "name" : "Jane" } { "_id" : ObjectId("58a99d6468e0d7b9f6992c6c"), "name" : "KangKang" } |
要清空整個集合的話,可以使用drop
函數:
1 2 3 | > db.test.drop() true > db.test.find() |
更新文檔
使用update
函數更新文檔,接收兩個參數,查詢文檔和修改器文檔,如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | > db.test.findOne({"name":"mrbird"}) { "_id" : ObjectId("58a9ace92363ff29a7d881e9"), "name" : "mrbird", "blog" : "mrbird.leanote.com" } > var mrbird = db.test.findOne({"name":"mrbird"}) > mrbird.blog = "mrbird's blog" mrbird's blog > db.test.update({"name":"mrbird"},mrbird) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.test.findOne({"name":"mrbird"}) { "_id" : ObjectId("58a9ace92363ff29a7d881e9"), "name" : "mrbird", "blog" : "mrbird's blog" } |
$inc
修改器用來增加或減少已有的鍵值,如果該鍵不存在則創造一個。比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | > db.test.findOne({"name":"mrbird"}) { "_id" : ObjectId("58a9ace92363ff29a7d881e9"), "name" : "mrbird", "blog" : "mrbird's blog" } > db.test.update({"name":"mrbird"},{"$inc":{"pageview":1}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.test.findOne({"name":"mrbird"}) { "_id" : ObjectId("58a9ace92363ff29a7d881e9"), "name" : "mrbird", "blog" : "mrbird's blog", "pageview" : 1 } > db.test.update({"name":"mrbird"},{"$inc":{"pageview":100}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.test.findOne({"name":"mrbird"}) { "_id" : ObjectId("58a9ace92363ff29a7d881e9"), "name" : "mrbird", "blog" : "mrbird's blog", "pageview" : 101 } > db.test.update({"name":"mrbird"},{"$inc":{"pageview":-50}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.test.findOne({"name":"mrbird"}) { "_id" : ObjectId("58a9ace92363ff29a7d881e9"), "name" : "mrbird", "blog" : "mrbird's blog", "pageview" : 51 } |
$inc
只能用於整型,長整型或雙精度浮點型的值。
$set
用於修改文檔的字段值,當這個字段不存在的時候就創建一個。如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | > db.test.findOne({"name":"mrbird"}) { "_id" : ObjectId("58a9ace92363ff29a7d881e9"), "name" : "mrbird", "blog" : "mrbird's blog", "pageview" : 51 } > db.test.update({"_id":ObjectId("58a9ace92363ff29a7d881e9")}, ... {"$set":{"note":"love leanote!!"}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.test.findOne({"_id":ObjectId("58a9ace92363ff29a7d881e9")}) { "_id" : ObjectId("58a9ace92363ff29a7d881e9"), "name" : "mrbird", "blog" : "mrbird's blog", "pageview" : 51, "note" : "love leanote!!" } |
$set
還可以修改鍵的類型,比如將note鍵的值改爲數組類型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | > db.test.update({"_id":ObjectId("58a9ace92363ff29a7d881e9")}, ... {"$set":{"note":["love leanote","the fun of code"]}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.test.findOne({"_id":ObjectId("58a9ace92363ff29a7d881e9")}) { "_id" : ObjectId("58a9ace92363ff29a7d881e9"), "name" : "mrbird", "blog" : "mrbird's blog", "pageview" : 51, "note" : [ "love leanote", "the fun of code" ] } |
$set
也可以修改內嵌文檔,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | > db.blog.findOne() { "_id" : ObjectId("58aa47f645b899838bfb6114"), "name" : "mrbird's blog", "post" : "mongodb", "comment" : { "name" : "xiaohema", "msg" : "學習了,感謝分享" } } > db.blog.update({"name":"mrbird's blog"}, ... {"$set":{"comment.msg":"好,支持威武有希望了"}}) > db.blog.findOne() { "_id" : ObjectId("58aa47f645b899838bfb6114"), "name" : "mrbird's blog", "post" : "mongodb", "comment" : { "name" : "xiaohema", "msg" : "好,支持威武有希望了" } } |
使用$unset
可刪除鍵,比如:
1 2 3 4 5 6 7 8 9 10 | > db.test.update({"_id":ObjectId("58a9ace92363ff29a7d881e9")}, ... {"$unset":{"note":1}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.test.findOne({"_id":ObjectId("58a9ace92363ff29a7d881e9")}) { "_id" : ObjectId("58a9ace92363ff29a7d881e9"), "name" : "mrbird", "blog" : "mrbird's blog", "pageview" : 51 } |
數組修改器
$push
會向已有的數組末尾添加一個值,如果數組不存在,則創建該數組。比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | > db.blog.findOne() { "_id" : ObjectId("58aa47f645b899838bfb6114"), "name" : "mrbird's blog", "post" : "mongodb" } > db.blog.update({"name":"mrbird's blog"}, {"$push": ...{"comments": {"name":"ltsc","msg":"不明覺厲"}}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.blog.findOne() { "_id" : ObjectId("58aa47f645b899838bfb6114"), "name" : "mrbird's blog", "post" : "mongodb", "comments" : [ { "name" : "ltsc", "msg" : "不明覺厲" } ] } |
如果要一次性向數組中添加多個值,可以使用$push
結合$each
修改器。比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | > db.blog.update({"name":"mrbird's blog"}, ... {"$push":{"comments":{"$each":[ ... {"name":"Althars","msg":"siguoyi"}, ... {"name":"jint","msg":"厲害了我的哥"}]}}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.blog.findOne() { "_id" : ObjectId("58aa47f645b899838bfb6114"), "name" : "mrbird's blog", "post" : "mongodb", "comments" : [ { "name" : "ltsc", "msg" : "不明覺厲" }, { "name" : "Althars", "msg" : "siguoyi" }, { "name" : "jint", "msg" : "厲害了我的哥" } ] |
$slice
可以在爲數組添加值的時候截取數組,但必須配合$push
和$each
一起使用,否則報語法錯誤,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | > db.user.findOne() { "_id" : ObjectId("58aa5e8a6a294f5543ff66eb"), "name" : "KangKang", "sex" : "male", "habbit" : [ "basketball", "football", "swimming", "running" ] } > db.user.update({"name":"KangKang"}, ... {"$push":{"habbit":{"$each": ... ["eating"],"$slice":-3}}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.user.findOne() { "_id" : ObjectId("58aa5e8a6a294f5543ff66eb"), "name" : "KangKang", "sex" : "male", "habbit" : [ "swimming", "running", "eating" ] } |
從結果可以看出,$slice
截取了數組最新的三個值。注意,$slice
的值必須是負整數。
現在有這麼一種情況,$push
修改器可以向一個數組中添加重複的值,如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | > db.user.findOne({"name":"mrbird"}) { "_id" : ObjectId("58aa7cb06a294f5543ff66ec"), "name" : "mrbird", "email" : [ ] } WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.user.findOne({"name":"mrbird"}) { "_id" : ObjectId("58aa7cb06a294f5543ff66ec"), "name" : "mrbird", "email" : [ ] } |
如果希望數組中添加的值不重複的話,可以使用$addToSet
修改器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | > db.user.update({"name":"mrbird"}, {"$unset":{"email":1}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.user.findOne({"name":"mrbird"}) { "_id" : ObjectId("58aa7cb06a294f5543ff66ec"), "name" : "mrbird" } > db.user.update({"name":"mrbird"}, ... {"$addToSet":{"email":{"$each":["[email protected]","[email protected]","[email protected]"]}}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.user.findOne({"name":"mrbird"}) { "_id" : ObjectId("58aa7cb06a294f5543ff66ec"), "name" : "mrbird", "email" : [ ] } |
刪除數組元素有幾種方法,比如$pop
,{“$pop”:{"key":1}}
表示從數組尾部刪除元素,-1則表示從頭部刪除:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | > db.user.findOne({"name":"mrbird"}) { "_id" : ObjectId("58aa7cb06a294f5543ff66ec"), "name" : "mrbird", "email" : [ ] } > db.user.update({"name":"mrbird"}, ... {"$pop":{"email":1}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.user.findOne({"name":"mrbird"}) { "_id" : ObjectId("58aa7cb06a294f5543ff66ec"), "name" : "mrbird", "email" : [ ] } |
另外一個刪除數組元素的修改器爲$pull
,該操作符會將所有匹配的元素從數組中刪除。比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | > db.user.update({"name":"KangKang"}, ... {"$push":{"habbit":"eating"}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.user.findOne({"name":"KangKang"}) { "_id" : ObjectId("58aa5e8a6a294f5543ff66eb"), "name" : "KangKang", "sex" : "male", "habbit" : [ "swimming", "running", "eating", "eating" ] } > db.user.update({"name":"KangKang"}, ... {"$pull":{"habbit":"eating"}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.user.findOne({"name":"KangKang"}) { "_id" : ObjectId("58aa5e8a6a294f5543ff66eb"), "name" : "KangKang", "sex" : "male", "habbit" : [ "swimming", "running" ] } |
還可以通過數組的下標修改數組內容,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | > db.blog.find({"name":"mrbird's blog"}).pretty() { "_id" : ObjectId("58aa47f645b899838bfb6114"), "name" : "mrbird's blog", "post" : "mongodb", "comments" : [ { "name" : "ltsc", "msg" : "不明覺厲" }, { "name" : "Althars", "msg" : "siguoyi" }, { "name" : "jint", "msg" : "厲害了我的哥" } ] } > db.blog.update({"name":"mrbird's blog"}, ... {"$set":{"comments.1.msg":"四國以"}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.blog.find({"name":"mrbird's blog"}).pretty() { "_id" : ObjectId("58aa47f645b899838bfb6114"), "name" : "mrbird's blog", "post" : "mongodb", "comments" : [ { "name" : "ltsc", "msg" : "不明覺厲" }, { "name" : "Althars", "msg" : "四國以" }, { "name" : "jint", "msg" : "厲害了我的哥" } ] } |
這種做法有侷限性,就是必須先知道待修改字段的數組下標,可以使用另外一種方法,下面這種方法只需要知道待修改字段就行了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | > db.blog.update({"comments.msg":"四國以"}, ... {"$set":{"comments.$.msg":"看完此文,猶如醍醐灌頂"}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.blog.find({"name":"mrbird's blog"}).pretty() { "_id" : ObjectId("58aa47f645b899838bfb6114"), "name" : "mrbird's blog", "post" : "mongodb", "comments" : [ { "name" : "ltsc", "msg" : "不明覺厲" }, { "name" : "Althars", "msg" : "看完此文,猶如醍醐灌頂" }, { "name" : "jint", "msg" : "厲害了我的哥" } ] } |
update
函數的第三個參數爲upsert
,設置爲true
時,新一個文檔,沒有找到匹配的查詢文檔時,插入該文檔,找到了就更新,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | > db.blog.findOne({"name":"mrbrid","post":"MongoDB文檔CUD"}) null > db.blog.update({"name":"mrbrid","post":"MongoDB文檔CUD"}, ... {"$inc":{"pageview":1}},true) WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : ObjectId("58acf0743c8ad0b0d9d65f45") }) > db.blog.findOne({"name":"mrbrid","post":"MongoDB文檔CUD"}) { "_id" : ObjectId("58acf0743c8ad0b0d9d65f45"), "name" : "mrbrid", "post" : "MongoDB文檔CUD", "pageview" : 1 } |
update函數的第四個參數爲multi
,設置爲true
的時候,批量更新和查詢文檔匹配的文檔,比如將mrbird’s blog集合中所有文檔的pageview增加1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | > db.blog.find().pretty() { "_id" : ObjectId("58acf0743c8ad0b0d9d65f45"), "name" : "mrbird's blog", "post" : "MongoDB文檔CUD", "pageview" : 1 } { "_id" : ObjectId("58acf64b3c8ad0b0d9d65f4a"), "name" : "mrbird's blog", "post" : "MongoDB shell", "pageview" : 1 } { "_id" : ObjectId("58acf65d3c8ad0b0d9d65f4d"), "name" : "mrbird's blog", "post" : "start Spring Boot", "pageview" : 1 } > db.blog.update({"name":"mrbird's blog"},{"$inc":{"pageview":1}}, ... false,true) WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 }) > db.blog.find().pretty() { "_id" : ObjectId("58acf0743c8ad0b0d9d65f45"), "name" : "mrbird's blog", "post" : "MongoDB文檔CUD", "pageview" : 2 } { "_id" : ObjectId("58acf64b3c8ad0b0d9d65f4a"), "name" : "mrbird's blog", "post" : "MongoDB shell", "pageview" : 2 } { "_id" : ObjectId("58acf65d3c8ad0b0d9d65f4d"), "name" : "mrbird's blog", "post" : "start Spring Boot", "pageview" : 2 } |
另外,調用getLastError
可查看最近一次更新的文檔數量,如:
1 2 3 4 5 6 7 8 9 10 | > db.runCommand({getLastError:1}) { "connectionId" : 1, "updatedExisting" : true, "n" : 3, "syncMillis" : 0, "writtenTo" : null, "err" : null, "ok" : 1 } |
擁有類似事務特性的更新與查詢操作findAndModify
。它是原子性的,會返回符合查詢條件的更新後的文檔。一次最多隻更新一個文檔,也就是條件query
條件,且執行sort
後的第一個文檔。語法如下:
1 2 3 4 5 6 7 8 9 | db.COLLECTION_NAME.findAndModify({ query:{}, update:{}, remove:true|false, new:true|false, sort:{}, fields:{}, upsert:true|false} ); |
query是查詢選擇器,與findOne的查詢選擇器相同。
update是要更新的值,不能與remove同時出現。
remove表示刪除符合query條件的文檔,不能與update同時出現。
new爲true:返回更新後的文檔,false:返回更新前的,默認是false。
sort:排序條件,與sort函數的參數一致。
fields:投影操作,與find的第二個參數一致。
upsert:與update的upsert參數一樣。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | > db.blog.findAndModify({ ... "query":{"name":"mrbird's blog"}, ... "update":{ ... "$inc":{"pageview":1}, ... "$set":{"like":1}}}) { "_id" : ObjectId("58acf0743c8ad0b0d9d65f45"), "name" : "mrbird's blog", "post" : "MongoDB文檔CUD", "pageview" : 3 } > db.blog.find().pretty() { "_id" : ObjectId("58acf0743c8ad0b0d9d65f45"), "name" : "mrbird's blog", "post" : "MongoDB文檔CUD", "pageview" : 4, "like" : 1 } { "_id" : ObjectId("58acf64b3c8ad0b0d9d65f4a"), "name" : "mrbird's blog", "post" : "MongoDB shell", "pageview" : 3 } { "_id" : ObjectId("58acf65d3c8ad0b0d9d65f4d"), "name" : "mrbird's blog", "post" : "start Spring Boot", "pageview" : 3 } |
可發現,執行findAndModify
後,返回被更新前(默認顯示更新前的)的文檔,並且只更新了匹配的第一條文檔。
如果要返回被更新後的文檔,我們設置new 爲true:
1 2 3 4 5 6 7 8 9 10 11 | > db.blog.findAndModify({ ..."query":{"name":"mrbird's blog"}, ..."update":{ "$inc":{"pageview":1}, "$set":{"like":2}}, ..."new":true}) { "_id" : ObjectId("58acf0743c8ad0b0d9d65f45"), "name" : "mrbird's blog", "post" : "MongoDB文檔CUD", "pageview" : 5, "like" : 2 } |