暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MongoDB Document CRUD Operations

148



Hi~朋友,关注置顶防止错过消息


MongoDB数据新增

  • db.collection.insertOne()

  • db.collection.insertMany()

  • db.collection.updateOne()方法并且option中的upsert为true

  • db.collection.updateMany()方法并且option中的upsert为true

  • db.collection.findAndModify()方法并且option中的upsert为true

  • db.collection.findOneAndUpdate()方法并且option中的upsert为true

  • db.collection.findOneAndReplace()方法并且option中的upsert为true

  • db.collection.bulkWrite()

insertOne的语法格式如下:

  1. db.collection.insertOne(

  2. <document>,

  3. {

  4. writeConcern: <document>

  5. }

  6. )

writeConcern表明写操作成功的关注级别。

  1. db.inventory.insertOne(

  2. { item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm"} }

  3. )

  1. db.inventory.insertMany([

  2. { item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm"} },

  3. { item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm"} },

  4. { item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm"} }

  5. ])

Insert行为

  • 集合不存在时,insert会创建集合

  • 集合中的每一行Document都必须包含一个id字段作为主键,如果id不存在,MongoDB Driver会自动生成一个ObjectId,逻辑同样适用于option为upsert:true的插入方法

  • 每一行Document的插入都是一个原子操作

  • 通过write concerns,可以控制数据写入的可靠性。

MongoDB数据查询

  • db.collection.find():查询所有数据

MongoDB数据过滤查询

通过在find方法中传入Query Filter Documents,Query Filter Documents可以完成对特定记录的读取、更新和删除操作,格式如下:

  1. {

  2. <field1>: <value1>,

  3. <field2>: { <operator>: <value>},

  4. ...

  5. }

operator主要有以下几种:

  • 比较操作符

  • 逻辑操作符

  • 文档操作符

  • Evaluation

  • Geospatial

  • Array

  • Bitwise

  • Projection Operators

  • Miscellaneous Operators

上述操作符可以去官网查询具体的用法,有些本人也没有用到过,这里不再过多讲述,细节大家可以去官网查看。

使用相等条件进行查询

  1. # 查询status为D的所有记录

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

使用Query Opearators进行查询

  1. # 查询status值为A或者D的记录

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

虽然上述功能可以用$or实现,但是对于同一个field请使用$in

使用AND进行查询

  1. # 查询status为A并且qty<30的记录

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

上述我们并没有使用$and,MongoDB对于上述写法默认会使用and对其进行连接。

使用OR进行查询

  1. # 查询status为A或者qty<30的记录

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

嵌套文档查询

嵌套文档属性的查询使用.来表示嵌套的field。

  1. #查找size字段的嵌套字段uom值为in的记录

  2. db.inventory.find( { "size.uom": "in"} )

数组查询

  1. # 查找tags字段为["red", "blank"]的所有记录,包括元素的顺序

  2. db.inventory.find( { tags: ["red", "blank"] } )


  3. # 查找tags字段包含了red和blank的所有记录,忽略元素顺序

  4. db.inventory.find( { tags: { $all: ["red", "blank"] } } )


  5. # 查找tags字段包含read的的所有记录

  6. db.inventory.find( { tags: "red"} )


  7. # 查找dic_cm字段至少包含一个大于25的元素的所有记录

  8. db.inventory.find( { dim_cm: { $gt: 25} } )


  9. # 查找dic_cm字段满足即有大于15又有小于20的元素的所有记录

  10. db.inventory.find( { dim_cm: { $gt: 15, $lt: 20} } )


  11. # 查找dic_cm字段满足至少有一个元素既大于22又小于30的所有记录

  12. db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30} } } )


  13. # 查找dic_cm字段中的第2个元素大于25的所有记录

  14. db.inventory.find( { "dim_cm.1": { $gt: 25} } )


  15. # 查找tags包含3个元素的所有记录

  16. db.inventory.find( { "tags": { $size: 3} } )

嵌套数组文档查询

  1. # 查找数组文档中包含{ warehouse: "A", qty: 5 }该元素文档的所有记录,字段顺序也要保持一致

  2. db.inventory.find( { "instock": { warehouse: "A", qty: 5} } )


  3. # 查找instock的数组对象中至少包含一个文档的qty<=20的所有记录

  4. db.inventory.find( { 'instock.qty': { $lte: 20} } )


  5. # 查找instock的数组对象中第一个文档的qty<=20的所有记录

  6. db.inventory.find( { 'instock.0.qty': { $lte: 20} } )


  7. # 查找instock的数组对象中至少有一个文档同时包含qty值为5,warehouse为A的所有记录

  8. db.inventory.find( { "instock": { $elemMatch: { qty: 5, warehouse: "A"} } } )


  9. # 查找instock的数组对象中包含qty>10且qty<=20元素的所有记录

  10. db.inventory.find( { "instock": { $elemMatch: { qty: { $gt: 10, $lte: 20} } } } )


  11. # 查找查找instock的数组对象中有qty>10和qty<=20的元素(可以不在一个文档中)的所有记录

  12. db.inventory.find( { "instock.qty": { $gt: 10, $lte: 20} } )

限制返回的字段

  1. # 返回_id, item, status字段

  2. db.inventory.find( { status: "A"}, { item: 1, status: 1} )


  3. # 返回item, status字段

  4. db.inventory.find( { status: "A"}, { item: 1, status: 1, _id: 0} )


  5. # 返回除了status和instock以外的所有字段

  6. db.inventory.find( { status: "A"}, { status: 0, instock: 0} )


  7. # 返回_id, status, instock数组(只包含qty元素)

  8. db.inventory.find( { status: "A"}, { item: 1, status: 1, "instock.qty": 1} )


  9. # 返回_id, status, instock数组中最后一个元素

  10. db.inventory.find( { status: "A"}, { item: 1, status: 1, instock: { $slice: -1} } )

也可以利用聚合函数返回自定义字段如下:

  1. db.inventory.find(

  2. { },

  3. {

  4. _id: 0,

  5. item: 1,

  6. status: {

  7. $switch: {

  8. branches: [

  9. {

  10. case: { $eq: [ "$status", "A"] },

  11. then: "Available"

  12. },

  13. {

  14. case: { $eq: [ "$status", "D"] },

  15. then: "Discontinued"

  16. },

  17. ],

  18. default: "No status found"

  19. }

  20. },

  21. area: {

  22. $concat: [

  23. { $toString: { $multiply: [ "$size.h", "$size.w"] } },

  24. " ",

  25. "$size.uom"

  26. ]

  27. },

  28. reportNumber: { $literal: 1}

  29. }

  30. )

查询null或者不存在的字段

  1. #查找item字段为null或者item字段不存在的所有记录

  2. db.inventory.find( { item: null} )


  3. #查找item字段存在且不为null的所有记录

  4. db.inventory.find( { item: { $ne : null} } )


  5. #查找item字段类型为Null的所有记录

  6. db.inventory.find( { item : { $type: 10} } )


  7. #查找item字段不存在的所有记录

  8. db.inventory.find( { item : { $exists: false} } )

MongoDB数据更新

MongoDB更新数据主要有以下三种方式:

  • db.collection.updateOne(<filter>,<update>,<options>)

  • db.collection.updateMany(<filter>,<update>,<options>)

  • db.collection.replaceOne(<filter>,<update>,<options>)

为了更新Document,MongoDB提供了一批operators,如下:

数组的operators如下:

  1. # 将item为paper的第一个文档中size.uom字段更新成cm,status字段更新为P,lastModified更新为当前日期

  2. db.inventory.updateOne(

  3. { item: "paper"},

  4. {

  5. $set: { "size.uom": "cm", status: "P"},

  6. $currentDate: { lastModified: true}

  7. }

  8. )


  9. # 将qty<50的所有档中size.uom字段更新成in,status字段更新为P,lastModified更新为当前日期

  10. db.inventory.updateMany(

  11. { "qty": { $lt: 50} },

  12. {

  13. $set: { "size.uom": "in", status: "P"},

  14. $currentDate: { lastModified: true}

  15. }

  16. )



  17. # 将item为paper的第一个文档替换为第2个参数中的文档

  18. db.inventory.replaceOne(

  19. { item: "paper"},

  20. { item: "paper", instock: [ { warehouse: "A", qty: 60}, { warehouse: "B", qty: 40} ] }

  21. )

replace的新文档中可以包含id,但是id必须要和原来的_id相等,新文档中不可以包含update operator表达式。

  • 对于update操作,对于单个文档的写入操作都是原子的

  • _id不可以被更新

  • 对于大部分写入操作,MongDB会保留文档的写入顺序,_id始终保持在一个字段,rename操作会导致字段的重新排序

  • 对于指定upsert:true的如果没有匹配的文档将会插入一个新的文档

通过聚合操作进行数据更新

对于更新操作,聚合操作主要有以下操作符:

  • $addFields

  • $set

  • $project

  • $unset

  • $replaceRoot

  • $replaceWith

  1. # 修改_id为3的记录,将test3字段的值设置为98,modified改为当前时间

  2. db.students.updateOne( { _id: 3}, [ { $set: { "test3": 98, modified: "$$NOW"} } ] )



  3. # 将所有的记录先通过replaceRoot替换整个文档(replaceRoot中又使用了mergeObjects对文档进行合并操作),然后再设置每个文档modified为当前时间

  4. db.students2.updateMany( {},

  5. [

  6. { $replaceRoot: { newRoot:

  7. { $mergeObjects: [ { quiz1: 0, quiz2: 0, test1: 0, test2: 0}, "$$ROOT"] }

  8. } },

  9. { $set: { modified: "$$NOW"} }

  10. ]

  11. )


  12. # 更新使用let来定义变量,可以在filter和update阶段使用$$进行引用

  13. db.cakeFlavors.updateOne(

  14. {

  15. $expr: { $eq: [ "$flavor", "$$targetFlavor"] }

  16. },

  17. [

  18. {

  19. $set: { flavor: "$$newFlavor"}

  20. }

  21. ],

  22. {

  23. let: { targetFlavor: "cherry", newFlavor: "orange"}

  24. }

  25. )

别的更新方法

  • db.collection.findOneAndReplace()

  • db.collection.findOneAndUpdate()

  • db.collection.findAndModify()

  • db.collection.bulkWrite()

MongoDB数据删除

MongoDB使用以下方法进行删除:

  • db.collection.deleteMany():删除所有符合过滤条件的记录

  • db.collection.deleteOne():删除第一条符合过滤条件的记录

其他删除方法

  • db.collection.findOneAndDelete()

  • db.collection.findAndModify()

  • db.collection.bulkWrite()

关于bulkWrite,后续文章单独写。

文章转载自程序员修炼笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论