mongodb修改器一覽表($inc/$set/$unset/$push/$pop/upsert......)

本文對原文進行了格式化和排版操作,作者大神講得非常清楚。mongodb_修改器(inc/inc/set/unset/unset/push/$pop/upsert…)
mongodb CRUD 增刪改查一應俱全 Mark一下。希望能幫到更多的人。
原文:https://blog.csdn.net/MCpang/article/details/7752736 ,

對於文檔的更新除替換外,針對某個或多個文檔只需要部分更新可使用原子的更新修改器,能夠高效的進行文檔更新。更新修改器是中特殊的鍵,
用來指定複雜的操作,比如增加、刪除或者調整鍵,還可能是操作數組或者內嵌文檔。

1.$inc

這個修改器幹什麼使的呢?看看下面示例的具體操作後的結果即可知道。

示例文檔:{“uid”:“201203”,“type”:“1”,size:10}

> db.b.insert({"uid":"201203","type":"1",size:10})
> db.b.find()
{ "_id" : ObjectId("5003b6135af21ff428dafbe6"), 
  "uid" : "201203", 
  "type" : "1",
  "size" : 10 
}
> db.b.update({"uid" : "201203"},{"$inc":{"size" : 1}})
> db.b.find()
{ "_id" : ObjectId("5003b6135af21ff428dafbe6"), 
  "uid" : "201203", 
  "type" : "1",
  "size" : 11 
}
> db.b.update({"uid" : "201203"},{"$inc":{"size" : 2}})
> db.b.find()
{ "_id" : ObjectId("5003b6135af21ff428dafbe6"), 
  "uid" : "201203", 
  "type" : "1",
  "size" : 13 
}
> db.b.update({"uid" : "201203"},{"$inc":{"size" : -1}})
> db.b.find()
{ "_id" : ObjectId("5003b6135af21ff428dafbe6"), 
  "uid" : "201203", 
  "type" : "1",
  "size" : 12 
}

得出結論:修改器inc滿滿使inc可以對文檔的某個值爲數字型(只能爲滿足要求的數字)的鍵進行增減的操作。 (這裏有個問題:上篇中說到更新默認只對滿足條件的記錄集中第一個文檔進行更新,那麼使用inc修改器之後,還是一樣嗎?)

2.$set

用來指定一個鍵並更新鍵值,若鍵不存在並創建。來看看下面的效果:

> db.a.findOne({"uid" : "20120002","type" : "3"})
{ "_id" : ObjectId("500216de81b954b6161a7d8f"), 
  "desc" : "hello world2!", 
  "num": 40,
  "sname" : "jk", 
  "type" : "3", 
  "uid" : "20120002" 
}

–size鍵不存在的場合

> db.a.update(
	{"uid" : "20120002","type" : "3"},
	{"$set":{"size":10}}
	)
> db.a.findOne({"uid" : "20120002","type" : "3"})
{ "_id" : ObjectId("500216de81b954b6161a7d8f"), 
  "desc" : "hello world2!", 
  "num": 40, 
  "size" : 10, 
  "sname" : "jk", 
  "type" : "3", 
  "uid" : "20120002" 
}

–sname鍵存在的場合

> db.a.update(
	{"uid" : "20120002","type" : "3"},
	{"$set": {"sname":"ssk"} }
	)
> db.a.find()
{ "_id" : ObjectId("500216de81b954b6161a7d8f"), 
  "desc" : "hello world2!", 
  "num" : 40, 
  "size" : 10, 
  "sname" : "ssk", 
  "type" : "3", 
  "uid" : "20120002" 
}
{ "_id" : ObjectId("50026affdeb4fa8d154f8572"), 
  "desc" : "hello world1!", 
  "num" : 50, 
  "sname" : "jk", 
  "type" : "1", 
  "uid" : "20120002" 
}

–可改變鍵的值類型

> db.a.update(
	{"uid" : "20120002","type" : "3"},
	{"$set": {"sname":["java",".net","c++"]} }
	)
> db.a.findOne({"uid" : "20120002","type" : "3"})
{
        "_id" : ObjectId("500216de81b954b6161a7d8f"),
        "desc" : "hello world2!",
        "num" : 40,
        "size" : 10,
        "sname" : [
                "java",
                ".net",
                "c++"
        ],
        "type" : "3",
        "uid" : "20120002"
}

對於內嵌的文檔,$set又是如何進行更新的內嵌的文檔的呢,請看下面的示例:
示例文檔:

{
	"name":"toyota",
	"type":"suv",
	"size":
		{
		"height":10,
		"width":5,
		"length":15
		}
}
> db.c.findOne({"name":"toyota"})
{
        "_id" : ObjectId("5003be465af21ff428dafbe7"),
        "name" : "toyota",
        "type" : "suv",
        "size" : {
                "height" : 10,
                "width" : 5,
                "length" : 15
        }
}
> db.c.update(
 	{"name": "toyota" },
 	{"$set": {"size.height":8} }
 	)
> db.c.findOne({"name":"toyota"})
{
        "_id" : ObjectId("5003be465af21ff428dafbe7"),
        "name" : "toyota",
        "type" : "suv",
        "size" : {
                "height" : 8,
                "width" : 5,
                "length" : 15
        }
}
> db.c.update(
	{"name": "toyota" },
	{"$set": {"size.width":7} }
	)
> db.c.findOne({"name":"toyota"})
{
        "_id" : ObjectId("5003be465af21ff428dafbe7"),
        "name" : "toyota",
        "type" : "suv",
        "size" : {
                "height" : 8,
                "width" : 7,
                "length" : 15
        }
}

可見:對於內嵌文檔在使用$set更新時,使用"."連接的方式。

3.$unset

從字面就可以看出其意義,主要是用來刪除鍵。
示例操作效果如下:

> db.a.update(
	{"uid" : "20120002","type" : "3"},
	{"$unset":{"sname":1}}
	)
> db.a.findOne({"uid" : "20120002","type" : "3"})
{
        "_id" : ObjectId("500216de81b954b6161a7d8f"),
        "desc" : "hello world2!",
        "num" : 40,
        "size" : 10,
        "type" : "3",
        "uid" : "20120002"
}
> db.a.update(
	{"uid" : "20120002","type" : "3"},
	{"$unset":{"num":0}}
	)
> db.a.findOne({"uid" : "20120002","type" : "3"})
{
        "_id" : ObjectId("500216de81b954b6161a7d8f"),
        "desc" : "hello world2!",
        "size" : 10,
        "type" : "3",
        "uid" : "20120002"
}
> db.a.update(
	{"uid" : "20120002","type" : "3"},
	{"$unset":{"size":-1}}
	)
> db.a.findOne({"uid" : "20120002","type" : "3"})
{
        "_id" : ObjectId("500216de81b954b6161a7d8f"),
        "desc" : "hello world2!",
        "type" : "3",
        "uid" : "20120002"
}
> db.a.update(
	{"uid" : "20120002","type" : "3"},
	{"$unset":{"desc":"sssssss"}}
	)
> db.a.findOne({"uid" : "20120002","type" : "3"})
{
        "_id" : ObjectId("500216de81b954b6161a7d8f"),
        "type" : "3",
        "uid" : "20120002"
}

得出結論:使用修改器$unset時,不論對目標鍵使用1、0、-1或者具體的字符串等都是可以刪除該目標鍵。

4.數組修改器–$push

示例操作效果如下:

> db.c.find()
{ 
	"_id" : ObjectId("5003be465af21ff428dafbe7"), 
	"name" : "toyota", 
	"type" : "suv",
	"size" : 
		{ 
		"height" : 8, 
		"width" : 7, 
		"length" : 15 
		} 
}

–先push一個當前文檔中不存在的鍵title

> db.c.update(
	{"name" : "toyota"},
	{$push:{"title":"t1"}}
	)
> db.c.find()
{ 
	"_id" : ObjectId("5003be465af21ff428dafbe7"), 
	"name" : "toyota", 
	"size" : 
		{ 
		"height" : 8,
		"width" : 7, 
		"length" : 15 
		},
	"title" : [ "t1" ], 
	"type" : "suv" 
}

–再向title中push一個值

> db.c.update(
	{"name" : "toyota"},
	{$push  : {"title":"t2"} }
	)
> db.c.find()
{ 
	"_id" : ObjectId("5003be465af21ff428dafbe7"), 
	"name" : "toyota", 
	"size" : 
	{ 
		"height" : 8,
		"width" : 7, 
		"length" : 15 
	}, 
	"title" : [ "t1", "t2" ], 
	"type" : "suv" 
}

–再向title中push一個值

> db.c.update(
	{"name" : "toyota" },
	{$push  : {"title":"t2"} }
	)
> db.c.find()
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), 
  "name" : "toyota", 
  "size" : { 
    "height" : 8,
    "width" : 7, 
    "length" : 15 }, 
  "title" : [ "t1", "t2", "t2" ],
  "type" : "suv" 
}

–再向一個已經存在的鍵值非數組類型的鍵push一個值

> db.c.update(
	{"name" : "toyota"},
	{$push  : {"size.height":10} }
	)
Cannot apply $push/$pushAll modifier to non-array
> db.c.update(
	{"name" : "toyota"},
	{$push  : {"name":"ddddddd"} }
	)
Cannot apply $push/$pushAll modifier to non-array

得出結論:$push–向文檔的某個數組類型的鍵添加一個數組元素,不過濾重複的數據。添加時鍵存在,要求鍵值類型必須是數組;鍵不存在,則創建數組類型的鍵。

5.數組修改器–ne/ne/addToSet

主要給數組類型鍵值添加一個元素時,避免在數組中產生重複數據,$ne在有些情況是不通行的。

> db.c.update(
	{"title": {$ne:"t2"} },  #如果有重複的t2則不執行操作
	{$push  : {"title":"t2"} }
	)
> db.c.find()
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), 
  "name" : "toyota", 
  "size" : { 
  	"height" : 8,
 	"width" : 7, 
 	"length" : 15 
 	}, 
  "title" : [ "t1", "t2", "t2" ], 
  "type" : "suv" 
}
> db.c.update(
	{"name" : "toyota"},
	{$addToSet:{"title":"t2"}}  #如果有重複的t2則不執行操作
	)
> db.c.find()
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), 
  "name" : "toyota", 
  "size" : { 
    "height" : 8,
    "width" : 7, 
    "length" : 15 
    }, 
  "title" : [ "t1", "t2", "t2" ], 
  "type" : "suv" 
 }

相當於$ne是在選擇的時機執行,而addToSet是在添加的時候執行。

6.數組修改器–poppop、pull

$pop從數組的頭或者尾刪除數組中的元素,示例如下:

{ 
	"_id" : ObjectId("5003be465af21ff428dafbe7"), 
	"name" : "toyota", 
	"size" : { 
		"height" : 8,
		"width" : 7, 
		"length" : 15 
		}, 
	"title" : [ "t1", "t2", "t3", "t4" ],
	"type" : "suv" 
}

–從數組的尾部刪除 1

> db.c.update(
	{"name" : "toyota"},
	{ $pop  : {"title":1} }
	)
> db.c.find()
{ 
	"_id" : ObjectId("5003be465af21ff428dafbe7"), 
	"name" : "toyota", 
	"size" : 
		{
		"height" : 8,
		"width" : 7, 
		"length" : 15 
		}, 
	"title" : [ "t1", "t2", "t3" ], 
	"type" : "suv" 
}

–從數組的頭部 -1

> db.c.update(
	{"name" : "toyota"},
	{$pop:{"title":-1}}
	)
> db.c.find()
{ 
	"_id" : ObjectId("5003be465af21ff428dafbe7"),
	"name" : "toyota", 
	"size" : 
		{ 
		"height" : 8,
		"width" : 7,
		"length" : 15 
		}, 
	"title" : [ "t2", "t3" ], 
	"type" : "suv" 
}

–從數組的尾部刪除 0

> db.c.update(
	{"name" : "toyota"},
	{$pop:{"title":0}}
	)
> db.c.find()
{ 
	"_id" : ObjectId("5003be465af21ff428dafbe7"), 
	"name" : "toyota",
	"size" : 
		{ 
		"height" : 8,
		"width" : 7, 
		"length" : 15 
		}, 
	"title" : [ "t2" ], 
	"type" : "suv" 
}

$pull從數組中刪除滿足條件的元素,示例如下:

{ 
	"_id" : ObjectId("5003be465af21ff428dafbe7"), 
	"name" : "toyota", 
	"size" : 
		{ 
		"height" : 8,
		"width" : 7,
		"length" : 15 
		}, 
	"title" : [ "t1", "t2", "t2", "t3" ],
	"type" : "suv" 
}
> db.c.update(
	{"name" : "toyota" },
	{ $pull : {"title":"t2"} }
	)
> db.c.find()
{ 
	"_id" : ObjectId("5003be465af21ff428dafbe7"),
	"name" : "toyota", 
	"size" : 
		{ 
		"height" : 8,
		"width" : 7, 
		"length" : 15 
		}, 
	"title" : [ "t1", "t3" ], 
	"type" : "suv" 
}

7.數組的定位修改器

在需要對數組中的值進行操作的時候,可通過位置或者定位操作符("$").數組是0開始的,可以直接將下標作爲鍵來選擇元素。
示例如下:

{
	"uid":"001",
	comments:
		[
			{"name":"t1","size":10},		
			{"name":"t2","size":12}
		]
}

> db.c.find({"uid":"001"})
{ 
	"_id" : ObjectId("5003da405af21ff428dafbe8"), 
	"uid" : "001", 
	"comments" : 
	[ 
		{"name" : "t1", "size" : 10 }, 
		{"name" : "t2", "size" : 12 } 
	] 
}
> db.c.update(
	{"uid":"001"},
	{$inc:{"comments.0.size":1}}
	)
> db.c.find({"uid":"001"})
{ 
	"_id" : ObjectId("5003da405af21ff428dafbe8"), 
	"uid" : "001", 
	"comments" : 
		[ 
			{"name" : "t1", "size" : 11 }, 
			{"name" : "t2", "size" : 12 } 
		] 
}
> db.c.update(
	{"comments.name":"t1"},
	{$set:{"comments.$.size":1}}
	)
> db.c.find({"uid":"001"})
{ 
	"_id" : ObjectId("5003da405af21ff428dafbe8"), 
	"uid" : "001", 
	"comments" : 
		[ 
			{"name" : "t1", "size" : 1 }, 
			{"name" : "t2", "size" : 12} 
		] 
}

–若爲多個文檔滿足條件,則只更新第一個文檔。

8.upsert

upsert是一種特殊的更新。當沒有符合條件的文檔,就以這個條件和更新文檔爲基礎創建一個新的文檔,如果找到匹配的文檔就正常的更新。
使用upsert,既可以避免競態問題,也可以減少代碼量(update的第三個參數就表示這個upsert,參數爲true時)

> db.c.remove()
> db.c.update({"size":11},{$inc:{"size":3}})
> db.c.find()
> db.c.update({"size":11},{$inc:{"size":3}},false)
> db.c.find()
> db.c.update({"size":11},{$inc:{"size":3}},true)
> db.c.find()
{ "_id" : ObjectId("5003ded6c28f67507a6df1de"), "size" : 14 }

9.save函數

1.可以在文檔不存在的時候插入,存在的時候更新,只有一個參數文檔。
2.要是文檔含有"_id",會調用upsert。否則,會調用插入。

> db.a.find()
{ 
	"_id" : ObjectId("50026affdeb4fa8d154f8572"), 
	"desc" : "hello world1!", 
	"num": 50,
 	"sname" : "jk", 
 	"type" : "1", 
 	"uid" : "20120002" 
 }
> var o = db.a.findOne()
> o.num = 55
55
> db.a.save(o)
> db.a.find()
{ 
	"_id" : ObjectId("50026affdeb4fa8d154f8572"), 
	"desc" : "hello world1!", 
	"num": 55,
	"sname" : "jk", 
	"type" : "1", 
	"uid" : "20120002" 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章