最近在看《MongoDB權威指南》,寫博客記錄一下相關內容~~
關於安裝之類的最基本的就不多說了,從基本操作增刪改查開始。
MongoDB官網地址:http://www.mongodb.org/
我使用的是MongoDB 2.4.8
插入文檔
db.user.insert({"name":"jun"})
在user中插入一條記錄。這個操作會給文檔添加一個"_id"鍵。如下圖所示:
如果要插入多個文檔,使用批量插入會快一些,一次批量插入只是單個TCP請求,無需處理大量的消息頭,減少了插入時間。
db.user.insert([{"name":"jun"},{"name":"jun12"}])
這個可能是在新版本才支持的,在網上的博客中都說shell不支持。
MongoDB消息的長度最大是16M,所以使用批量插入時還是有限制的。
MongoDb插入原理:使用驅動程序進行插入的時候,會將數據轉換成BSON格式。數據庫會解析BSON,並檢驗是否含有“_id”鍵。而且每次插入文檔不能超過4M。
刪除文檔
db.user.remove()
上面的命令會刪除user集合中的文檔,但不會刪除user集合本身,索引也會保留。
remove函數可以接受一個查詢作為可選參數。給定參數之后,只有符合條件的文檔才會被刪除。
db.user.remove({"name":"jun"})
上面的命令會刪除user集合中name為jun的文檔。如下圖所示:
刪除數據是永久的,不能撤銷也不能恢復。
更新文檔
1.文檔替換
db.user.update({"_id":ObjectId("52d791307ae252f9149547c9")},jun)
將_id為ObjectId("52d791307ae252f9149547c9")的文檔更新為jun,jun是一個object。
詳細如下圖
先將查找的數據復制給jun變量,修改name屬性,在使用命令db.user.update({"_id":ObjectId("52d791307ae252f9149547c9")},jun)在數據庫中更新。當update時,數據庫會去查找一個_id為ObjectId("52d791307ae252f9149547c9")的文檔,並替換它。update時最好使用_id。
2.使用修改器
當文檔只需要修改一部分時,利用原子的更新修改器,效率更高。
1."$set"修改器
"$set"是用來設置一個鍵的值的,如果這個鍵不存在,就創建它。
db.user.update({"name":"jun12"},{"$set":{"email":"jun@126.com"}})
使用$set修改器向name為jun12的文檔里添加或修改鍵email為jun@126.com
詳細如下圖
如果使用如下命令
db.user.update({"name":"jun12"},{"email":"jun@126.com"})
會將name為jun12的文檔替換為文檔{"email":"jun@126.com"},就相當於前面的文檔替換。
如果要刪除一個key就使用對應的$unset
db.user.update({'_id': ObjectId('54deeacc2736e74e058b4568')},{ $unset: {"email" : 1}});
執行完這條命令后,_id是ObjectId('54deeacc2736e74e058b4568')的文檔里就會移除email的key。
2."$inc"修改器
"$inc"修改器可以用來增加已有鍵的值,或者在建不存在時創建一個鍵。
db.user.update({"name":"jun12"},{"$inc":{"score":100}})
上面的命令會在name為jun12的文檔的score鍵上加100,如果score鍵不存在,就創建score鍵,並把值設置為增加量100。
詳細如下圖
"$inc"只能用於整數、長整數或雙精度浮點數,不僅僅其后的值,而且要更新的鍵值也要滿足。如果用在其他類型的數據上就會導致操作失敗。其中包括很多語言會自動轉換成數字的類型,例如null、布爾類型或數字構成的字符串。"$inc"專門用來增加或減少(數字為負數)數字的。
3."$push"修改器
"$push"修改器可以向數組的末尾加入一個元素,如果指定的鍵不存在,就會創建一個新數組,並把要插入的元素插入。
db.user.update({name:"jun12"},{$push:{tel:12345678902}})
上面的命令會在name為jun12的文檔的tel鍵上插入一個元素12345678902,如果tel鍵不存在,就創建tel鍵,並出插入元素。
詳細如下圖
如果要添加多條,可以使用$pushAll,代碼如下
db.user.update({'_id': ObjectId('54deeacc2736e74e058b4568')},{ $pushAll: {tel : [15155555555,13133334343]}});
4."$addToSet"修改器
"$addToSet"也可用來插入數組元素,與"$push"不同的是,當要插入的元素在數組中已經存在時,"$addToSet"就不會再次插入。可以用來避免重復。
db.user.update({_id:ObjectId("52d791327ae252f9149547cb")},{$addToSet:{tel:12345678903}})
詳細如下圖
第一次插入因為存在相同元素沒有插入,第二次插入tel中。
5."$each"修改器
"$each"用來循環,與"$addToSet"結合使用,可以不重復的插入多個元素。
db.user.update(
{_id:ObjectId("52d791327ae252f9149547cb")},
{$addToSet:{tel:{$each:[12345678903,12345678904,12345678905]}}}
)
詳細如下圖
6."$pop"修改器
"$pop"作用與"$push"相反,可以從數組中刪除元素,{$pop:{key:1}}從數組末尾刪除一個元素,{$pop:{key:-1}}則從頭部刪除。
db.user.update(
{_id:ObjectId("52d791327ae252f9149547cb")},
{$pop:{tel:1}}
)
詳細如下圖
7."$pull"修改器
"$pull"修改器會將所有符合條件的元素都刪掉。
db.user.update({},{$pull:{tel:12345678901}})
詳細如下圖
如果有多條,可以使用$pullAll,代碼如下
db.user.update({'_id': ObjectId('54deeacc2736e74e058b4568')},{ $pullAll: {tel : [12345678902,12345678903]}});
8."$"修改器
若數組有多個值,我們只想對其中一部分進行操作,就需要用位置或者定位操作符"$"。
db.blog.update( {"comments.author":"jun"}, {"$set":{"comments.$.author":"harry"}} )
定位符職匹配第一個,會將jun的第一個評論的名字修改為harry。
upsert操作
upsert是一種特殊的更新。要是沒有文檔符合更新條件,就會以這個條件和更新文檔為基礎創建一個新的文檔。如果找到了匹配的文檔,則正常更新。
其命令就是將update的第3個參數設為true。
db.blog.update( {"url":"/blog"}, {"inc":{"visit":1}}, true)
upsert是原子性的,比起查詢出來,判斷是否存在,再決定添加還是修改要高效的多。
更新多個文檔
默認情況下更新只針對第一個匹配的文檔執行,若要使所有匹配的文檔都更新,只需設置update的第4個參數為true。
db.blog.update( {"visit":1}, {"inc":{"visit":1}}, false, true)
findAndModify
擁有類似事務特性的更新與查詢操作。它是原子性的,會返回符合查詢條件的更新后的文檔。
一次只能處理一個文檔,也就是條件query條件,且執行sort后的第一個文檔。
比更新要慢,大概耗時相當於一次查找、一次更新和一次getLastError順序執行所需的時間。
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參數一樣。
使用findAndModify能夠實現的功能如下:
1. 查找並更新
2. 查找並刪除
3. 查找,存在就更新,不存在就插入一條
今天就先到這里~~該去吃飯了~~