標籤:mongodb 文檔欄位增刪改
MongoDB 基於CRUD(create,read,update,delete)方式實現了對集合上的文檔進行增刪改查。對於集合上欄位的增刪改,可以使用set或者unset修改器來實現。也可以使用文檔替換的方式來實現。本文主要描述集合上欄位的增刪改,以及基於選項upsert的更新。
a.文法描述
db.collection.update(
<query>, //查詢或過濾條件
<update>, //修改器(被修改鍵及內容)
{
upsert: <boolean>, //為true或者false,如果為true,未找到匹配文檔則建立新文檔
multi: <boolean>, //用於確定是單行還是更新所有行(true為所有行)
writeConcern: <document> //設定寫關注,用於確保強一致性還是弱一致性
} //後面的3.2之後的文法參數基本相同
)
其他的如updateOne,updateMany等用法請參考:MongoDB 文檔更新
MongoDB集合上所有的寫操作特性
原子性操作(單個文檔層級原子性操作)
_id 欄位無法修改,即無法使用一個新的_id值來代替
由於更新導致文檔尺寸超出預期分配的情形,會自動調整填滿因數,重新分配空間
保留文檔欄位的順序,但是更新或重新命名可能導致欄位順序重新排序(_id總是文檔第一個欄位)
update的幾個常用修改器:
//$set修改器最常用,等同於RDBMSupdate的set子句
b.使用$set修改器修改年齡欄位
> db.chenji.update({name:"李旭"},{$set:{"年齡":24}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]})
{
"_id" : ObjectId("59987eee7cd6cda607043cd1"),
"name" : "李旭",
"年紀" : "三年級",
"年齡" : 24
}
> db.chenji.find({$or:[{name:"李旭"},{"年齡":24}]})
{
"_id" : ObjectId("59987eee7cd6cda607043cd1"),
"name" : "李旭",
"年紀" : "三年級",
"年齡" : 24
}
c. 文檔新增欄位($set實現)
> db.chenji.update({name:"李旭"},{$set:{add:"sex"}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"},{"年齡":24}]})
{
"_id" : ObjectId("59987eee7cd6cda607043cd1"),
"name" : "李旭",
"年紀" : "三年級",
"年齡" : 24,
"add" : "sex"
查看新增欄位add
> db.chenji.find({name:"李旭"},{"_id":0,"年紀":1,"年齡":1,add:1})
{ "年紀" : "三年級","年齡" : 24, "add" : "sex" }
d.文檔刪除欄位
欄位的刪除方法為{"$unset":{field_name:1}}
> db.chenji.update({name:"李旭"},{"$unset":{add:1}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]})
{
"_id" : ObjectId("59987eee7cd6cda607043cd1"),
"name" : "李旭",
"年紀" : "三年級",
"年齡" : 24
}
> db.chenji.find({name:"李旭"},{"_id":0,"年紀":1,"年齡":1,add:1})
{ "年紀" : "三年級","年齡" : 24 }
刪除年齡欄位:
> db.chenji.update({name:"李旭"},{"$unset":{"年齡":1}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]})
{
"_id" : ObjectId("59987eee7cd6cda607043cd1"),
"name" : "李旭",
"年紀" : "三年級"
}
刪除年紀欄位:
> db.chenji.update({name:"李旭"},{"$unset":{"年紀":1}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]})
{ "_id" :ObjectId("59987eee7cd6cda607043cd1"), "name" : "李旭"}
>
添加欄位:age和年齡
> db.chenji.update({name:"李旭"},{$set:{"年級":"一年級"}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.update({name:"李旭"},{$set:{"age":9}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]})
{
"_id" : ObjectId("59987eee7cd6cda607043cd1"),
"name" : "李旭",
"age" : 9,
"年級" : "一年級"
}
e.欄位值的增加或減少
當使用$inc修改器時,當欄位不存在時,會自動建立該欄位,如果存在,則在原有值的基礎上進行增加或者減少
//$inc主要是用於專門進行數位增加或減少,因此$inc只能用於整型,長整形,或者雙精確度浮點型的值
//$inc不支援字串,數組以及其他非數位值
//注,對於$inc的操作,$set也可以完成。$inc存在的理由是$inc更高效
> db.chenji.update({name:"李旭"},{$inc:{num:100}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]})
{
"_id" : ObjectId("59987eee7cd6cda607043cd1"),
"name" : "李旭",
"age" : 9,
"年級" : "一年級",
"num" : 100
}
再次update這個num欄位會和第一次的100增加101
> db.chenji.update({name:"李旭"},{$inc:{num:101}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]})
{
"_id" : ObjectId("59987eee7cd6cda607043cd1"),
"name" : "李旭",
"age" : 9,
"年級" : "一年級",
"num" : 201
}
基於$inc的負值:
> db.chenji.update({name:"李旭"},{$inc:{num:-100}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]}).pretty()
{
"_id" : ObjectId("59987eee7cd6cda607043cd1"),
"name" : "李旭",
"age" : 9,
"年級" : "一年級",
"num" : 101
}
> db.chenji.update({name:"李旭"},{$inc:{num:-50}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]}).pretty()
{
"_id" : ObjectId("59987eee7cd6cda607043cd1"),
"name" : "李旭",
"age" : 9,
"年級" : "一年級",
"num" : 51
下面使用非數字來實現$inc,報錯如下:
db.chenji.update({name:"李旭"},{$inc:{num:"1ab"}})
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 14,
"errmsg" : "Cannot increment with non-numeric argument:{num: \"1ab\"}"
}
})
f. 時間戳記欄位的增加及自動更新($currentDate)
> db.chenji.update({name:"李旭"},{$inc:{num:60},$currentDate:{lastModified:true}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]}).pretty()
{
"_id" : ObjectId("59987eee7cd6cda607043cd1"),
"name" : "李旭",
"age" : 9,
"年級" : "一年級",
"num" : 231,
"lastModified" : ISODate("2017-08-20T08:39:53.601Z")
}
f.文檔欄位重新命名($rename)
> db.chenji.update({name:"李旭"},{$rename:{"name":"ename"}})
WriteResult({ "nMatched" : 1,"nUpserted" : 0, "nModified" : 1 })
> db.chenji.find({$or:[{name:"李旭"}]}).pretty()
> db.chenji.find({$or:[{ename:"李旭"}]}).pretty()
{
"_id" : ObjectId("59987eee7cd6cda607043cd1"),
"age" : 9,
"年級" : "一年級",
"num" : 231,
"lastModified" :ISODate("2017-08-20T08:39:53.601Z"),
"ename" : "李旭"
}
> db.chenji.find({ename:"李旭"},{"_id":0,ename:1})
{ "ename" : "李旭"}
對整個集合上所有文檔欄位進行重新命名:
>db.chenji.update({},{$rename:{"name":"ename"}},{multi:true})
WriteResult({ "nMatched" : 7,"nUpserted" : 0, "nModified" : 6 }) /此次修改為11條,因為前面以及修改過1條
> db.chenji.find();
{ "_id" :ObjectId("59990ec402730a37fe1ee79e"), "年紀": "二年級", "年齡" : "12", "ename" :"建偉" }
{ "_id" :ObjectId("59987eee7cd6cda607043cd1"), "age" : 9, "年級": "一年級", "num" : 231, "lastModified" :ISODate("2017-08-20T08:39:53.601Z"), "ename" : "李旭"}
{ "_id" :ObjectId("5998860a7cd6cda607043cd2"), "年紀": "三年級", "年齡" : "14", "ename" :"張三" }
{ "_id" :ObjectId("599886227cd6cda607043cd3"), "年紀": "四年級", "年齡" : "16", "ename" :"王三" }
{ "_id" :ObjectId("599886357cd6cda607043cd4"), "年紀": "一年級", "年齡" : "8", "ename" :"王七" }
{ "_id" :ObjectId("599886537cd6cda607043cd5"), "年紀": "一年級", "年齡" : "9", "ename" :"張巴" }
{ "_id" :ObjectId("5998866e7cd6cda607043cd6"), "年紀": "七年級", "年齡" : "16", "ename" :"謝娜" }
>
g.upsert選項用法
/ upsert相當於oracle的merge into或者mysql中的replaceinto
// upsert即是當集合中匹配到滿足條件的文檔時,則更新文檔,否則則是新增文檔。前提是該選項的值為true,預設為flase。
> //下面的示範的是匹配到文檔時的例子
小結:
a、對於文檔上資料的修改有多種方式(修改器),常用的為$set修改器以及$inc
b、$inc是一種高效的資料修改器,通常用於實現數值的增加或減少,僅支援資料類型。
c、對於文檔欄位的增加,可以使用$set,$unset,$inc,$currentDate等方式
d、對於文檔欄位的刪除,使用$unset方式來實現
e、upsert選項可以實現匹配的文檔則更新,不匹配時則插入
參考資料:
http://blog.csdn.net/leshami/article/details/54930588
本文出自 “10931853” 部落格,請務必保留此出處http://wujianwei.blog.51cto.com/10931853/1957832
MongoDB 文檔欄位增刪改