mongodb 查询条件,查询逻辑对照表,逻辑运算符,正则表达式匹配查询,排序,分页/巧分页,更新操作符,更新单个/多个文档,删除文档,批量插入,$type操作符,内嵌文档和数组查找修改
1.条件查询
SQL MQL
a = 1 {a: 1}
a <> 1 {a: {$ne: 1}}
a > 1 {a: {$gt: 1}}
a >= 1 {a: {$gte: 1}}
a < 1 {a: {$lt: 1}}
a <= 1 {a: {$lte: 1}}
2.查询逻辑对照表
SQL MQL
a = 1 AND b = 1 {a: 1, b: 1}或{$and: [{a: 1}, {b: 1}]}
a = 1 OR b = 1 {$or: [{a: 1}, {b: 1}]}
a IS NULL {a: {$exists: false}}
a IN (1, 2, 3) {a: {$in: [1, 2, 3]}}
3.查询逻辑运算符:
$lt: 存在并小于
$lte: 存在并小于等于
$gt: 存在并大于
$gte: 存在并大于等于
$ne: 不存在或存在但不等于
$in: 存在并在指定数组中
$nin: 不存在或不在指定数组中
$or: 匹配两个或多个条件中的一个
$and: 匹配全部条件
4.例子:
1 #查询带有nosql标签的book文档:
2 db.books.find({tag:"nosql"})
3 #按照id查询单个book文档:
4 db.books.find({_id:ObjectId("61caa09ee0782536660494d9")})
5 #查询分类为“travel”、收藏数超过60个的book文档:
6 db.books.find({type:"travel",favCount:{$gt:60}})
5.正则表达式匹配查询
MongoDB 使用 $regex 操作符来设置匹配字符串的正则表达式。
1 //使用正则表达式查找type包含 so 字符串的book
2 db.books.find({type:{$regex:"so"}})
3 //或者
4 db.books.find({type:/so/})
6.排序
在 MongoDB 中使用 sort() 方法对数据进行排序
1 #指定按收藏数(favCount)降序返回
2 db.books.find({type:"travel"}).sort({favCount:-1})
1 为升序排列,而 -1 是用于降序排列
7.分页
skip用于指定跳过记录数,limit则用于限定返回结果数量。可以在执行find命令的同时指定skip、limit参数,以此实现分页的功能。
比如,假定每页大小为8条,查询第3页的book文档:
db.books.find().skip(16).limit(8)
.skip(16) 表示跳过前面 16 条记录,即前两页的所有记录。
.limit(8) 表示返回 8 条记录,即第三页的所有记录。
8.处理分页问题 – 巧分页
数据量大的时候,应该避免使用skip/limit形式的分页。
替代方案:使用查询条件+唯一排序条件;
例如:
第一页:db.books.find({}).sort({_id: 1}).limit(10);
第二页:db.books.find({_id: {$gt: <第一页最后一个_id>}}).sort({_id: 1}).limit(10);
第三页:db.books.find({_id: {$gt: <第二页最后一个_id>}}).sort({_id: 1}).limit(10);
9.处理分页问题 – 避免使用 count
尽可能不要计算总页数,特别是数据量大和查询条件不能完整命中索引时。
考虑以下场景:假设集合总共有 1000w 条数据,在没有索引的情况下考虑以下查询:
1 db.coll.find({x: 100}).limit(50);
2 db.coll.count({x: 100});
前者只需要遍历前 n 条,直到找到 50 条 x=100 的文档即可结束;
后者需要遍历完 1000w 条找到所有符合要求的文档才能得到结果。 为了计算总页数而进行的 count() 往往是拖慢页面整体加载速度的原因
10.MongoDB提供了以下方法来更新集合中的文档:
更新操作符
updateOne语法如下:
db.collection.updateOne ():即使多个文档可能与指定的筛选器匹配,也只会更新第一个匹配的文档。
db.collection.updateMany ():更新与指定筛选器匹配的所有文档。
11.操作符 格式 描述
$set {$set:{field:value}} 指定一个键并更新值,若键不存在则创建
$unset {$unset : {field : 1 }} 删除一个键
$inc {$inc : {field : value } } 对数值类型进行增减
$rename {$rename : {old_field_name :new_field_name } } 修改字段名称
$push { $push : {field : value } } 将数值追加到数组中,若数组不存在则会进行初始化
$pushAll {$pushAll : {field : value_array}} 追加多个值到一个数组字段内
$pull {$pull : {field : _value } } 从数组中删除指定的元素
$addToSet {$addToSet : {field : value } } 添加元素到数组中,具有排重功能
$pop {$pop : {field : 1 }} 删除数组的第一个或最后一个元素
12.更新单个/多个文档
db.books.updateOne({_id:ObjectId("642e62ec933c0dca8f8e9f60")},{$inc:{favCount:1}})
updateMany更新与集合的指定筛选器匹配的所有文档:
db.books.updateMany({type:"novel"},{$set:{publishedDate:new Date()}})
findAndModify
findAndModify兼容了查询和修改指定文档的功能,findAndModify只能更新单个文档
db.books.findAndModify({
query:{_id:ObjectId("642ec31813bdda928a1ea2a8")},
update:{$inc:{favCount:1}},
new: true //true返回修改后的数据,false返回修改前的旧数据
})
13.删除文档
db.books.deleteOne ({ type:"novel" }) //删除 type等于novel 的一个文档
db.books.deleteMany ({}) //删除集合下全部文档
db.books.deleteMany ({ type:"novel" }) //删除 type等于 novel 的全部文档
注意:remove、deleteMany命令需要对查询范围内的文档逐个删除,如果希望删除整个集合,则使用drop命令会更加高效
14.批量插入:
db.pizzas.insertMany( [ { _id: 0, type: "pepperoni", size: "small", price: 4 },
{ _id: 1, type: "cheese", size: "medium", price: 7 },
{ _id: 2, type: "vegan", size: "large", price: 8 } 5 ] )
15.$type操作符
$type操作符基于BSON类型来检索集合中匹配的数据类型,并返回结果。
db.books.find({"title" : {$type : 2}})
//或者
db.books.find({"title" : {$type : "string"}})
16.ObjectId生成器
在默认情况下,_id字段使用ObjectId类型,采用16进制编码形式,共12个字节。
生成一个新的 ObjectId
1 db.dates.insertMany([{data1:Date()},{data2:new Date()},{data3:ISODate()}])
2 db.dates.find().pretty()
4.3 ObjectId生成器
4字节表示Unix时间戳(秒)。
5字节表示随机数(机器号+进程号唯一)。
3字节表示计数器(初始化时随机)。
db.getCollection("orderItem").find({_id :{$gt:ObjectId("66f152405d660000ad00690d")}})
ObjectId("66f152405d660000ad00690d").getTimestamp() //2024-09-23 11:34:24.000
ObjectId("66f152405d660000ad00690d").str //66f152405d660000ad00690d
ObjectId("66f152405d660000ad00690d").toString() //ObjectId("66f152405d660000ad00690d")
ObjectId("66f152405d660000ad00690d").valueOf() //66f152405d660000ad00690d
17.内嵌文档和数组
db.books.insert({
title: "撒哈拉的故事",
author: {
name:"三毛",
gender:"女",
hometown:"重庆"
}
})
db.books.find({"author.name":"三毛"})
db.books.updateOne({"author.name":"三毛"},{$set:{"author.hometown":"重庆/台湾"}})
db.books.updateOne({"author.name":"三毛"},{$set:{tags:["旅行","随笔","散文","爱情","文 学"]}}) //增加tags标签
db.books.updateOne({"author.name":"三毛"},{$push:{tags:"猎奇"}}) //数组末尾追加元素