一,插入文档
主要方法db.collection.insert()
https://docs.mongodb.com/manual/reference/method/db.collection.insert/
db.products.insert( { item: “card”, qty: 15 } )
二,删除文档
主要方法db.collection.remove()
https://docs.mongodb.com/manual/reference/method/db.collection.remove/index.html
1,删除集合所有文档
db.bios.remove( { } )
2,删除集合对应条件所有文档
db.products.remove( { qty: { $gt: 20 } } )
3,删除集合对应条件的第一个文档
db.products.remove( { qty: { $gt: 20 } }, true )
三,更新文档
主要方法db.collection.update()(默认只会更新一个文档)
https://docs.mongodb.com/manual/reference/method/db.collection.update/
1,文档替换
db.people.update( { name: “Andy” },{ name: “Andy”,rating: 1,score: 1})
2,修改器
(1),”$set”
“$set”用来更新一个键的值,如果这个键不存在,则创建它。
这对更新或增加用户定义键来说非常方便。
有一用户资料
> db.users.findOne()
{
"name" : "joe",
"age" : 30,
"sex" : "male",
"location" : "wisconsin"
}
添加
- 把喜欢的书添加进去
> db.users.update({"name":"joe"},{"$set":{"favorite book" : "war and peace"}})
更新
- 喜欢另一本书
> db.users.update({"name":"joe"},{"$set":{"favorite book" : "green eggs"}})
- 喜欢一堆书($set可以修改键的数据类型)
> db.users.update({"name":"joe"},{"$set":{"favorite book" : ["cat's cradle","foundation trilogy"]}})
- 修改内嵌文档
> db.users.update({"name":"joe"},{"$set":{"favorite book" : {"name":"green eggs","author":"jim"}}})
> db.users.update({"favorite book.name":"green eggs"},{"$set":{"favorite book.name" : "green" }})
删除
- 不喜欢读书,可以用“$unset”将键完全删除
https://docs.mongodb.com/manual/reference/operator/update/unset/可以同时删除多个键
,且键的值可以随意,试过空字符串和数字都可以
> db.users.update({"name":"joe"},{"$unset":{"age":"","sex":""}})
(2),”$inc”
“$inc”用来增加已有键的值,或者在键不存在时创建一个键
> db.users.update({"name":"joe"},{"$inc":{"age": 5}})
(3),数组修改器
- “
$push
”会向已有数组末尾加入一个元素,要是没有会创建一个新的数组(不会去重)
> db.users.update({"name":"joe"},{"$push":{"mail":"example@111.com"}})
- “
$addToSet
”基本作用同上(会去重)
> db.users.update({"name":"joe"},{"$addToSet":{"mail":"example@111.com"}})
$addToSet和$each
增加多个数组元素
> db.users.update({"name":"joe"},{"$addToSet":{"mail":{"$each":["joe@123.com","joe@example.com"]}}})
- “
$pop
“可以从数组任何一端删除元素
{$pop : {key : 1}}从数组末尾删除一个元素
{$pop : {key : -1}}从数组头部删除一个元素
- “
$pull
“根据条件删除元素,会将所有
匹配的部分删掉
> db.users.update({"name":"joe"},{"$pull":{"mail":"example@111.com"}})
(4),数组定位修改器
有两种方法操作数组中的值:位置或定位操作符(“$”)
> db.blog.posts.insert({"content":"......","comments":[{"comment": "good post","author":"john","votes":0}]})
- 位置
> db.blog.posts.update({"content":"......"},{"$inc":{"comments.0.votes" : 1}})
- 定位操作符
> db.blog.posts.update({"comments.author":"john"},{"$set":{"comments.$.author" : "jim"}})
(5),修改器速度
用python语言进行测试,装python后,装pymongo
https://pypi.python.org/pypi/pymongo
python -m pip install pymongo
运行python代码,统计时间
import pymongo
client = pymongo.MongoClient()
import time
db = client.performance
db.drop_collection("updates")
collection = db.updates
collection.insert({"x": 1})
# in inc test
start_inc = time.time()
for i in range(10000):
collection.update({}, {"$inc" : {"a" : 1}})
print '$inc:', time.time() - start_inc
# in set test
start_set = time.time()
for i in range(10000):
collection.update({}, {"$set" : {"b" : 1}})
print '$set:', time.time() - start_set
# in push test
start_push = time.time()
for i in range(10000):
collection.update({}, {"$push" : {"c" : 1}})
print '$push:', time.time() - start_push
结论:在MongoDB中 $inc
$set
修改器的操作速度相差不大,但明显快于$push
修改器。
$inc
$set
修改器因为只需要将键的值修改一下,所以非常快
而 $push
数组修改器更改了文档大小,需要新的分配空间,所以会慢
要是“$push”成为瓶颈,可以将内嵌数组独立出来,放到单独一个集合里
3,upsert(更新或新增)
- upsert是一种特殊的更新。要是没有文档符合更新条件,就会以这个条件和更新文档为基础创建一个新文档。如果找到匹配文档,则正常更新。
update方法的第三个参数就是upsert,设为true,起作用
> db.math.remove()
> db.math.update({"count" : 25}, {"$inc" : {"count" : 3}}, true)
- save可以在文档不存在时插入,存在时更新,它只有一个参数:
文档
。
要是这个文档含有“_id”键,save会调用upsert。否则,会调用插入。
> var x = db.math.findOne()
> x.count = 30
30
> db.math.save(x)
要是不用save,最后一行可以像下面这样写,但很罗嗦
> db.math.update({"_id" : x._id}, x)
4,更新多个文档
要使所有匹配到的文档都得到更新,可以设置update的第四个参数为true
> db.math.update({count : 30}, {$inc: {count : 1}}, false, true)
5,返回已更新文档
db.collection.findAndModify()
https://docs.mongodb.com/manual/reference/method/db.collection.findAndModify/
db.collection.findAndModify({
query: <document>,
sort: <document>,
remove: <boolean>,
update: <document>,
new: <boolean>,
fields: <document>,
upsert: <boolean>,
bypassDocumentValidation: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ]
});
- query:查询文档的条件
- sort:按照此参数指定的排序顺序修改第一个文档。
- update:更新内容
- remove:默认false。true删除文档
- new:默认false,返回更新前文档。true返回更新后文档
- upsert:没有可以插入
- arrayFilters: 更新数组元素筛选条件
“update”和“remove”有且只能有一个
findAndModify()每次只能处理一个文档
与update方法比较
- 默认情况下,这两个操作都会修改单个文档。
但是,update()可以使用其特殊选项修改多个文档。 - 如果多个文档符合更新条件,
findAndModify() 可以用sort排序更新要更新的文档。
update() 无法指定在多个文档匹配时要更新哪个文档。 - findAndModify()返回文档的预修改版本。要获取更新的文档,请使用new选项。
update()方法返回一个 WriteResult包含操作状态的对象。要返回更新的文档,请再使用find() 方法。但是,其他更新可能会在更新和文档检索之间修改文档
。
所以findAndModify()具有原子性