ITPub博客

首页 > 数据库 > NoSQL > [mongo] {第二部分}MongoDB CRUD v1

[mongo] {第二部分}MongoDB CRUD v1

原创 NoSQL 作者:匠人xin 时间:2021-02-02 17:43:00 0 删除 编辑

CRUD 操作可 create ,  read,  update 和 delete     documents 。

create

创建或插入操作会将新 documents 添加到 collection 中 。如果该集合当前不存在,则插入操作将创建该集合。

MongoDB 提供了以下将文档插入集合的方法:

在 MongoDB 中,插入操作的目标是单个 collection 。 MongoDB 中的所有写操作在单个 文档 级别上都是 原子 性的   。


Insert

插入一个文档

db.collection.insertOne() 将 单个   文档 插入集合中。

以下示例将一个新文档插入到   inventory 集合中。如果文档未指定 _id 字段,则 MongoDB 将 _id 具有 ObjectId 值的字段添加到新文档中。

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

insertOne() 返回包含新插入的文档的 _id 字段值的文档。

要检索刚刚插入的文档,请 查询集合 :

db.inventory.find( { item: "canvas" } )


插入多个文档

3.2 版中的新功能。

db.collection.insertMany() 可以将 多个   文档 插入一个集合中。将文档数组传递给该方法。

下面的示例将三个新文档插入到   inventory 集合中。如果文档未指定   _id 字段,则 MongoDB 将 _id 具有 ObjectId 值的字段添加到每个文档。

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" } }])

Insert Behavior

集合创建(Collection Creation)

如果该集合当前不存在,则插入操作将创建该集合。

_id 字段

在 MongoDB 中,存储在集合中的每个文档都需要一个唯一的   _id 字段作为 主键 。如果插入的文档省略了该 _id 字段,则 MongoDB 会自动为该字段生成一个 ObjectId _id 。

这也适用于通过 upsert : true 通过更新操作插入的文档。

原子性

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

写确认(Write Acknowledgement)

对于写问题,您可以指定 MongoDB 向写操作请求的确认级别。

Insert Methods

MongoDB 提供了以下将 文档 插入到集合中的方法:

db.collection.insertOne()

插入单个文档到集合中

db.collection.insertMany()

db.collection.insertMany()   插入多个文档到集合中

db.collection.insert()

db.collection.insert() 插入单个或多个文档到集合中

插入文档的其他方式

  • 以下方法还可以将新文档添加到集合中:

See the individual reference pages for the meth

 

查询

读取操作从   集合中 检索 文档 ;  即查询文档集合。 MongoDB 提供了以下方法来从集合中读取文档:

您可以指定 查询 或筛选 条件 以标识要返回的文档。


列出集合中的所有文档

要选择集合中的所有文档,请将空文档作为查询过滤器参数传递给 find 方法。查询过滤器参数确定选择条件:

db.inventory.find( {} )


此操作对应于以下 SQL 语句:

SELECT * FROM inventory


指定相等条件

要指定相等条件,请 <field>:<value>   在 查询过滤器文档中 使用表达式   :

{ <field1>: <value1>, ... }


以下示例从 inventory 集合中选择 status 等于的所有文档 "D" :

db.inventory.find( { status: "D" } )


此操作对应于以下 SQL 语句:

SELECT * FROM inventory WHERE status = "D"


指定条件下使用查询运算符

文档可以使用 查询运算符 ,以指定在以下形式的条件:

{ <field1>: { <operator1>: <value1> }, ... }


以下示例从 inventory   集合中检索 status 等于 "A" 或的所有文档 "D" :

db.inventory.find( { status: { $in: [ "A", "D" ] } } )


 

注意

尽管可以使用 $or 运算符表示此查询,但是在同一字段上执行相等性检查时,请使用 $in 运算符而不是 $or 运算符。

该操作对应于以下 SQL 语句:

db.inventory.find( { status: { $in: [ "A", "D" ] } } )


AND 条件

复合查询可以为集合文档中的多个字段指定条件。隐式地,逻辑 AND 连接将复合查询的子句连接起来,以便查询选择集合中符合所有条件的文档。

以下示例检索 inventory   集合中 status 等于 "A"   和   qty 小于( $lt )的所有文档 30 :

db.inventory.find( { status: "A", qty: { $lt: 30 } } )


该操作对应于以下 SQL 语句:

SELECT * FROM inventory WHERE status = "A" AND qty < 30


OR条件

使用 $or 运算符,您可以指定一个复合查询,该查询将每个子句与一个逻辑连接符连接在一起, OR 以便该查询选择集合中至少匹配一个条件的文档。

以下示例检索 status 等于 "A"   或   qty 小于( $lt )的集合中的所有文档 30 :

db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )


该操作对应于以下 SQL 语句:

SELECT * FROM inventory WHERE status = "A" OR qty < 30


注意

使用 比较运算符的 查询   需进行 Type Bracketing 。

AND 和 OR 条件

在下面的例子中, status 等号 "A"   和   任一   qty 小于( $lt ) 30   或   item 开始字符为 p :

{
  <update operator>: { <field1>: <value1>, ... },
  <update operator>: { <field2>: <value2>, ... },
  ...}

该操作对应于以下 SQL 语句:

SELECT * FROM inventory WHERE status = "A" AND ( qty < 30 OR item LIKE "p%")

注意

MongoDB 支持正则表达式 $regex 查询以执行字符串模式匹配。

Update

Update 操作修改在 集合 已存在的文档。 MongoDB 提供了以下方法来更新集合的文档:

在 MongoDB 中,更新操作针对单个集合。 MongoDB 中的所有写操作都是单个文档级别的 原子 操作。

您可以指定标识要更新的文档的条件或过滤规则。这些 过滤器 使用与读取操作相同的语法。


 

更新集合中的文档

要更新文档, MongoDB 提供了   诸如的 更新操作符 $set 来修改字段值。

要使用更新运算符,请将以下形式的更新文档传递给更新方法:

{
  <update operator>: { <field1>: <value1>, ... },
  <update operator>: { <field2>: <value2>, ... },
  ...}

$set 如果该字段不存在,则某些更新运算符(例如)将创建该字段。

注意:

从 MongoDB 4.2 开始, MongoDB 可以接受聚合管道来指定要进行的修改而不是更新文档。有关详细信息,请参见方法参考页。

更新单个文档

以下示例使用集合 db.collection.updateOne() 上的   方法   inventory 更新等于的 第一个文档   : item 为 "paper"

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

更新操作:

  • 使用 $set操作员更新的值  size.uom字段 "cm"和值 status 字段 "P",
  • 使用 $currentDate 运算符将 lastModified 字段的值更新为当前日期。如果   lastModified 字段不存在,   $currentDate 将创建该字段。

 

更新多个文档

3.2 版中的新功能。

以下示例使用集合 db.collection.updateMany()   上的方法 inventory 更新 qty 小于的所有文档   50 :

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

更新操作:

  • 使用 $set操作员更新的值  size.uom字段 "in"和值 status 字段 "P",
  • 使用 $currentDate 运算符将 lastModified 字段的值更新为当前日期。如果   lastModified 字段不存在,   $currentDate 将创建该字段。

替换一个文档

要替换除 _id   字段以外的文档的所有内容,请将一个全新的文档作为第二个参数传递给   db.collection.replaceOne() 。

替换文档时,替换文档必须仅由字段 / 值对组成;即不包括 更新运算符 表达式。

替换文档可以具有与原始文档不同的字段。在替换文档中, _id 由于该 _id 字段是不可变的,因此可以省略该字段;但是,如果确实包含该 _id 字段,则该   字段必须与当前值具有相同的值。

下面的示例替换集合中的 第一个文档,   inventory 其中: item:   "paper"

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

 

Delete

删除操作从集合中删除文档。 MongoDB 提供了以下删除集合文档的方法:

在 MongoDB 中,删除操作的目标是单个 collection 。。

您可以指定条件或过滤器,以标识要删除的文档。这些 过滤器 使用与读取操作相同的语法。


删除所有文档

要删除集合中的所有文档,请将空的 筛选器 文档传递   {} 给   db.collection.deleteMany() 方法。

下面的示例从   集合中删除 所有文档 inventory :

db.inventory.deleteMany({})


该方法返回具有操作状态的文档

删除所有符合条件的文档

您可以指定标准或过滤器,以标识要删除的文档。该 过滤器 使用相同的语法,读操作。

要指定相等条件,请 <field>:<value>   在 查询过滤器文档中 使用表达式   :

db.inventory.deleteMany({})


查询过滤器文档 可以使用 查询运算符 ,以指定在以下形式的条件:

复制

复制的

{  < field1 >: {  <运算符1 >: < value1 >  }, ...  }

要删除所有符合删除条件的文档,请将 过滤器 参数传递   给该   deleteMany() 方法。

以下示例从 inventory   该 status 字段等于的集合中删除所有文档 "A" :

db.inventory.deleteMany({ status : "A" })


该方法返回具有操作状态的文档。

仅删除一个符合条件的文档

要最多删除一个与指定过滤器匹配的文档(即使多个文档可能与指定过滤器匹配),请使用 db.collection.deleteOne() 方法。

下面的示例删除 第一文件,其中 status 是   "D" :

db.inventory.deleteOne( { status: "D" } )

索引

即使从集合中删除所有文档,删除操作也不会删除索引。

Delete Methods

MongoDB 提供了以下删除集合文档的方法:

db.collection.deleteOne()

即使多个文档可能与指定过滤器匹配,也最多删除一个与指定过滤器匹配的文档。 3.2 版中的新功能。

db.collection.deleteMany()

删除所有与指定过滤器匹配的文档。 3.2 版中的新功能。

db.collection.remove()

删除单个文档或与指定过滤器匹配的所有文档。

其他方式

以下方法也可以从集合中删除文档:

findOneAndDelete ()  提供了一个排序选项。该选项允许删除按指定顺序排序的第一个文档。

db.collection.findAndModify() 提供排序选项。该选项允许删除按指定顺序排序的第一个文档。

 

 

批量写( Bulk Write )

概述

MongoDB 使客户端能够批量执行写操作。批量写入操作会影响 单个集合。 MongoDB 允许应用程序确定批量写入操作所需的可接受级别。

3.2 版中的新功能。

db.collection.bulkWrite() 方法提供了执行批量插入,更新和删除操作的能力。 MongoDB 还支持通过批量插入 db.collection.insertMany() 。

有序与无序操作

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

通过有序操作, MongoDB 串行执行操作。如果在写操作之一的处理过程中发生错误, MongoDB 将返回而不处理列表中任何剩余的写操作。

使用不排序的操作, MongoDB 可以并行执行操作,但是不能保证此行为。如果在写操作之一的处理过程中发生错误, MongoDB 将继续处理列表中剩余的写操作。

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

默认情况下, bulkWrite() 执行 ordered   操作。要指定 unordered 写操作,请在选项文档中进行设置   , ordered   :   false 。

bulkWrite()方法

bulkWrite()  支持以下写操作:

每个写操作都 bulkWrite() 作为文档传递到数组中。

例如,以下执行多个写操作:

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);}

批量插入分片集合的策略

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

预拆分集合

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

无序写入 mongos

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

避免单调

如果您的分片键在插入过程中单调增加,则所有插入的数据都将到达集合中的最后一块,该块将始终以单个分片结尾。因此,群集的插入容量将永远不会超过该单个分片的插入容量。

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

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


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69993564/viewspace-2755526/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2021-01-19

  • 博文量
    33
  • 访问量
    39510