MongoDB教程之?dāng)?shù)據(jù)操作實(shí)例
1. 批量插入:
以數(shù)組的方式一次插入多個(gè)文檔可以在單次TCP請(qǐng)求中完成,避免了多次請(qǐng)求中的額外開銷。就數(shù)據(jù)傳輸量而言,批量插入的數(shù)據(jù)中僅包含一份消息頭,而多次單條插入則會(huì)在每次插入數(shù)據(jù)時(shí)封裝消息頭數(shù)據(jù)。對(duì)于數(shù)據(jù)導(dǎo)入而言,我們可以使用mongoimport完成。
2. 數(shù)據(jù)庫清除:
> db.users.remove()
以上命令將會(huì)清除users集合中的所有數(shù)據(jù),但是不會(huì)刪除集合本身以及關(guān)聯(lián)的索引。數(shù)據(jù)刪除操作是不可恢復(fù)的,一旦刪除就物理的刪除了。對(duì)于全集合清除這種case,一個(gè)更為有效的方式是直接刪除集合對(duì)象本身以及他關(guān)聯(lián)的所有索引,之后再依次重建,如:
> db.one_collection.drop()
3. 數(shù)據(jù)更新:
如果在執(zhí)行數(shù)據(jù)更新時(shí),有多條文檔匹配更新條件,為了避免更新后的_id出現(xiàn)重復(fù)性沖突,MongoDB將僅更新第一條查詢結(jié)果,如:
> post1 = { "name": "stephen", "age" : "35"}
{ "name" : "stephen", "age" : "35" }
> post2 = { "name": "stephen", "age" : 36}
{ "name" : "stephen", "age" : 36 }
> db.blog.insert(post1)
> db.blog.insert(post2)
> post3 = { "name" : "stephen", "age": 37}
{ "name" : "stephen", "age" : 37 }
> db.blog.update({"name":"stephen"},post3)
> db.blog.find()
{ "_id" : ObjectId("4fcd7e2e20668578cc1097d8"), "name" : "stephen", "age" : 36 }
{ "_id" : ObjectId("4fcd7e2820668578cc1097d7"), "name" : "stephen", "age" : 37 }
4. 修改器:
使用修改器進(jìn)行數(shù)據(jù)更新是原子的,也是高效的,不同于全部文檔更新的是被更新文檔的_id不會(huì)變化,而文檔完全更新則會(huì)修改文檔的_id,以及相關(guān)的索引。
> db.blog.find()
{ "_id" : ObjectId("4fcd7e2820668578cc1097d7"), "name" : "stephen", "age" : 41 }
{ "_id" : ObjectId("4fcd81bb20668578cc1097d9"), "name" : "stephen", "age" : 38 }
--$inc修改符將匹配條件的文檔的age鍵原子加一,缺省情況下只是更新第一條符合條件的文檔。
> db.blog.update({"name":"stephen"},{"$inc":{"age":1}})
> db.blog.find()
{ "_id" : ObjectId("4fcd7e2820668578cc1097d7"), "name" : "stephen", "age" : 42 }
{ "_id" : ObjectId("4fcd81bb20668578cc1097d9"), "name" : "stephen", "age" : 38 }
--可以通過update函數(shù)的最后一個(gè)參數(shù)來指定更新所有符合條件的文檔,如:
> db.blog.update({"name":"stephen"},{"$inc":{"age":1}},true,true)
> db.blog.find()
{ "_id" : ObjectId("4fcd7e2820668578cc1097d7"), "name" : "stephen", "age" : 43 }
{ "_id" : ObjectId("4fcd81bb20668578cc1097d9"), "name" : "stephen", "age" : 39 }
--$set修改符直接修改匹配文檔的內(nèi)容,如果修改的鍵存在則直接修改,否則新增。
> db.blog.update({"name":"stephen"},{"$set":{"genda":"male"}})
> db.blog.find()
{ "_id" : ObjectId("4fcd88b720668578cc1097da"), "age" : "35", "genda" : "male", "name" : "stephen" }
--$unset修改符合$set的功能是完全相反的,如:
> db.blog.update({"name":"stephen"},{"$unset":{"genda":"male"}})
> db.blog.find()
{ "_id" : ObjectId("4fcd88b720668578cc1097da"), "age" : "35", "name" : "stephen" }
--可以通過$set修改符修改嵌套子文檔。
> db.blog.find()
{ "_id" : ObjectId("4fcd8e0220668578cc1097db"), "title" : "A Blog Post", "author" : { "name" : "joe", "email" : "joe@ee.com" } }
> db.blog.update({"title":"A Blog Post"},{"$set":{"author.name":"joe schmoe"}})
> db.blog.find()
{ "_id" : ObjectId("4fcd8e0220668578cc1097db"), "author" : { "email" : "joe@ee.com", "name" : "joe schmoe" }, "title" : "A Blog Post" }
5. 數(shù)組修改器:
> db.blog.insert({"title":"one blog"})
> db.blog.find()
{ "_id" : ObjectId("4fcd909520668578cc1097dc"), "title" : "one blog" }
--如果其操作的鍵不存在,則創(chuàng)建新的鍵值,其值的類型為數(shù)組類型。
> log.update({"title":"one blog"}, {"$push": {"comments":{"content":"hello"}}})
> db.blog.findOne()
{
"_id" : ObjectId("4fcd909520668578cc1097dc"),
"comments" : [
{
"content" : "hello"
}
],
"title" : "one blog"
}
--如果$push操作的鍵值已經(jīng)存在,且其值為數(shù)組類型,該修改符將為該數(shù)組添加新的數(shù)組元素。
> db.blog.update({"title":"one blog"}, {"$push": {"comments":{"content":"word"}}
> db.blog.findOne()
{
"_id" : ObjectId("4fcd909520668578cc1097dc"),
"comments" : [
{
"content" : "hello"
},
{
"content" : "word"
}
],
"title" : "one blog"
}
> post = {"username":"joe", "emails":["joe@example.com","joe@gmail.com","joe@yahoo.com"]}
{
"username" : "joe",
"emails" : [
"joe@example.com",
"joe@gmail.com",
"joe@yahoo.com"
]
}
> db.blog.insert(post)
> db.blog.findOne()
{
"_id" : ObjectId("4fd2e468b2ac404941134bed"),
"username" : "joe",
"emails" : [
"joe@example.com",
"joe@gmail.com",
"joe@yahoo.com"
]
}
--$addToSet適用于數(shù)組,如果數(shù)組中該元素已經(jīng)存在,該命令就不做任何操作后返回,否則將新元素插入數(shù)組。
> db.blog.update({"username":"joe"}, {"$addToSet": {"emails":"joe@gmail.com"}})
> db.blog.findOne()
{
"_id" : ObjectId("4fd2e468b2ac404941134bed"),
"username" : "joe",
"emails" : [
"joe@example.com",
"joe@gmail.com",
"joe@yahoo.com"
]
}
> db.blog.update({"username":"joe"}, {"$addToSet": {"emails":"joe@hotmail.com"}
> db.blog.findOne()
{
"_id" : ObjectId("4fd2e468b2ac404941134bed"),
"emails" : [
"joe@example.com",
"joe@gmail.com",
"joe@yahoo.com",
"joe@hotmail.com"
],
"username" : "joe"
}
--$addToSet和$each的組合可以將數(shù)組插入到另外一個(gè)數(shù)組中。
> db.blog.update({"username":"joe"},{"$addToSet": {"emails":{"$each":["joe@php.net","joe@example.com"]}}})
> db.blog.findOne()
{
"_id" : ObjectId("4fd2e468b2ac404941134bed"),
"emails" : [
"joe@example.com",
"joe@gmail.com",
"joe@yahoo.com",
"joe@hotmail.com",
"joe@php.net"
],
"username" : "joe"
}
--$pop從數(shù)組中刪除一個(gè)元素,如參數(shù)為1,表示從數(shù)組的尾部刪除一個(gè)元素,如果是-1,則從頭部刪除。
> db.blog.update({"username":"joe"}, {"$pop":{"emails":1}})
> db.blog.findOne()
{
"_id" : ObjectId("4fd2e468b2ac404941134bed"),
"emails" : [
"joe@example.com",
"joe@gmail.com",
"joe@yahoo.com",
"joe@hotmail.com"
],
"username" : "joe"
}
> db.blog.update({"username":"joe"}, {"$pop":{"emails":-1}})
> db.blog.findOne()
{
"_id" : ObjectId("4fd2e468b2ac404941134bed"),
"emails" : [
"joe@gmail.com",
"joe@yahoo.com",
"joe@hotmail.com"
],
"username" : "joe"
}
--$pull修改符則是從數(shù)據(jù)中刪除指定的元素
> db.blog.update({"username":"joe"}, {"$pull":{"emails":"joe@yahoo.com"}})
> db.blog.findOne()
{
"_id" : ObjectId("4fd2e468b2ac404941134bed"),
"emails" : [
"joe@gmail.com",
"joe@hotmail.com"
],
"username" : "joe"
}
--使數(shù)組中出現(xiàn)重復(fù)的元素,便于后面修改符的功能演示。
> db.blog.update({"username":"joe"}, {"$push": {"emails":"joe@gmail.com"}})
> db.blog.findOne()
{
"_id" : ObjectId("4fd2e468b2ac404941134bed"),
"emails" : [
"joe@gmail.com",
"joe@hotmail.com",
"joe@gmail.com"
],
"username" : "joe"
}
--在數(shù)組中,第一個(gè)元素的下標(biāo)是0,然后依次增長。下面的示例是將數(shù)組中下標(biāo)為1
--(第二個(gè)元素)的元素值修改為新值。
> db.blog.update({"username":"joe"}, {"$set":{"emails.1":"joe@example.com"}})
> db.blog.findOne()
{
"_id" : ObjectId("4fd2e468b2ac404941134bed"),
"emails" : [
"joe@gmail.com",
"joe@example.com",
"joe@gmail.com"
],
"username" : "joe"
}
--有的時(shí)候,特別是在修改查詢結(jié)果的時(shí)候,我們無法獲知結(jié)果文檔數(shù)組下標(biāo),MongoDB
--提供了$定位符表示查詢結(jié)果的下標(biāo)。但是該他只更新第一個(gè)匹配元素。
> db.blog.update({"emails":"joe@gmail.com"},{"$set":{"emails.$":"joe@hotmail.com"}})
> db.blog.findOne()
{
"_id" : ObjectId("4fd2e468b2ac404941134bed"),
"emails" : [
"joe@hotmail.com",
"joe@example.com",
"joe@gmail.com"
],
"username" : "joe"
}
6. upsert:
upsert是一種特殊的更新。要是沒有文檔符合更新條件,就會(huì)以這個(gè)條件和更新文檔為基礎(chǔ)創(chuàng)建一個(gè)新的文檔。如果找到了匹配的文檔,則正常更新。
> db.blog.remove()
> db.blog.update({"username":"joe"},{"username":"joe","age":30},true)
> db.blog.findOne()
{
"_id" : ObjectId("4fd2faac576cd9c101ac0f3d"),
"username" : "joe",
"age" : 30
}
下面的示例可以在新增的同時(shí),修改新增后的值。
> db.blog.remove()
> db.blog.update({"count":25},{"$inc":{"count":3}},true)
> db.blog.find()
{ "_id" : ObjectId("4fd2fd59576cd9c101ac0f3e"), "count" : 28 }
save是一個(gè)shell函數(shù),可以在文檔不存在時(shí)插入,存在時(shí)更新。upsert也可以完成同樣的工作,但是不如save命令方便。
> var x = db.blog.findOne()
> x.count = 40
40
> db.blog.save(x)
> db.blog.findOne()
{ "_id" : ObjectId("4fd2fde4576cd9c101ac0f3f"), "count" : 40 }
7. 返回已更新文檔:
可以通過getLastError命令獲取更新多個(gè)文檔時(shí)被更新的文檔數(shù)量。
> db.blog.remove()
> db.blog.insert({"name":"stephen"})
> db.blog.insert({"name":"stephen3"})
> db.blog.insert({"name":"stephen4"})
> db.blog.update({},{"$set":{"name":"liu"}},false,true)
--n:3表示修改的數(shù)量為3。
> db.runCommand({getLastError:1})
{
"updatedExisting" : true,
"n" : 3,
"connectionId" : 1,
"err" : null,
"ok" : 1
}
findAndModify可以原子性的修改查詢結(jié)果,也可以原子性的刪除查詢結(jié)果。
> db.blog.insert({"name":"stephen"})
> db.blog.insert({"name":"stephen2"})
> db.blog.find()
{ "_id" : ObjectId("4fd30cd117f6dccb7c058244"), "name" : "stephen" }
{ "_id" : ObjectId("4fd30cd417f6dccb7c058245"), "name" : "stephen2" }
> db.runCommand({"findAndModify":"blog", "query":{"name":"stephen2"},"update":{"$set":{"name":"stephen3"}}})
> db.blog.find()
{ "_id" : ObjectId("4fd30cd117f6dccb7c058244"), "name" : "stephen" }
{ "_id" : ObjectId("4fd30cd417f6dccb7c058245"), "name" : "stephen3" }
> runCommand({"findAndModify":"blog", "query":{"name":"stephen3"},"remove":true})
> db.blog.find()
{ "_id" : ObjectId("4fd30cd117f6dccb7c058244"), "name" : "stephen" }
findAndModify命令中每個(gè)鍵對(duì)應(yīng)的值如下:
findAndModify: 字符串類型的集合名稱。
query:查詢文檔,用來檢索文檔的條件。
sort: 排序結(jié)果的條件。
update:修改文檔,對(duì)所找到的文檔執(zhí)行的更新。
remove:布爾類型,表示是否刪除文檔。
new:布爾類型,表示返回的是更新前的文檔還是更新后的文檔。缺省是更新前文檔。
update和remove必須有一個(gè)存在,也只能有一個(gè)存在。如果沒有匹配的文檔,該命令會(huì)返回一個(gè)錯(cuò)誤。這個(gè)命令有些限制,即一次只能處理一個(gè)文檔,也不能執(zhí)行upsert操作,只能更新已有文檔。
相關(guān)文章
MongoDB快速入門筆記(二)之MongoDB的概念及簡單操作
MongoDB是面向集合的文檔式數(shù)據(jù)庫,不像關(guān)系數(shù)據(jù)庫那樣,有表,列、行,mongoDB數(shù)據(jù)庫則是由一系列的文檔組成。接下來通過本文給大家介紹MongoDB的概念及簡單操作,一起看看吧2016-06-06MongoDB數(shù)據(jù)去重與保存最新數(shù)據(jù)操作指南
在 MongoDB 數(shù)據(jù)庫中,我們經(jīng)常需要進(jìn)行數(shù)據(jù)去重并保留最新的數(shù)據(jù),本文將介紹如何使用 MongoDB 聚合操作完成這一任務(wù),并將結(jié)果保存到新的集合或者覆蓋原有的集合,感興趣的小伙伴跟著小編一起來看看吧2024-01-01mongodb的安裝和開機(jī)自啟動(dòng)詳細(xì)講解
這篇文章主要介紹了mongodb的安裝和開機(jī)自啟動(dòng)詳細(xì)講解,,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08mongodb增量備份腳本的實(shí)現(xiàn)和原理詳解
MongoDB本身不支持增量備份,所以這里介紹我找到的方法,下面這篇文章主要給大家介紹了關(guān)于mongodb增量備份腳本的實(shí)現(xiàn)和原理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-09-09MongoDB聚合$listSampledQueries實(shí)例操作
使用$listSampledQueries可以返回指定集合或所有集合的采樣查詢,analyzeShardKey命令使用采樣查詢來計(jì)算分片密鑰的讀寫分布指標(biāo),這篇文章主要介紹了MongoDB聚合$listSampledQueries,需要的朋友可以參考下2024-02-02MongoDB固定集合(capped collection)的知識(shí)小結(jié)
固定集合指的是事先創(chuàng)建,并且大小固定的集合。下面這篇文章主要給大家總結(jié)介紹了MongoDB固定集合(capped collection)的知識(shí),文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起學(xué)習(xí)學(xué)習(xí)吧2018-10-10使用centos系統(tǒng)中的crontab命令對(duì)mongodb定時(shí)備份恢復(fù)
編寫centos腳本使用crontab命令對(duì)mongodb定時(shí)執(zhí)行備份與恢復(fù)操作,并刪除指定天數(shù)前的備份2018-03-03