MongoDB創建更新和刪除文檔


MongoDB最基礎的部分已經看的差不多了,作為數據庫來說做的最多的還是對數據庫數據的操作。本文將介紹MongoDB中一下三點

      • 向集合中添加新文檔
      • 從集合中刪除文檔
      • 更新現有文檔

插入並保存文檔

插入一條記錄

> db.user.find()
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
" : "121212", "tel" : "121212" }
> db.user.insert({username:'aaa',password:'bbb',tel:'123123123'});
> db.user.find()
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
" : "121212", "tel" : "121212" }
{ "_id" : ObjectId("51b91edc32b7955cd61dbc8e"), "username" : "aaa", "password" :
 "bbb", "tel" : "123123123" }
>


操作為文檔增加了一個“_id”,然后保存到了MongoDB中

> db.user.insert({_id:'12345678',username:'aaa',password:'bbb',tel:'123123123'})
;
> db.user.find();
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
" : "121212", "tel" : "121212" }
{ "_id" : ObjectId("51b91edc32b7955cd61dbc8e"), "username" : "aaa", "password" :
 "bbb", "tel" : "123123123" }
{ "_id" : "12345678", "username" : "aaa", "password" : "bbb", "tel" : "123123123
" }
>

如果我們自己定義了一個_id的話,數據庫就不在自己生存,可以看到數據庫自己生成的是ObjectId。

批量插入

如果要插入多個文檔,批量要快一些。批量插入能傳遞一個由文檔構成的數組給數據庫

一次發送多個文檔會提高插入數度。一次插入需要建立一個TCP鏈接。批量提交,會比多次提交數據少建立TCP連接,避免了零碎的請求開銷。而且批量提交只會有一個文件頭信息,數據不用多次的處理文件頭。

用數組的方式一次插入兩條數據

> db.user.insert([{username:'aaa',password:'bbb',tel:'123123123'},{username:'bbb
',password:'ccc',tel:'123123234'}]);
> db.user.find()
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
" : "121212", "tel" : "121212" }
{ "_id" : ObjectId("51b91edc32b7955cd61dbc8e"), "username" : "aaa", "password" :
 "bbb", "tel" : "123123123" }
{ "_id" : "12345678", "username" : "aaa", "password" : "bbb", "tel" : "123123123
" }
{ "_id" : ObjectId("51b920ca32b7955cd61dbc8f"), "username" : "aaa", "password" :
 "bbb", "tel" : "123123123" }
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "username" : "bbb", "password" :
 "ccc", "tel" : "123123234" }
>

插入原理和作用

當執行插入事,使用的驅動會將數據轉換為BSON的形式,將其送入數據庫。數據庫解析BSON,檢驗是否有_id,和文檔的大小,除此之外,文檔不做別的數據驗證,簡單的將數據存入數據庫中。

ps.大於4M的文檔是不能存入數據庫中的。

刪除文檔

刪除文檔用

> db.user.remove()

如果remove不傳入任何參數,會刪除所有文檔,但不會刪除集合本身,原索引也會保留。

如果給定參數,只有符合條件的才會刪除

> db.user.remove({username:'aaa'})
> db.user.find();
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
" : "121212", "tel" : "121212" }
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "username" : "bbb", "password" :
 "ccc", "tel" : "123123234" }
>


刪除速度

刪除文檔通常會很快,但是要清除整個集合,直接刪除集合會更快

更新文檔

文檔存入數據庫后,就可以用update方法來修改它,update有兩個參數一個是查詢文檔,找出需要更新的文檔。一個是修改文檔,描述對找到的文檔做哪些修改

更新操作是原子的,若是兩個更新同時發生,先到達服務器的先執行。

文檔替換

更新最簡單的就是完全用一個新文檔替代匹配文檔。比如我們將username為bb的文檔替換為如下

> db.user.update({username:'bbb'},{password:'abc'});
> db.user.find();
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
" : "121212", "tel" : "121212" }
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
>

我們發現文檔結構被替換成了

{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
>

也就是說這樣的替換是直接替換文檔,而不是做修改。在大的改動的情況下,使用文檔變更可以直接替換文檔,但有時候這樣卻不是我們想要的,我們只是希望修改password而不變動其他的內容

使用修改器

通常文檔只會有部分要更新。利用原子的修改器,可以用來部分更新。

$set修改器

$set用來指定一個鍵的值,如果這個鍵不存在,就創建它。下面我們修改username為wangwu的password的值

> db.user.find();
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
" : "121212", "tel" : "121212" }
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
> db.user.update({username:'wangwu'},{$set:{password:'abcdef'}});
> db.user.find();
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "username" : "wangwu", "password
" : "abcdef", "tel" : "121212" }
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
>

$unset修改器

$unset來刪除一個鍵,比如刪除username為wangwu的tel鍵

> db.user.update({username:'wangwu'},{$unset:{tel:1}});
> db.user.find();
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "password" : "abcdef", "username
" : "wangwu" }
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
>

$inc修改器

$inc用來增加已有的鍵值,或者在鍵值不存在時創建。

現在我們需要一個age的值

現在給age執行$inc

> db.user.find()
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "password" : "abcdef", "username
" : "wangwu" }
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
> db.user.update({username:'wangwu'},{$inc:{age:1}});
> db.user.find()
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 1, "password" : "abcdef"
, "username" : "wangwu" }
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
> db.user.update({username:'wangwu'},{$inc:{age:1}});
> db.user.find()
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "password" : "abcdef"
, "username" : "wangwu" }
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
>


這里執行了兩次$inc,age第一次創建了一個值為1的鍵值,然后自加了1.

$inc鍵的值必須為數字,如果嘗試修改成其他類型就會出現如下錯誤

> db.user.update({username:'wangwu'},{$inc:{age:'abc'}});
Modifier $inc allowed for numbers only
>


數組修改器

數組修改器只能用於數組。

$push會像已有的數組末尾假如一個元素

$pop會從頭部刪除一個元素

> db.user.find()
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "password" : "abcdef"
, "username" : "wangwu" }
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
> db.user.update({username:'wangwu'},{$push:{arr:1}});
> db.user.find()
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [  1 ], "pass
word" : "abcdef", "username" : "wangwu" }
> db.user.update({username:'wangwu'},{$push:{arr:2}});
> db.user.find()
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [  1,  2 ], "
password" : "abcdef", "username" : "wangwu" }
> db.user.update({username:'wangwu'},{$pop:{arr:2}});
> db.user.find()
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [  1 ], "pass
word" : "abcdef", "username" : "wangwu" }
> db.user.update({username:'wangwu'},{$pop:{arr:2}});
> db.user.find()
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [ ], "passwor
d" : "abcdef", "username" : "wangwu" }


數組的定位修改器

若是數組中多個值,我們只想修改其中的部分值,有兩種方法操作數組中的值:通過位置和定位操作符($)

> db.user.update({username:'wangwu'},{$set:{'arr.1':1}});
> db.user.find()
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [  2,  1,  3,
  4 ], "password" : "a", "username" : "wangwu" }
> db.user.update({username:'wangwu'},{$set:{'arr.$':1}});
Cannot apply the positional operator without a corresponding query field contain
ing an array.
> db.user.update({'arr.1':1},{$set:{'arr.$':1}});
> db.user.update({'arr.1':1},{$set:{'arr.$':3}});
> db.user.find()
{ "_id" : ObjectId("51b920ca32b7955cd61dbc90"), "password" : "abc" }
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [  2,  3,  3,
  4 ], "password" : "a", "username" : "wangwu" }
>

使用位置可以直接修改指定位置的數據,使用定位操作符是在查詢的時候不知道該位置的時候使用,這個時候需要注意的是查詢username的時候,使用$會報出錯誤。也就是查詢出來的值不是數組,所以不能用$來指定

 

upsert

upsert是一個特殊的更新。當沒有文檔符合更新條件,就會以這個條件創建新的文檔。當update的第三個參數設置為true的時候,為upsert模式

> db.user.find()
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [  2,  3,  3,
  4 ], "password" : "a", "username" : "wangwu" }
> db.user.update({age:1},{$set:{abc:123}},true)
> db.user.find()
{ "_id" : ObjectId("51b28f74b73ec06e42c91598"), "age" : 2, "arr" : [  2,  3,  3,
  4 ], "password" : "a", "username" : "wangwu" }
{ "_id" : ObjectId("51ba745f5fdf5d2d7426eb35"), "abc" : 123, "age" : 1 }
>

 

更新多個文檔

默認情況下,更新只能對符合匹配條件的第一個文檔操作,要是有多個文檔符合條件,其余的文檔就沒有變化。要使所有的文檔都得到更新,可以設置update的第四個參數為true

返回已經更新的文檔

用getLastError只能獲取有限的信息,並不能返回更新的文檔。這個可以通過findAndModify來做到。

安全操作

MongoDB選中選擇不安全的版本作為默認操作,如果需要判斷狀態,在執行完操作后立即運行getLastError,來檢查是否成功。

如果不考慮安全性的問題,就無序調用getLastError

把重要的數據用安全的方式操作

請求和連接

數據庫為MongoDB創建了一個隊列,存放這個連接請求。當客戶端發送一個請求,會被放到隊列的末尾。只有隊列中的請求都執行完畢,后續的請求才會執行。每個連接都有獨立的隊列。


免責聲明!

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



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