Mongo文档增删改查超大全

前言

这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题

于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。

微信小程序搜索:Python面试宝典

或可关注原创个人博客:https://lienze.tech

也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习

文档CURD

文档的数据结构和JSON基本一样,存储在集合中的数据都是**BSON(Binary JSON)**格式,为二进制JSON


插入文档

db.connection_name.insert(document)db.connection_name.save(document)

> db.test_coll.save({"test":1})

WriteResult({
	"nMatched" : 0,
	"nUpserted" : 1,
	"nModified" : 0,
	"_id" : "61303f6c27b08b32c2c72c05"
})

save方法在出现重复_id主键时会更新,不重复则创建

该方法新版本中已废弃,可以使用db.collection.insertOne()db.collection.replaceOne()来代替


db.collection.insertOne(document)db.collection.insertMany(document)

> db.test_coll.insertOne({"1":1})

{
	"acknowledged" : true,
	"insertedId" : ObjectId("6130470b4febbde5afbf754c")
}
> db.test_coll.insertMany([{"1":1},{2:2}],{ordered:false})

{
	"acknowledged" : true,
	"insertedIds" : [
		ObjectId("6130472e4febbde5afbf754f"),
		ObjectId("6130472e4febbde5afbf7550")
	]
}

ordered控制按照顺序写入,默认为true

查找文档

查找文档使用: db.collection.find

比如查找所有名字为王欣欣的数据

db.test_coll.find({name:"abc"})
过滤操作符
  • 比较
-描述
$eq匹配等于指定值的值。
$gt匹配大于指定值的值。
$gte匹配大于或等于指定值的值。
$in匹配数组中指定的任何值。
$lt匹配小于指定值的值。
$lte匹配小于或等于指定值的值。
$ne匹配所有不等于指定值的值。
$nin不匹配数组中指定的任何值。
  • 逻辑
-描述
$and使用逻辑连接查询子句AND返回与两个子句的条件匹配的所有文档。
$not反转查询表达式的效果并返回与查询表达式匹配的文档。
$nor将查询子句与逻辑连接NOR返回所有未能匹配两个子句的文档。
$or使用逻辑连接查询子句OR返回与任一子句的条件匹配的所有文档
  • 检查
-描述
$exists匹配具有指定字段的文档。
$type如果字段为指定类型,则选择文档。
  • 表达式
-描述
$expr允许在查询语言中使用聚合表达式。
$jsonSchema根据给定的 JSON 模式验证文档。
$mod对字段的值执行模运算并选择具有指定结果的文档。
$regex选择值与指定正则表达式匹配的文档。
$text执行文本搜索。
$where匹配满足 JavaScript 表达式的文档。
  • 数组
-描述
$all匹配包含查询中指定的所有元素的数组。
$elemMatch如果数组字段中的元素匹配所有指定$elemMatch条件,则选择文档。
$size如果数组字段是指定大小,则选择文档。
查找示范

插入一些测试数据

db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
   { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
   { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
   { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
   { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }
]);
  • 查询数组结果
db.inventory.find( { tags: ["red", "blank"] } )
  • 查询数组结果,不论顺序,只要包含这俩就可以
db.inventory.find( { tags: { $all: ["red", "blank"] } } )
  • 查询包含某个tags
db.inventory.find( { tags: "red" } )
  • 查询数组dim_cm中至少包含一个值大于25的所有文档
db.inventory.find( { dim_cm: { $gt: 25 } } )
  • 一个元素可以满足大于15 条件,另一个元素可以满足小于20 条件,或者单个元素可以同时满足两者
db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )
  • 如果希望数组对象满足全部的条件,可以使用elemMatch
db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } )

使用点表示法,您可以为文档中特定索引或数组位置的字段指定查询条件。该数组使用从零开始的索引

使用点表示法查询时,字段和索引必须在引号内。

db.inventory.find( { 'dim_cm.0': { $lte: 20 } } )
  • 返回指定字段

可以在查询条件的第二个大括号处,通过{field: 0/1}来标记是否返回当前字段

比如_id在结果中

db.inventory.find( {}, { _id:0 } )
  • 返回instock数组中的最后一个结果

$slice传两个参数代表切片

db.inventory.find( { }, { instock: { $slice: -1 } } )

注意: mongo对于数组的匹配是默认符合其一即可

  • 空值查询

查询匹配包含item其值为null 不包含该item字段的字段的文档

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

如果希望查询到的结果含有item字段,只是值为null,使用$type手动指明类型

db.inventory.find( { item : { $type: 10 } } )
  • 存在检查

通过$exists可以检查是否存在该字段的数据们,比如查找不存在item的数据行

db.inventory.find( { item : { $exists: false } } )
  • 正则查询

通过$regex可以完成对文本内容的正则匹配

db.inventory.find( { item : { $regex: /^p/ } } )
Sort

对数据结果进行排序

db.collection_name.find().sort({KEY:1})
价值描述
1升序。
-1降序排列。
Skip

跳过指定数量的数据

db.collection_name.find().skip(5)
Limit

读取指定数量的数据记录

db.collection_name.find().limit(10)
Count

查询全表的记录条数

db.collection_name.find().count()

如果在结合一些skiplimit时,只想获取到拿到的数据条数,可以结合count参数true/1

db.collection_name.find().skip(10).limit(5).count(1);
例子

总是先sortskip,最后limit

db.test.insertMany([
    {_id:3, "name":"abc姑娘","age":16},
    {_id:5, "name":"abc壮年","age":33},
    {_id:2, "name":"abc青年","age":25},
    {_id:1, "name":"abc老年","age":80},
    {_id:6, "name":"abc婴儿","age":1},
    {_id:10, "name":"abc青年+","age":27},
    {_id:12, "name":"abc壮年+","age":35},
    {_id:7, "name":"abc更年","age":45},
    {_id:4, "name":"abc更年+","age":50},
])
db.test.find({"_id": {"$gt": 0, "$lt": 13}}).skip(6).sort({"_id":-1})

更新文档

db.update(<filter>, <update>, <options>)

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ],
     hint:  <document|string>, // Added in MongoDB 4.2
     let: <document> // Added in MongoDB 5.0
   }
)
  • query : update的查询条件,类似sql update查询内where后面的。
  • update : update的对象和一些更新的操作符(如 , , ,inc…)等,也可以理解为sql update查询内set后面的
  • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入
  • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新
  • collation: 可选的,指定操作要使用的排序规则,常用于字符串结果排序

3.2版中的新功能

db.collection.updateOne(): 即使多个文档可能与指定的过滤器匹配,也最多更新与指定过滤器匹配的单个文档

db.collection.updateMany(): 更新与指定过滤器匹配的所有文档,查找与过滤器匹配的第一个文档并应用指定的更新修改

db.collection.replaceOne(): 即使多个文档可能与指定的过滤器匹配,也最多替换与指定过滤器匹配的单个文档

db.collection.updateOne(
   <filter>,
   <update>,
   {
     upsert: <boolean>,
     writeConcern: <document>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ],
     hint:  <document|string>        // Available starting in MongoDB 4.2.1
   }
)

以下方法也可以更新集合中的文档

db.collection.findOneAndReplace()

db.collection.findOneAndUpdate()

db.collection.findAndModify()

db.collection.bulkWrite()


字段更新操作符
-描述
$currentDate将字段的值设置为当前日期,作为日期或时间戳,字段不存在则创建
$inc将字段的值增加指定的数量
$min仅当指定值小于现有字段值时才更新该字段
$max仅当指定值大于现有字段值时才更新该字段
$mul将字段的值乘以指定的数量
$rename重命名字段
$set设置文档中字段的值
$setOnInsert如果更新导致插入文档,则设置字段的值。对修改现有文档的更新操作没有影响
$unset从文档中删除指定的字段
数组更新操作符
-描述
$充当占位符以更新与查询条件匹配的第一个元素。
$[\]充当占位符,为匹配查询条件的文档更新数组中的所有元素。
$[\]充当占位符,arrayFilters为符合查询条件的文档更新符合条件的所有元素。
$addToSet仅当集合中尚不存在元素时,才将元素添加到数组中。
$pop删除数组的第一项或最后一项。
$pull删除与指定查询匹配的所有数组元素。
$push将项目添加到数组。
$pullAll从数组中删除所有匹配的值。
-描述
$each修改$push$addToSet运算符以附加多个项目以进行数组更新。将一个数组内数据作为单独元素依次加入
$position修改$push运算符以指定要在数组中添加元素的位置。
$slice修改$push运算符以限制更新数组的大小。
$sort修改$push运算符以重新排序存储在数组中的文档。
示范
db.test.insertMany([
    {_id:3, "name":"abc姑娘","age":16},
    {_id:5, "name":"abc壮年","age":33},
    {_id:2, "name":"abc青年","age":25},
    {_id:1, "name":"abc老年","age":80},
    {_id:6, "name":"abc婴儿","age":1},
    {_id:10, "name":"abc青年+","age":27},
    {_id:12, "name":"abc壮年+","age":35},
    {_id:7, "name":"abc更年","age":45},
    {_id:4, "name":"abc更年+","age":50},
])
  • 为所有王欣欣青年开头的数据的年纪+1
db.test.updateMany({name:{$regex: /^abc青年/}},{$inc:{age:1}})
  • 为第一个王欣欣的num数组中,添加一个新的值,这只会影响目前具有num字段的数据

$addToSet只有当这个值在数组中不存在时才增加

db.test.update({name:"abc姑娘"},{$addToSet: {num: {1:1}}})
  • 更新num数组包含数字为2的,将这个2更新为-1

由于并不确定具体更新的数组位置,那么可以用$来暂时站位代替

db.test.updateMany({num:2},{$set:{"num.$":-1}})

更新参考

  • 插入一些数据
db.test_coll.insertMany([
    {name:'abc'},
    {name:'王AB'},
    {name:'abc '},
])
  • 更新所有王姓李姓
db.update

删除文档

db.collection.deleteMany(
   <filter>,
   {
      writeConcern: <document>,
      collation: <document>
   }
)
db.collection.deleteOne(
   <filter>,
   {
      writeConcern: <document>,
      collation: <document>,
      hint: <document|string>        // Available starting in MongoDB 4.4
   }
)

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

批量操作

MongoDB 为客户端提供了批量执行写入操作的能力

批量写入操作影响单个集合,MongoDB 允许应用程序确定批量写入操作所需的可接受确认级别

db.collection.bulkWrite(
   [ <operation 1>, <operation 2>, ... ],
   {
      writeConcern : <document>,
      ordered : <boolean>
   }
)

operations[array]: bulkWrite操作的数组。支持操作: insertOneupdateOneupdateManydeleteOnedeleteManyreplaceOne

writeConcern[document]: 可选,写入确认有关参数

ordered[boolean]: 可选,表示mongod实例有序还是无序执行操作。默认值true

  • 使用有序的操作列表,MongoDB 以串行方式执行操作

    • 如果在处理其中一个写入操作的过程中发生错误,MongoDB 将返回而不处理列表中的任何剩余写入操作
  • 使用无序列表的操作,MongoDB 可以并行执行操作

    • 但不能保证这种行为。如果在处理其中一个写操作的过程中发生错误,MongoDB 将继续处理列表中剩余的写操作

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李恩泽的技术博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值