DB-TUTORIAL DB-TUTORIAL
数据库综合
数据库中间件
  • 综合
  • Mysql
  • 其他
  • MongoDB
  • Redis
  • Elasticsearch
  • Elastic技术栈
GitHub (opens new window)
数据库综合
数据库中间件
  • 综合
  • Mysql
  • 其他
  • MongoDB
  • Redis
  • Elasticsearch
  • Elastic技术栈
GitHub (opens new window)
  • 数据库综合

  • 数据库中间件

  • 关系型数据库

  • 文档数据库

    • MongoDB

      • MongoDB 应用指南
      • MongoDB 的 CRUD 操作
        • 一、基本 CRUD 操作
          • Create 操作
          • Read 操作
          • Update 操作
          • Delete 操作
        • 二、批量写操作
          • 有序和无序的操作
          • bulkWrite() 方法
          • 批量写操作策略
          • 预拆分 collection
          • 无序写操作
          • 避免单调节流
        • SQL 和 MongoDB 对比
          • 术语和概念
        • 参考资料
      • MongoDB 的聚合操作
      • MongoDB 事务
      • MongoDB 建模
      • MongoDB 建模示例
      • MongoDB 索引
      • MongoDB 复制
      • MongoDB 分片
      • MongoDB 运维
  • KV数据库

  • 列式数据库

  • 搜索引擎数据库

  • 数据库
  • 文档数据库
  • MongoDB
dunwu
2020-09-25
目录

MongoDB 的 CRUD 操作

# MongoDB 的 CRUD 操作

# 一、基本 CRUD 操作

MongoDB 的 CRUD 操作是针对 document 的读写操作。

# Create 操作

MongoDB 提供以下操作向一个 collection 插入 document

  • db.collection.insertOne() (opens new window):插入一条 document
  • db.collection.insertMany() (opens new window):插入多条 document

注:以上操作都是原子操作。

img

插入操作的特性:

  • MongoDB 中的所有写操作都是单个文档级别的原子操作。
  • 如果要插入的 collection 当前不存在,则插入操作会自动创建 collection。
  • 在 MongoDB 中,存储在集合中的每个文档都需要一个唯一的 _id (opens new window) 字段作为主键。如果插入的文档省略 _id 字段,则 MongoDB 驱动程序会自动为 _id 字段生成 ObjectId。
  • 可以 MongoDB 写入操作的确认级别来控制写入行为。

【示例】插入一条 document 示例

db.inventory.insertOne({
  item: 'canvas',
  qty: 100,
  tags: ['cotton'],
  size: { h: 28, w: 35.5, uom: 'cm' }
})

【示例】插入多条 document 示例

db.inventory.insertMany([
  {
    item: 'journal',
    qty: 25,
    tags: ['blank', 'red'],
    size: { h: 14, w: 21, uom: 'cm' }
  },
  {
    item: 'mat',
    qty: 85,
    tags: ['gray'],
    size: { h: 27.9, w: 35.5, uom: 'cm' }
  },
  {
    item: 'mousepad',
    qty: 25,
    tags: ['gel', 'blue'],
    size: { h: 19, w: 22.85, uom: 'cm' }
  }
])

# Read 操作

MongoDB 提供 db.collection.find() (opens new window) 方法来检索 document。

img

# Update 操作

MongoDB 提供以下操作来更新 collection 中的 document

  • db.collection.updateOne() (opens new window):更新一条 document
  • db.collection.updateMany() (opens new window):更新多条 document
  • db.collection.replaceOne() (opens new window):替换一条 document

语法格式:

  • db.collection.updateOne(<filter>, <update>, <options>) (opens new window)
  • db.collection.updateMany(<filter>, <update>, <options>) (opens new window)
  • db.collection.replaceOne(<filter>, <update>, <options>) (opens new window)

img

【示例】插入测试数据

db.inventory.insertMany([
  {
    item: 'canvas',
    qty: 100,
    size: { h: 28, w: 35.5, uom: 'cm' },
    status: 'A'
  },
  { item: 'journal', qty: 25, size: { h: 14, w: 21, uom: 'cm' }, status: 'A' },
  { item: 'mat', qty: 85, size: { h: 27.9, w: 35.5, uom: 'cm' }, status: 'A' },
  {
    item: 'mousepad',
    qty: 25,
    size: { h: 19, w: 22.85, uom: 'cm' },
    status: 'P'
  },
  {
    item: 'notebook',
    qty: 50,
    size: { h: 8.5, w: 11, uom: 'in' },
    status: 'P'
  },
  { item: 'paper', qty: 100, size: { h: 8.5, w: 11, uom: 'in' }, status: 'D' },
  {
    item: 'planner',
    qty: 75,
    size: { h: 22.85, w: 30, uom: 'cm' },
    status: 'D'
  },
  {
    item: 'postcard',
    qty: 45,
    size: { h: 10, w: 15.25, uom: 'cm' },
    status: 'A'
  },
  {
    item: 'sketchbook',
    qty: 80,
    size: { h: 14, w: 21, uom: 'cm' },
    status: 'A'
  },
  {
    item: 'sketch pad',
    qty: 95,
    size: { h: 22.85, w: 30.5, uom: 'cm' },
    status: 'A'
  }
])

【示例】更新一条 document

db.inventory.updateOne(
  { item: 'paper' },
  {
    $set: { 'size.uom': 'cm', status: 'P' },
    $currentDate: { lastModified: true }
  }
)

【示例】更新多条 document

db.inventory.updateMany(
  { qty: { $lt: 50 } },
  {
    $set: { 'size.uom': 'in', status: 'P' },
    $currentDate: { lastModified: true }
  }
)

【示例】替换一条 document

db.inventory.replaceOne(
  { item: 'paper' },
  {
    item: 'paper',
    instock: [
      { warehouse: 'A', qty: 60 },
      { warehouse: 'B', qty: 40 }
    ]
  }
)

更新操作的特性:

  • MongoDB 中的所有写操作都是单个文档级别的原子操作。
  • 一旦设置了,就无法更新或替换 _id (opens new window) 字段。
  • 除以下情况外,MongoDB 会在执行写操作后保留文档字段的顺序:
    • _id 字段始终是文档中的第一个字段。
    • 包括重命名字段名称的更新可能导致文档中字段的重新排序。
  • 如果更新操作中包含 upsert : true 并且没有 document 匹配过滤器,MongoDB 会新插入一个 document;如果有匹配的 document,MongoDB 会修改或替换这些 document。

# Delete 操作

MongoDB 提供以下操作来删除 collection 中的 document

  • db.collection.deleteOne() (opens new window):删除一条 document
  • db.collection.deleteMany() (opens new window):删除多条 document

img

删除操作的特性:

  • MongoDB 中的所有写操作都是单个文档级别的原子操作。

# 二、批量写操作

MongoDB 通过 db.collection.bulkWrite() (opens new window) 方法来支持批量写操作(包括批量插入、更新、删除)。

此外,db.collection.insertMany() (opens new window) 方法支持批量插入操作。

# 有序和无序的操作

批量写操作可以有序或无序。

  • 对于有序列表,MongoDB 串行执行操作。如果在写操作的处理过程中发生错误,MongoDB 将不处理列表中剩余的写操作。
  • 对于无序列表,MongoDB 可以并行执行操作,但是不能保证此行为。如果在写操作的处理过程中发生错误,MongoDB 将继续处理列表中剩余的写操作。

在分片集合上执行操作的有序列表通常比执行无序列表要慢,因为对于有序列表,每个操作必须等待上一个操作完成。

默认情况下,bulkWrite() (opens new window) 执行有序操作。要指定无序写操作,请在选项文档中设置 ordered : false。

# bulkWrite() 方法

bulkWrite() (opens new window) 支持以下写操作:

  • insertOne (opens new window)
  • updateOne (opens new window)
  • updateMany (opens new window)
  • replaceOne (opens new window)
  • deleteOne (opens new window)
  • deleteMany (opens new window)

【示例】批量写操作示例

try {
  db.characters.bulkWrite([
    {
      insertOne: {
        document: {
          _id: 4,
          char: 'Dithras',
          class: 'barbarian',
          lvl: 4
        }
      }
    },
    {
      insertOne: {
        document: {
          _id: 5,
          char: 'Taeln',
          class: 'fighter',
          lvl: 3
        }
      }
    },
    {
      updateOne: {
        filter: { char: 'Eldon' },
        update: { $set: { status: 'Critical Injury' } }
      }
    },
    { deleteOne: { filter: { char: 'Brisbane' } } },
    {
      replaceOne: {
        filter: { char: 'Meldane' },
        replacement: { char: 'Tanys', class: 'oracle', lvl: 4 }
      }
    }
  ])
} catch (e) {
  print(e)
}

# 批量写操作策略

大量的插入操作(包括初始数据插入或常规数据导入)可能会影响分片集群的性能。对于批量插入,请考虑以下策略:

# 预拆分 collection

如果分片集合为空,则该集合只有一个初始 chunk (opens new window),该 chunk (opens new window) 位于单个分片上。然后,MongoDB 必须花一些时间来接收数据,创建拆分并将拆分的块分发到可用的分片。为了避免这种性能成本,您可以按照拆分群集中的拆分块中的说明预拆分 collection。

# 无序写操作

要提高对分片集群的写入性能,请使用 bulkWrite() (opens new window),并将可选参数顺序设置为 false。mongos (opens new window) 可以尝试同时将写入操作发送到多个分片。对于空集合,首先按照分片群集中的分割 chunk (opens new window) 中的说明预拆分 collection。

# 避免单调节流

如果在一次插入操作中,分片 key 单调递增,那么所有的插入数据都会存入 collection 的最后一个 chunk,也就是存入一个分片中。因此,集群的插入容量将永远不会超过该单个分片的插入容量。

如果插入量大于单个分片可以处理的插入量,并且无法避免单调递增的分片键,那么请考虑对应用程序进行以下修改:

  • 反转分片密钥的二进制位。这样可以保留信息,并避免将插入顺序与值序列的增加关联起来。
  • 交换第一个和最后一个 16 位字以“随机”插入。

# SQL 和 MongoDB 对比

# 术语和概念

SQL 术语和概念 MongoDB 术语和概念
database database (opens new window)
table collection (opens new window)
row document (opens new window) 或 BSON (opens new window)
column field (opens new window)
index index (opens new window)
table joins $lookup (opens new window)、嵌入式文档
primary key primary key (opens new window)
MongoDB 中自动设置主键为 _id (opens new window) 字段
aggregation (e.g. group by) aggregation pipeline
参考 SQL to Aggregation Mapping Chart (opens new window).
SELECT INTO NEW_TABLE $out (opens new window)
参考 SQL to Aggregation Mapping Chart (opens new window)
MERGE INTO TABLE $merge (opens new window) (MongoDB 4.2 开始支持)
参考 SQL to Aggregation Mapping Chart (opens new window).
UNION ALL $unionWith (opens new window) (MongoDB 4.4 开始支持)
transactions transactions (opens new window)

# 参考资料

  • 官方
    • MongoDB 官网 (opens new window)
    • MongoDB Github (opens new window)
    • MongoDB 官方免费教程 (opens new window)
  • 教程
    • MongoDB 教程 (opens new window)
    • MongoDB 高手课 (opens new window)
📝 帮助改善此页面! (opens new window)
#数据库#文档数据库#MongoDB
上次更新: 2024/10/09, 07:16:02
MongoDB 应用指南
MongoDB 的聚合操作

← MongoDB 应用指南 MongoDB 的聚合操作→

最近更新
01
HBase Java API 管理功能
04-13
02
HBase Java API 其他高级特性
03-31
03
HBase 数据模型
03-16
更多文章>
Theme by Vdoing | Copyright © 2019-2024 钝悟(dunwu) | CC-BY-SA-4.0
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×