db.collectionName.insert({ bar : baz )} 批量插入:如果要向集合插入多個文檔,使用批量插入會快一些。batchInsert函數(shù)實(shí)現(xiàn)批量插入,它接..."/>
溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

03.Mongodb創(chuàng)建、更新和刪除文檔。

發(fā)布時間:2020-08-04 17:58:38 來源:網(wǎng)絡(luò) 閱讀:791 作者:貴在堅持 欄目:MongoDB數(shù)據(jù)庫

 

插入:

>db.collectionName.insert({"bar":"baz")}

 

批量插入:
如果要向集合插入多個文檔,使用批量插入會快一些。

batchInsert函數(shù)實(shí)現(xiàn)批量插入,它接受一個文檔數(shù)組作為參數(shù)。

>db.collectionName.batchInsert([ {"_id:0}, {"_id":1}, {"_id":2} ])

>db.collectionName.find()

{"_id:0}

{"_id":1}

{"_id":2}

 

刪除文檔:

>db.collectionName.remove({})

上述命令只刪除集合里面的文檔,并不會刪除集合本身,也不會刪除集合的元信息。

remove函數(shù)可以接受一個查詢文檔作為限定條件作為可選參數(shù)。給定參數(shù)后,符合條件的文檔才會被刪除。

>db.collectionName.remove({"xxxx":true})

刪除數(shù)據(jù)是永久性的,不能撤銷,也不能恢復(fù)。

 

刪除速度:

刪除文檔通常很快,但是如果要清空集合,使用drop直接刪除集合會更快。

 

例如,插入測試數(shù)據(jù):

>for (var i=0; i < 1000000; i++) {

... db.tmps.insert({"foo":i})

... }

 

使用remove刪除,并記錄花費(fèi)時間:

var timeRemoves = function() {

    var start = (new Date()).getTime();

    db.tmps.remove({});

    db.tmps.findOne();//Make sure the remove finishes before continuing

    var timeDiff = (new Date()).getTime() - start;

    print("Remove took:"+timeDiff+"ms");

}

 

 

更新文檔:

 

db.collection.update(

   <query>,

   <update>,

   {

     upsert: <boolean>,

     multi: <boolean>,

     writeConcern: <document>

   }

)

update有兩個參數(shù),一個是查詢文檔,用于定位需要更新的文檔,另一個是修改器(modifier)文檔,用于說明要對找到的文檔進(jìn)行哪些修改。

更新操作是不可分割的:若是兩個更新同時發(fā)生,先到達(dá)服務(wù)器的先執(zhí)行,接著執(zhí)行令一個。

 

·文檔替換:

最簡單的更新就是用一個新文檔完全替換匹配的文檔。這適用于進(jìn)行大規(guī)模式遷移的情況。

例:

默認(rèn)文檔結(jié)構(gòu):

>db.tmps.findOne()

{

        "_id" : ObjectId("54f125773d3fab4bb9d6dc63"),

        "Name" : "joe",

        "Friends" : 32,

        "Enemies" : 2,

        "Date" : ISODate("2015-02-28T02:18:21.858Z")

}

寫一個definetmps.js文檔,內(nèi)容如下:

var replaceupdate = function(){

        db.tmps.findOne();

        var joe = db.tmps.findOne({"Name":"joe"});

        joe.relationships = {"Friends":joe.Friends,"Enemies":joe.Enemies};

        joe.Username = joe.Name;

        delete joe.Friends;

        delete joe.Enemies;

        delete joe.Name;

        db.tmps.update({"Name":"joe"},joe);

        db.tmps.findOne();

}

然后再Shell中加載,并執(zhí)行函數(shù)replaceupdate(),最后驗證文檔結(jié)構(gòu):

>load("definetmps.js")

true

>replaceupdate()

>db.tmps.findOne()

{

        "_id" : ObjectId("54f125773d3fab4bb9d6dc63"),

        "Date" : ISODate("2015-02-28T02:18:21.858Z"),

        "relationships" : {

                "Friends" : 32,

                "Enemies" : 2

        },

        "Username" : "joe"

}

 

一個常見的錯誤是查詢條件匹配到了多個文檔,然后更新時由于第二個參數(shù)存在就產(chǎn)生重復(fù)的"_id"值。數(shù)據(jù)庫就會拋出錯誤,任何文檔都不會更新。

 

·使用修改器:

通常文檔只會有一部分要更新??梢允褂迷有缘母滦薷钠?,指定對文檔中的某些字段進(jìn)行更新。

 

1."$set"修改器入門:

"$set"用來指定一個字段的值。如果這個字段不存在,則創(chuàng)建它。這對更新模式或增加用戶自定義鍵來說非常方便。

例:存儲用戶資料的文檔,結(jié)構(gòu)如下,

>db.tmps.findOne()

{

        "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

        "name" : "joe",

        "age" : 32,

        "sex" : "male",

        "location" : "Wisconsin"

}

 

我們要添加一個新鍵,用戶喜歡的書籍進(jìn)去,可以使用"$set"

>db.tmps.update({"_id" : ObjectId("54f131d0f755cba4f8d7cb2a")},

... {"$set" : {"favorite book" : "war and peace"}})

 

然后我們文檔就有了新鍵:

>db.tmps.findOne()

{

        "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

        "name" : "joe",

        "age" : 32,

        "sex" : "male",

        "location" : "Wisconsin",

        "favorite book" : "war and peace"

}

這個時候喜歡書的鍵已經(jīng)存在了,用戶想換一本,可直接通過$set完成更新。

 

"$set"甚至可以修改鍵的類型。例如用戶喜歡很多本書,就可以將"favorite book"鍵值變成一個數(shù)組:

>db.tmps.update({"_id" : ObjectId("54f131d0f755cba4f8d7cb2a")},

... {"$set" : {"favorite book" : ["book1","book2","book3"]}})

 

如果用戶不喜歡讀書,可以用"$unset"將這個鍵值完全刪除。

>db.tmps.update({"_id" : ObjectId("54f131d0f755cba4f8d7cb2a")},

... {"$unset" : {"favorite book" : 1}})

 

也可以用"$set"修改內(nèi)嵌文檔:

>db.tmps.findOne()

{

        "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

        "name" : "joe",

        "age" : 32,

        "sex" : "male",

        "location" : "Wisconsin",

        "contact" : {

                "email" : "123@qq.com",

                "pnum" : "13212342112"

        }

}

>db.tmps.update({"name":"joe"},

... {"$set":{"contact.email":"1450327195@qq.com"}})

>db.tmps.findOne()

{

        "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

        "name" : "joe",

        "age" : 32,

        "sex" : "male",

        "location" : "Wisconsin",

        "contact" : {

                "email" : "1450327195@qq.com",

                "pnum" : "13212342112"

        }

}

 

2.增加和減少"$inc"

"$inc"修改器用來增加已有鍵的值,改鍵不存在就會創(chuàng)建一個。

"$inc""$set"的用法類似,就是專門用來增加和減少數(shù)字的。"$inc"只能用于×××、長×××或雙精度浮點(diǎn)型的值。

>db.tmps.update({"name":"joe"},

... {"$inc":{"age":1}})

>db.tmps.findOne()

{

        "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

        "name" : "joe",

        "age" : 33,

        "sex" : "male",

        "location" : "Wisconsin",

        "contact" : {

                "email" : "1450327195@qq.com",

                "pnum" : "13212342112"

        }

}

 

3.數(shù)組修改器

有一大類很重要的修改器可用于操作數(shù)組。數(shù)組是常用且非常有用的數(shù)據(jù)結(jié)構(gòu):它們不僅是可通過索引進(jìn)行引用的列表,而且還可以作為數(shù)據(jù)集(set)來用。

 

4.添加元素"$push"

如果數(shù)組已經(jīng)存在,"$push"會向已有數(shù)組末尾添加一個元素,沒有則創(chuàng)建一個新數(shù)組。

如:

>db.tmps.update({"name":"joe"},

... {"$push":{"comments":{"name":"bob","email":"bob@qq.com"}}})

 

還添加繼續(xù)使用"$push",這是一種比較簡單的"$push"使用形式,也可以將它應(yīng)用在一些比較復(fù)雜的數(shù)組操作中。

使用"$each"子操作符,可以通過一次"$push"操作添加多個值。

db.tmps.update({"name":"joe"},

... {"$push":{"comments":{"$each":[{"name":"bob","email":"bob@qq.com"},{"name":"carlo","email":"carlo@qq.com"}]}}})

PS:通過"$set"的實(shí)現(xiàn):

>db.tmps.update({"name":"joe"},

... {"$set":{"comments":[{"name":"bob","email":"bob@qq.com"},{"name":"carlo","email":"carlo@qq.com"}]}})

 

如果希望數(shù)組的最大長度是固定的,那么可以將"$slice""$push"組合在一起使用,這樣就可以保證數(shù)組不會超出設(shè)定好的最大長度,這實(shí)際上就得到了一個最多包含N個元素的數(shù)組。

>db.tmps.update({"name":"joe"},

... {"$push":{"favoritetop":{

...   "$each":[{"name":"book","level":3},

...            {"name":"music","level":1},

...            {"name":"movie","level":4},

...            {"name":"run","level":2}],

...   "$slice":-3,

...   "$sort":{"level":-1}}}})

注意:不能只將"slice"或者"$sort""$push"配合使用,且必須使用"$each"。

 

5.將數(shù)組作為數(shù)據(jù)集使用

如果將數(shù)組作為數(shù)據(jù)集使用,保證數(shù)組元素不會重復(fù)??梢栽诓樵兾臋n中用"$ne"來實(shí)現(xiàn)。

(test)>db.tmps.findOne()

{

        "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

        "name" : "joe",

        "age" : 43,

        "emails" : [

                "aa@qq.com",

                "bb@qq.com",

                "cc@qq.com"

        ]

}

>db.tmps.update({"emails":{"$ne":"aa@qq.com"}}, {"$push":{"emails":"aa@qq.com"}})

WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })

>db.tmps.update({"emails":{"$ne":"dd@qq.com"}}, {"$push":{"emails":"a@qq.com"}})

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

由這里可以看出,$ne是在查詢中做判斷的,如果判斷內(nèi)容不存在則執(zhí)行后面的$push操作。

 

也可以用"$addToSet"來實(shí)現(xiàn):

>db.tmps.findOne()

{

        "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

        "name" : "joe",

        "age" : 43,

        "emails" : [

                "aa@qq.com",

                "bb@qq.com",

                "cc@qq.com"

        ]

}

>db.tmps.update({"name":"joe"},

... {"$addToSet":{"emails":"aa@qq.com"}})

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

>db.tmps.update({"name":"joe"},

... {"$addToSet":{"emails":"dd@qq.com"}})

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

(test)>db.tmps.findOne()

{

        "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

        "name" : "joe",

        "age" : 43,

        "emails" : [

                "aa@qq.com",

                "bb@qq.com",

                "cc@qq.com",

                "dd@qq.com"

        ]

}

 

"$addToSet""$each"組合起來,可以添加多個不同的值,而使用"$ne""$push"組合則不能實(shí)現(xiàn)。

>db.tmps.update({"name":"joe"},

... {"$addToSet":{"emails":{"$each":[

... "a@qq.com","b@qq.com","c@qq.com","d@qq.com"]}}})

 

6.刪除元素

有幾個從數(shù)組中刪除元素的方法。若是把數(shù)組看成隊列或者棧,可以用"$pop"這個修改器從數(shù)組任何一端刪除元素。

>db.tmps.update({"name":"joe"},

... {"$pop":{"emails":1}})    //從數(shù)組末尾刪除元素。

 

>db.tmps.update({"name":"joe"}, {"$pop":{"emails":-1}})   //從數(shù)組開頭刪除元素。

 

有時需要基于特定條件來刪除元素,而不僅僅是依據(jù)元素位置,這時可以用"$pull"。它會將所有匹配文檔全部刪除,而不是只刪除一個。對數(shù)組[1,1,2,1]執(zhí)行pull 1,結(jié)果就只剩一個元素的數(shù)組[2]。

 

7.基于位置的數(shù)組修改器

通過位置或者定位操作符("$")

數(shù)組下標(biāo)都是以0開始的,可以將下標(biāo)直接作為建來選擇元素。

>db.tmps.findOne()

{

        "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

        "name" : "joe",

        "age" : 43,

        "emails" : [

                "bb@qq.com",

                "cc@qq.com",

                "dd@qq.com",

                "a@qq.com",

                "b@qq.com",

                "c@qq.com"

        ]

}

>db.tmps.update({"name":"joe"},

... {"$set":{"emails.3":"aa@qq.com"}})

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

>db.tmps.findOne()

{

        "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

        "name" : "joe",

        "age" : 43,

        "emails" : [

                "bb@qq.com",

                "cc@qq.com",

                "dd@qq.com",

                "aa@qq.com",

                "b@qq.com",

                "c@qq.com"

        ]

}

 

很多情況下,不預(yù)先查詢文檔就不能知道要修改數(shù)組的下標(biāo),為了解決這個問題,Mongodb提供了定位操作符"$",用來定位查詢已經(jīng)匹配的數(shù)組元素,并進(jìn)行更新。如下:

>db.blog.findOne()

{

        "_id" : ObjectId("54f56483d9c146390ce21c58"),

        "title" : "my frist blog.",

        "content" : "a b c d e f g ....",

        "comments" : [

                {

                        "comment" : "good",

                        "author" : "joe",

                        "votes" : 0

                },

                {

                        "comment" : "it's ok",

                        "author" : "john",

                        "votes" : 2

                }

        ]

}

>db.blog.update({"comments.author":"joe"},

... {"$set":{"comments.$.author":"jim"}})

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

>db.blog.findOne()

{

        "_id" : ObjectId("54f56483d9c146390ce21c58"),

        "title" : "my frist blog.",

        "content" : "a b c d e f g ....",

        "comments" : [

                {

                        "comment" : "good",

                        "author" : "jim",

                        "votes" : 0

                },

                {

                        "comment" : "it's ok",

                        "author" : "john",

                        "votes" : 2

                }

        ]

}

注意,定位符只更新第一個匹配元素。

 

特殊的更新:upsert

upsert更新,要是沒有找到符合更新條件的文檔,就會以這個條件和更新文檔為基礎(chǔ)創(chuàng)建一個新的文檔。如果找到匹配文檔,則正常更新。

update操作的第三個參數(shù)處為true,則是upsert更新!

db.test.update({"url":"www.example.com"}, {"$inc":{"pageviews":1}},true)    // 此為簡寫

db.test.update({"url":"www.example.com"}, {"$inc":{"pageviews":1}},{upsert:true})

 

save函數(shù):

使用save函數(shù)時,如果文檔不存在,它會自動創(chuàng)建文檔;如果文檔存在,它就更新這個文檔。它只有一個參數(shù):文檔。如果這個文檔有"_id"鍵,save會調(diào)用upsert;否則調(diào)用insert。

>db.tmps.findOne()

{

        "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

        "name" : "joe",

        "age" : 43,

        "emails" : [

                "bb@qq.com",

                "cc@qq.com",

                "dd@qq.com",

                "aa@qq.com",

                "b@qq.com",

                "c@qq.com"

        ]

}

>var x = db.tmps.findOne()

(test)>x.age = 23

23

>db.tmps.save(x)

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

>db.tmps.findOne()

{

        "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"),

        "name" : "joe",

        "age" : 23,

        "emails" : [

                "bb@qq.com",

                "cc@qq.com",

                "dd@qq.com",

                "aa@qq.com",

                "b@qq.com",

                "c@qq.com"

        ]

}

 

更新多個文檔:

默認(rèn)情況,更新只對匹配條件的第一個文檔執(zhí)行操作。要更新所有匹配,可以將update的第四個參數(shù)設(shè)置為true。

>db.tmps.find()

{ "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"), "name" : "joe", "age" : 23 }

{ "_id" : ObjectId("54f6aa46d9c146390ce21c5f"), "name" : "peter", "age" : 23 }

{ "_id" : ObjectId("54f6aa4cd9c146390ce21c60"), "name" : "carlo", "age" : 23 }

>db.tmps.update({"age":23}, {"$set":{"age":24}},false,true)     //簡寫方式

>db.tmps.update({"age":23}, {"$set":{"age":24}},{upsert:false,multi:true})

>db.tmps.find()

{ "_id" : ObjectId("54f131d0f755cba4f8d7cb2a"), "name" : "joe", "age" : 24 }

{ "_id" : ObjectId("54f6aa46d9c146390ce21c5f"), "name" : "peter", "age" : 24 }

{ "_id" : ObjectId("54f6aa4cd9c146390ce21c60"), "name" : "carlo", "age" : 24 }

 

寫入安全機(jī)制(write concern

是一種客戶端設(shè)置,用于控制寫入的安全級別。

 

 

PS:內(nèi)容整理于《Mongodb權(quán)威指南》

 

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI