限制:文档大小必须小于16MB,如果要查看文档的BSON大小(unit:byte),可以在shell中执行Object.bsonsize(doc)
批量插入文档:db.foo.batchInsert({"_id": "0"}, {"_id": "1"}, {"_id": "2"})
限制:当前版本最大支持消息长度48MB
不能在单次请求中将多个文档批量插入到多个集合中,如果只是导入原始数据,可以使用mongoimport,而不是批量插入。
删除文档:db.foo.remove()
删除集合foo中所有文档,删除操作是永久性的,不可撤销,不能恢复
使用drop()直接删除集合速度比remove()更快,但是不支持限定条件。
删除符合条件文档:db.foo.remove({"field": "value"})
更新文档:db.foo.update({"field": "value"}, 修改器文档)
修改操作一个常见的错误是查询器匹配到多个文档,然后更新时由于第二个参数的存在产生重复的“_id”值,数据库抛出错误,任何文档都不会更新。
使用修改器:
$set修改器:1.可以更新字段的值 2.可以新增字段 3.可以修改键的类型 4.可以修改内嵌文档
db.users.update({"name": "zhangsan"},
{"$set": {"hobby": ["play baskball", "play pingpang"]}}
)
$unset修改器: 删除某个字段
db.users.update({"name": "zhangsan"},
{"$unset": {"hobby": 1}}
)
$inc修改器:用来增加已有键的值,或者该键不存在就创建一个
(原子操作)
db.users.update({"name": "zhangsan", "game": "baskball"},
{"$inc": {"score": 1000}}
)
$push修改器:用来向数组末尾加入一个元素,要是没有就创建一个新的含该元素的数组
db.blog.update({"title": "A blog"},
{"$push": {"comments": {"name": "wangwu", "content": "good post."}}}
)
使用
$each子操作符,可以一次“$push”操作多个值,如果$each后指定的数组只包含一个元素,那么这个操作就等于没有使用$each的普通$push操作。
db.users.update({"name": "zhangsan"},
{"$push": {"hobby": {"$each": ["play baskball", "play pingpang"]}}}
)
可以使用
$slice操作符,保证数组的最大长度固定,$slice的值必须是负整数,以下例子保证数组只包含最后加入的10个元素,如果数组元素数量小于10,那么所有元素会被保留,如果大于10,那么只有最后10个元素会被保留,因此$slice也可以用来在文档中创建一个队列
db.movies.find({"genre": "horror"},
{"$push": {"top10": {
"$each": ["Elm Street", "Saw"],
"$slice": -10
}}}
)
可以使用
$sort操作符,对数组中的所有对象进行排序,然后保留前N个。
不能只将$slice或者$sort与$push配合使用,且必须使用$each。
db.movies.find({"genre": "horror"},
{"$push": {"top10": {
"$each": [{"name": Elm Street", "rating": 5.5,
{"name": "Saw", "rating": 2.5}],
"$slice": -10,
"$sort": {"rating": -1}
}}}
)
$addToSet: 将数组作为数据集使用,保证数组内的元素不重复
db.users.update({"_id": ObjectId("")},
{"$addToSet": {"email": "joe@email.com"}}
)
可以使用$each,添加多个不同的值
db.users.update({"_id": ObjectId("")},
{"$addToSet": {"email": {"$each": ["joe@email.com", "joe@email.cn"]}}}
)
$pop修改器:可以从数组的任何一端删除元素,{"$pop": {"key": -1}},从数组的头部删除元素,{"$pop": {"key": 1}}则从数组的尾部删除元素
db.getCollection('test').update(
{"_id" : ObjectId("55c8815d236df6dabfcb06a5")},
{"$pop": {"users": 1}}
)
$pull修改器:可以基于特定条件删除元素,而不需要仅仅是依赖于元素的位置,它会将匹配到的所有元素全部删除
db.getCollection('test').update(
{"_id" : ObjectId("55c8815d236df6dabfcb06a5")},
{"$pull": {"users": "zhangsan"}}
)
基于位置的数组修改器:如果数组有多个值,而我们只是想对其中的一部分进行操作,就需要一些技巧,有两种方法操作数组中的值:通过位置或定位操作符("$")
数组下表都是以0开头的,可以将下标直接作为键来选择元素,例如:
db.getCollection('test').update(
{"_id" : ObjectId("55c8815d236df6dabfcb06a5")},
{"$set": {"users.0": "newzhangsan"}}
)
MongoDB提供定位操作符"$",用来定位查询文档匹配到的数组元素并进行更新,定位符只更新第一个匹配到的元素
db.getCollection('test').update(
{"users" : "newzhangsan"},
{"$set": {"users.$": "zhangsan"}}
)
将文档插入到MongoDB中,依次插入的文档在磁盘上的位置是相邻的,因此,如果一个文档变大了,那么原先的位置就放不下这个文档了,这个文档就会被移动到集合中的另一个位置
upsert是一种特殊的更新,如果没有找到符合更新条件的文档,就会以这个条件和更新文档为基础创建一个新的文档。如果找到了匹配的文档,则正常更新。(原子操作)
db.getCollection('test').update(
{"url": "map.baidu.com"},
{"$inc": {"pageviews": 1}},
true //是否为upsert操作
)
$setOnInsert:
仅在文档插入时设置字段的值,以后的所有更新操作都不会改变这个字段的值
db.getCollection('test').update(
{"url": "map.baidu.com.cn"},
{"$setOnInsert": {"createDate": new Date()}},
true
)
save是一个shell函数,如果文档不存在,它会自动创建文档,如果文档存在,它就更新这个文档,它只有一个参数:文档。如果这个文档含"_id"参数,它会调用upsert,否则,调用insert。
默认情况下,更新只对符合匹配条件的第一个文档执行更新操作,要更新所有匹配到的文档,可以将update的第四个参数设置为true,(服务器以后可能默认会更新所有匹配的文档,只有第四个参数为false时才更新一个,所以建议每次显示表明是否需要做多文档更新)
db.getCollection('test').update(
{"pageviews" : 1},
{"$set": {"description" : "First interview"}},
false,
true //是否需要做多文档更新
)
在更新后,立即运行db.runCommand({getLastError: 1}),可通过观察键"n"的值了解此次被更新的文档总量。调用getLastError仅能获取关于更新的有限信息,并不能返回被更新的文档,可以通过findAndModify命令得到被更新的文档信息,这对于
操作队列,及执行其他需要原子性取值和赋值操作,十分方便。
(原子操作)
ps = db.runCommand(
{
"findAndModify": "process",
"query": {"status": "READY"},
"sort": {"priority": -1},
"update": {"$set": {"status": "RUNNING"}}
}
).value
do_something(ps)
db.process.update(
{"_id": ObjectId("ps._id")},
{"$set": {"status": "DONE"}}
)
findAndModify命令可以有很多可以使用的字段:
findAndModify:字符串,集合名
query: 查询文档,用于检索文档的条件
sort: 排序结果的条件
update: 修改器文档,用于对匹配到的文档进行更新
remove: 布尔类型,表示是否删除文档
new: 布尔类型,表示返回更新前的文档还是更新后的文档,默认是更新前的文档
fields: 文档中需要返回的字段(可选)
upsert: 布尔类型,值为true表示这是一个upsert,默认为false
update和remove必须指定一个,也只能有一个,要是没有匹配的文档,这个命令会返回一个错误。