十二:文档更新删除之非典型篇

一灰灰blogDBMongoMongoDB约 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 Methodopen in new window

如果我们希望直接修改数组中的某个元素,可以借助之前查询的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...