十二:文档更新删除之非典型篇
约 1097 字大约 4 分钟
前面介绍document的新增、删除、更新都处于相对常见和基础的说明,但是考虑到mongodb非结构化的特点,它的一些特性是我们的mysql不会遇到的,本文将针对这些特殊场景给出示例说明
- 在现有文档中,增加一个field
- 删除文档中的某个field
- 重命名文档的field
- 在文档的数组orObject中,添加/删除/更新数据
1. 增加field
我们知道修改文档的命令格式如下
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
当我们更新一个文档中,不存在的field,会怎样
# 插入一条数据,然后设置一个不存在的field
db.doc_demo.insert({ "author" : "一灰灰blog", "title" : "测试"})
db.doc_demo.update({'author': '一灰灰blog'}, {$set: {'skill': ['java', 'db']}})
2. 重命名field
同样是借助update方法,但是我们用到的关键字为 $rename
db.doc_demo.update({'author': '一灰灰blog'}, {$rename: {'skill': 'like'}})
请注意,当文档中不存在这个field,则不会有任何影响
3. 删除field
既然$set
可以新增一个不存在的field,那么是不是就可以用$unset
来删除一个已存在的field呢
db.doc_demo.update({'author': '一灰灰blog'}, {$unset: {'title': 1}})
4. 数组元素修改
数组元素的修改删除增加,可以参考官方教程: MongoDB update-array Method
如果我们希望直接修改数组中的某个元素,可以借助之前查询的case
# 修改数组中第0个元素
db.doc_demo.update({'author': '一灰灰blog'}, {$set: {'like.0': 'spring'}})
# 如果查询条件中,包含了数组内容的过滤,则可以用`$`来代替具体的数组下标,如
db.doc_demo.update({'author': '一灰灰blog', 'like': {$eq: 'db'}}, {$set: {'like.$': 'mysql'}})
请注意,使用$
占位符的前途是,前面的查询条件可以限定数组元素
5. 数组元素新增
元素添加支持两种方式,一是addToSet
,一是push
$addToSet
- 确保没有重复的项添加到数组集合,对于已经存在的重复元素不受影响;
- 不能保证添加时元素的顺序
- 如果值是数组,则作为一个元素添加进去
- 可以通过
$each
实现添加多个元素到数组中
# 不存在时,则添加,存在则忽略
db.doc_demo.update({'author': '一灰灰blog'}, {$addToSet: {'like': 'redis'}})
# 借助 $each 实现批量添加
db.doc_demo.update({'author': '一灰灰blog'}, {$addToSet: {'like': {$each: ['mongodb', 'es']}}})
$push
- 如果被更新的文档该数组不存在,那么$push将添加数组字段和值
- 如果字段不是数组,失败
- 如果值是数组,那么整个数组作为一个单个元素添加到数组
# 不存在时,创建一个数组
db.doc_demo.update({'author': '一灰灰blog'}, {$push: {'skill': 'a'}})
# 存在时,添加到数组
db.doc_demo.update({'author': '一灰灰blog'}, {$push: {'skill': 'a'}})
# 批量添加
db.doc_demo.update({'author': '一灰灰blog'}, {$push: {'skill': {$each: ['b', 'c']}}})
6. 数组元素删除
$pop
删除第一个or最后一个
# 删除最后一个
db.doc_demo.update({'author': '一灰灰blog'}, {$pop: {'skill': 1}})
# 删除第一个
db.doc_demo.update({'author': '一灰灰blog'}, {$pop: {'skill': -1}})
$pull
删除满足条件的数组元素
# 将数组中添加几个元素
db.doc_demo.update({'author': '一灰灰blog'}, {$push: {'skill': {$each: ['a', 'b', 'c']}}})
# 删除指定的元素
db.doc_demo.update({'author': '一灰灰blog'}, {$pull: {'skill': 'b'}})
# 删除多个指定的元素
db.doc_demo.update({'author': '一灰灰blog'}, {$pull: {'skill': {$in: ['a', 'c']}}})
注意,$pull
后面跟上的可以理解为限定条件,查询教程篇的一些操作也是支持的(如比较查询等)
7. 内嵌文档操作
对于内嵌文档的操作,实际上普通的field的操作姿势没有什么区别,只是对于key加了一个xx.xx
的限定而已
# 删除测试数据
db.doc_demo.remove({})
# 初始话一条演示文档
db.doc_demo.insert({'author': '一灰灰blog',})
# 不存在内嵌文档,则新增
db.doc_demo.update({}, {$set: {'t': {'a': 1, 'b': 2}}})
# 修改子field
db.doc_demo.update({}, {$set: {'t.a': 10}})
# 新增子field
db.doc_demo.update({}, {$set: {'t.c': 'c'}})
# 删除子field
db.doc_demo.update({}, {$unset: {'t.c': 1}})
# 重命名
db.doc_demo.update({}, {$rename: {'t.b': 't.dd'}})
Loading...