標籤:style blog http io os 使用 java ar 資料
-
MongoDB數組修改器更新資料
-
2013-04-22 10:20:40 我來說兩句 來源:薑志福 的BLOG
-
收藏 我要投稿
-
MongoDB數組修改器更新資料 這裡,我們將瞭解一下數組修改器。數組,是我們經常看到和使用到的且非常有用的資料結構:它不僅可以通過索進行引用,還可以作為集合來使用。數組修改器,顧名思義,它是用來修改數組的,而不能用來修改整數或者字串。數組修改器不多,就那麼幾個,但熟練掌握它後,將給我們帶來非常方便的操作。下面,我們來瞭解一下:> db.user.findOne(){ "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"), "age" : 23, "favorite" : { "1" : "reading", "2" : "swimming", "3" : "listening music" }, "fname" : "jeff", "height" : 166, "lname" : "jiang", "relationships" : [ { "fname" : "deng", "lname" : "pan" }, { "fname" : "qiang", "lname" : "he" }, { "fname" : "dongren", "lname" : "zeng" } ]}以上是我的還在完善中的個人資訊文檔。假設最近我又交了一個好朋友,我想把他加到我的人際關係“relationships”數組中。這時,$push修改器就派上用場了。$push的作用就是,如果指定的鍵已經存在,它會向已有的數組末尾加入一個元素,要是沒有就會建立一個新的數組。下面我們把新朋友加進去。> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$push:{"relationships":{"fname":"xiong","lname":"lan"}}})> db.user.findOne(){ "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"), "age" : 23, "favorite" : { "1" : "reading", "2" : "swimming", "3" : "listening music" }, "fname" : "jeff", "height" : 166, "lname" : "jiang", "relationships" : [ { "fname" : "deng", "lname" : "pan" }, { "fname" : "qiang", "lname" : "he" }, { "fname" : "dongren", "lname" : "zeng" }, { "fname" : "xiong", "lname" : "lan" } ]}有加就有減,那麼怎麼對數組進行“減”操作呢。能達到對數組“減”目的的修改器有兩個,$pop和$pull。$pop和$pull又有區別,我們來分別實驗。首先是$pop> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$pop:{"relationships":1}})> db.user.findOne(){ "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"), "age" : 23, "favorite" : { "1" : "reading", "2" : "swimming", "3" : "listening music" }, "fname" : "jeff", "height" : 166, "lname" : "jiang", "relationships" : [ { "fname" : "deng", "lname" : "pan" }, { "fname" : "qiang", "lname" : "he" }, { "fname" : "dongren", "lname" : "zeng" } ]}從上面可以看出,它把我們剛加進去的朋友又刪除了,也就是說它從數組的最後刪除。那麼,如果我們想從數組的開頭刪除該怎麼辦呢。很簡單,把上面的“1”改成“-1”,它將逆向操作。下面看一下:> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$pop:{"relationships":-1}})> db.user.findOne(){ "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"), "age" : 23, "favorite" : { "1" : "reading", "2" : "swimming", "3" : "listening music" }, "fname" : "jeff", "height" : 166, "lname" : "jiang", "relationships" : [ { "fname" : "qiang", "lname" : "he" }, { "fname" : "dongren", "lname" : "zeng" } ]}從結果可以看出,它達到了我們預期的目的。那麼如果我們想刪除數組中間的呢。這時,$pull派上用場。首先,我們先將新朋友加進去,這裡我不再示範。但我們可以想到“dongren”這個人是在數組的中間。現在我們要將他刪除:> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$pull:{"relationships":{"fname":"dongren","lname":"zeng"}}})> db.user.findOne(){ "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"), "age" : 23, "favorite" : { "1" : "reading", "2" : "swimming", "3" : "listening music" }, "fname" : "jeff", "height" : 166, "lname" : "jiang", "relationships" : [ { "fname" : "qiang", "lname" : "he" }, { "fname" : "xiong", "lname" : "lan" } ]}從上面可以看出,$pull可以將數組中間的資料刪除。這裡還有一點要注意,$pull會將所有匹配到的資料都刪除,這裡我就不做實驗了。下面,我們再來看看$push還有什麼特點,我們再往數組裡插入一相同的資料,看看會如何:> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$push:{"relationships":{"fname":"xiong","lname":"lan"}}})> db.user.findOne(){ "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"), "age" : 23, "favorite" : { "1" : "reading", "2" : "swimming", "3" : "listening music" }, "fname" : "jeff", "height" : 166, "lname" : "jiang", "relationships" : [ { "fname" : "qiang", "lname" : "he" }, { "fname" : "xiong", "lname" : "lan" }, { "fname" : "xiong", "lname" : "lan" } ]}結果表明,它是能正常插入到數組的。而在實際生產環境中,我們都不想看到這樣的結果,那麼,這裡又出現了兩個可以用的修改器:$ne和$addToSet。$ne主要拿來判斷,若數組裡面有這個值,則不插入;沒有才插入。> db.user.update({"relationships.fname":{$ne:"xiong"}},{$set:{"fname":"xiong","lname":"lan"}})> db.user.findOne(){ "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"), "age" : 23, "favorite" : { "1" : "reading", "2" : "swimming", "3" : "listening music" }, "fname" : "jeff", "height" : 166, "lname" : "jiang", "relationships" : [ { "fname" : "qiang", "lname" : "he" }, { "fname" : "xiong", "lname" : "lan" }, { "fname" : "xiong", "lname" : "lan" } ]}由結果可以看出,由於該資料在數組中已經存在,所以不再插入。其實,$addToSet比$ne更好用,它可以自己判斷資料是否存在,而且它和$each結合使用,還能同時在數組中插入多個資料,這是$ne沒辦法辦到的,下面我們來看一下$addToSet的用法,這裡順便結合了$each的使用:> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$addToSet:{"relationships":{$each:[{"fname":"xiong","lname":"lan"},{"fname":"dongren","lname":"zeng"}]}}})> db.user.findOne(){ "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"), "age" : 23, "favorite" : { "1" : "reading", "2" : "swimming", "3" : "listening music" }, "fname" : "jeff", "height" : 166, "lname" : "jiang", "relationships" : [ { "fname" : "qiang", "lname" : "he" }, { "fname" : "xiong", "lname" : "lan" }, { "fname" : "xiong", "lname" : "lan" }, { "fname" : "dongren", "lname" : "zeng" } ]}在修改語句中,我們想同時插入{"fname":"xiong","lname":"lan"},{"fname":"dongren","lname":"zeng"}兩個資料,但在原數組中,{"fname":"xiong","lname":"lan"}這個資料已經存在,所以它只插入了後面那條。達到了我們想要的目的。所以,我個人更喜歡使用$addToSet。 有時候數組有多個值,而我們只想對其中的一部分進行操作。如果我們把整個文檔都抄下來,那太麻煩也太愚蠢了。好在mongodb給我們提供了兩種簡便方法:通過位置或者操作符“$”。下面我們來分別看看這兩種方法怎麼使用。首先是通過數組位置來操作。數組都是以0開頭的,可以將下標直接作為鍵來選擇元素。例如,我們想給數組的第一個資料加上年齡索引值對,我們可以這麼操作:> db.user.update({"_id" : ObjectId("4ffcb2ed65282ea95f7e3304")},{$set:{"relationships.0.age":22}})> db.user.findOne(){ "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"), "age" : 23, "favorite" : { "1" : "reading", "2" : "swimming", "3" : "listening music" }, "fname" : "jeff", "height" : 166, "lname" : "jiang", "relationships" : [ { "age" : 22, "fname" : "qiang", "lname" : "he" }, { "fname" : "deng", "lname" : "pan" }, { "fname" : "xiong", "lname" : "lan" } ]}可是很多情況下,不預先查詢文檔我們就不知道要修改數組的元素的下標。這時定位操作符“$”就很好用了。它就是用來定位查詢文檔已匹配的元素,並進行更新。我們來看看它怎麼用:> db.user.update({"relationships.fname":"xiong"},{$set:{"relationships.$.age":22}})> db.user.findOne(){ "_id" : ObjectId("4ffcb2ed65282ea95f7e3304"), "age" : 23, "favorite" : { "1" : "reading", "2" : "swimming", "3" : "listening music" }, "fname" : "jeff", "height" : 166, "lname" : "jiang", "relationships" : [ { "age" : 22, "fname" : "qiang", "lname" : "he" }, { "age" : 22, "fname" : "deng", "lname" : "pan" }, { "age" : 22, "fname" : "xiong", "lname" : "lan" } ]}
MongoDB數組修改器更新資料