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

举报
dber 发表于 2021/02/02 17:42:02 2021/02/02
【摘要】  CRUD操作可create, read, update和delete  documents。create创建或插入操作会将新documents添加到collection中。如果该集合当前不存在,则插入操作将创建该集合。MongoDB提供了以下将文档插入集合的方法:db.collection.insertOne() 3.2版中的新功能db.collection.insertMany() 3....

 CRUD操作可createreadupdatedelete  documents

create

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

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

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


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

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

原子性

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

ANDOR条件

在下面的例子中,status等号"A"  任一 qty小于($lt30  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 设置为falsemongos可以尝试同时将写入发送到多个分片。对于空集合,首先按照分片群集中的分割块中的说明预分割集合 

避免单调

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

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

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

 

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。