Skip to content

Latest commit

 

History

History
289 lines (215 loc) · 12.7 KB

MongoDB运算命令.md

File metadata and controls

289 lines (215 loc) · 12.7 KB

MongoDB运算命令

查询和映射

比较查询

语法 解释
$eq 等于
$ne 不等于
$gt 大于
$gte 大于等于
$lt 小于
$lte 小于等于
$in 等于数组中某个值
$nin 不等于数组中任意值

注意:
对于$in和$nin来说,数组里匹配的值还可以是正则表达式,例如:db.users.find({name:{$in:[/x/,/^p/]}}) 找出名字中有字母x或以字母p为开头的数据

对于$nin来说,如果检测的属性本身不存在,则会返回该条数据。例如:db.users.find({age:{$nin:[18]}}) 如果age属性根本就不存在,也就意味着age的值不会为18,因此会返回所有数据

逻辑查询

语法 解释
$and 逻辑与,数组中所有表达式必须都成立
$not 逻辑非,数组中表达式都不成立或要对比的属性本身不存在
$nor 逻辑或的取反,数组中表达式中任何一个都不成立
$or 逻辑或,数组中表达式任何一个成立即可

注意:
$and 执行短路查询,即若数组中前面表达式不成立,则不会继续剩余表达式的运算
$not 若对比属性本身不存在,运行结果也视为成立
$nor 不可以单独使用$nor,$nor必须配合[],[]包含其他查询才可以使用。

元素查询

语法 解释
$exists 属性是否存在,哪怕该属性值为null或undefined(事实上undefined类型值已经被废弃)
$type 属性值类型,如果属性值是数组则判断数组每一项是否是该类型

注意
$exists 只存在2个值,$exists:true 或 $exists:false
$type 对应的值可以有2种表现形式:类型对应的字符串 或 类型对应的数字编号

如果有一条数据为 {'_id':1,'zipcode':['450000','450022']} 那么
db.address.find({zipcode:{$type:'string'}}) 由于zipcode属性值为array,则会对数组每一项进行类型匹配,因此是可以命中该条数据的。

类型 含义 数字编号 别名(字符串) 备注
Double 双精度浮点数(整数或小数) 1 'double'
String 字符串 2 'string'
Object 对象 3 'object'
Array 数组 4 'array'
Binary data 二进制数据 5 binData
Undefined 未定义 6 'undefined' 已废弃
ObjectId MongoDB自动生成的_id 7 'objectId'
Boolean 布尔值 8 'bool'
Date 日期(unix格式) 9 'date'
Null 非任何有效值 10 'null'
Regullar Expression 正则表达式 11 'regex'
DBPointer / 12 'dbPointer' 已废弃
JavaScript JS代码 13 'javascript'
Symbol 符号 14 'symbol' 已废弃
JavaScript(with scope) 带作用域的JS代码 15 'javascriptWithScope'
32-bit integer 32为整数 16 'int'
Timestamp 时间戳(数字) 17 'timestamp'
64-bit integer 64位整数 18 'long'
Decimal128 高精度小数 19 'decimal'
Min key 最小键 -1 'minKey'
Max key 最大键 127 'maxKey'

例如 String 对应的编号数字为2,别名为'string' 因此:
db.address.find({zipcode:{$type:2}})
等同于
db.address.find({zipcode:{$type:'string'}})


关于数字精度的知识补充:

类型 含义 补充
float 单精度浮点数 32位二进制储存 MongoDB中不存在此类型
double 双精度浮点数 64位二进制储存 MongoDB中对应类型为Double
decimal 高精度浮点数 128位二进制储存 MongoDB中对应类型为Decimal128

注意:
浮点数计算结果并不精确,例如 0.3 - 0.2 = 0.0999999999
对于计算机来说,数字类型精度越高 运算速度越慢。


关于ObjectID的知识补充:
MongoDB默认自动生成的_id格式遵循以下规则:

  • 前 4 个字节为时间戳中的秒
  • 中间 5 个字节为一个随机数(事实上并不真的是随机数,前3个字节为机器标识码,后2个字节为进程pid)
  • 后 3 个字节为 一个累加的计数器数字,起始值并不是 0 而是一个随机数

假设某_id值为 '5ecdf8e67c9b393daa572f6e'
该字符串长度24,是 24位16进制数,实际占用12个字节储存空间。

注意,批量写入数据时:

  • 前4个字节对应 时间戳中的秒 可能相同
  • 中间5个字节(3个字节机器标识码和2个字节进程pid) 也可能相同
  • 后3个字节对应的 累加计数 肯定不同。 由于累加计数器初始值并不一定是从0开始,所以理论上无法通过后3个字节对应的数字大小来判断写入数据库的先后顺序

评价查询

语法 解释
$expr 允许使用聚合表达式
$jsonSchema 根据给定的JSON结构格式验证文档,限定数据类型
$mod 根据给定的2个参数来取余
$regex 匹配出符合正则表达式的数据
$text 根据指定的规则,进行文本搜索
$where 匹配符合JavaScript表达式(或函数)的数据

注意:
$expr 所谓允许使用聚合表达式,意思就是让原本不支持聚合查询的函数可以使用聚合查询,例如find()。举例: db.users.find({$expr:{$gt:['$yingyu','$shuxue']}})

$jsonSchema中验证的JSON文档结构需要使用特定的书写规范,而具体规范此处暂时不做深究。

$mod 的两个参数,第1个为除数,第2个为余数。例如{$mod:[4,1]}即表示 除以4余数为1个 评估查询。

$regex 通常使用格式为 {$regex:/xxx/x} 其中xxx为正则表达式的内容,而x为匹配参数选项(i表示不区分大小写、m是否换行匹配、s允许.字符匹配所有字符包括换行符、x忽略空格) $regex还有另外2中写法,例如:{$regex:/^yang/i} 还可以写成 {$regex:/^yang/,$options:'i'} 或 {$regex:'^yang',$options:'i'}

$text对应的搜索规则,与4个选项:$search(关键词)、$language、$caseSensitive(大小写是否敏感,默认为false即不区分大小写)、$diacriticSensitive(声调是否敏感,默认为false即不敏感,例如:e 和 é)

$where 中对应的JavaScript表达式(或函数)中 this 指当前这条数据。 $where 和 $expr 的区别:$where可以匹配以JavaScript表达式(或函数)为规则的数据,$expr不可以,$expr对应的是以聚合查询为规则,$expr执行效率更快。因此,应优先使用$expr和对应的聚合表达式,而不是使用$where和对应的JS表达式。

地理空间查询

语法 解释
$geoIntersects 查询出与区域相交的文档,仅支持2dsphere索引
$geoWithin 查询出完全包含在某个区域的文档,支持2dsphere和2d索引
$near 查询出距离某区域从近到远的其他区域文档,支持2dsphere和2d索引
$nearSphere 查询出距离球面几何上某个点从近到远的其他文档,支持2dsphere和2d索引

注意:
地理空间查询非常重要,需要稍后再深入研究
可参考这2篇文章:https://www.jianshu.com/p/f04810bfdc44https://yq.aliyun.com/articles/616432

数组查询

语法 解释
$all 查询出数组中所有选项必须可以匹配到的文档,而$in只要求匹配到其中一个即可
$elemMath 查询出满足数组中每一个条件查询的文档
$size 查询出符合size设定长度的数组所对应的文档

注意:
$in和$nin归类在 比较查询 中,并不属于数组查询,尽管他们形式上也可以使用数组。

二进制操作

语法 解释
$bitsAllClear 将符合条件的全部二进制数据的值设置为0,即全部清空
$bitsAllSet 将符合条件的全部二进制数据的值设置为1
$bitsAnyClear 将符合条件的任何二进制数据的值设置为0,即全部清空
$bitsAnySet 将符合条件的任何二进制数据的值设置为1

注意:
All和Any的区别暂时还不清楚,有待以后研究。

注释操作

语法 解释
$comment 添加一条查询注释

注意:
这条查询注释语句是会写入log日志文件中的,目的是为了查看日志时方便理解。

投影操作

语法 解释
$ 与查询值匹配的数组中第一个元素的投影,表现为 <array>.$
$elemMatch 与查询条件匹配的数组中第一个元素的投影,表现为 $elemMath:{}
$meta 使用$text查询获得的文档匹配分数的投影,表现为 $meta: "textScore"
$slice 控制数组返回数量(类似JS中array的slice方法),表现为 $slice:[num] 或 $slice:[num1,num2]

注意:
$meta 中的“文档匹配分数”指“匹配接近度”

$slice的参数也可以为负数,表示从数组结尾处开始计算,和JS中array.slice()完全一致

更新运算

字段属性

语法 解释
$currentDate 设置字段属性值为当前时间,可以是时间戳(timestamp)或日期(date)
$inc 预聚合,将字段属性值按照指定的量进行自增
$min 若字段属性值小于指定值,则将该属性值修改为该值
$max 若字段属性值大于指定值,则将该属性值修改为该值
$mul 将字段属性值乘以指定值
$rename 将字段属性名修改为指定值
$set 将字段属性值修改为指定值
$setOnInsert 若更新导致插入该字段,并设定该字段属性值为指定值
$unset 删除该字段属性,表现为 {$unset:{xxx:''}

注意:
对字段操作的前提是该字段需要先存在,若不存在则会找不到对象的报错 $setOnInsert 对于本身已存在该字段的文档不起作用
$unset 虽然为删除某字段属性,但是依然需要编写代码,设置该字段属性值为''

数组操作

语法 解释
$ 占位符,表示数组中的第1个元素,形式为 .$
$[] 占位符,表示数组中的全部元素,形式为 .$[]
$[] 占位符,表示arrayFilters的全部元素
$addToSet 若字段中不存在该值,才将值添加到字段属性值中
$pop 删除字段属性值为数组中的第一项(filed:-1时)或最后一项(filed:1时)
$pull 删除符合匹配的字段属性值的项(默认只作用1条文档,若希望是多条则需配合 {multi:true})
$push 向字段属性值中添加项
$pullAll 删除符合匹配的字段数值的全部项

注意:
以上所有的增加或删除,全部针对的是元素中某字段属性值为数组的操作,不是针对元素的操作。

修饰语

语法 解释
$each 配合$push或$addToSet,以数组形式储存要验证或添加的每一项
$position 配合$push,表明插入的位置,$position:0 即表示插入在开头第1项,
但是请注意 $position 必须配合 $push 的 $each:[] 的形式才可以,示例:$push:{ myarr: { $each:[xxx,xxx], $position:0 }}
$slice 配合$push,控制修改之后属性值数组的长度,若超出则进行数组裁切
$sort 配合$push,表明以升序(值为-1)或降序(值为1)进行排序

注意:
$slice的值若为0则意味着将属性值数组清空、若为正整数则从左往右裁切、若为负整数则从右往左裁切

二进制操作

语法 解释
$bit 以and或or或xor方式操作二进制数据

元操作

修饰语

语法 解释
$comment 向查询添加注释
$explain 强制MongoDB报告查询执行计划
$hint 强制MongoDB使用特定索引
$max 获得最大值
$maxTimeMS 指定处理游标上的操作累计时间限制(毫秒)
$min 获得最小值
$orderby 返回一个光标,包含根据排序规范排序的文档
$query 包装查询文档
$returnKey 强制光标仅返回索引中包含的字段
$showDiskLoc 修改返回的文档以包含对每个文档的磁盘位置引用

排序

语法 解释
$natural 使用磁盘上文档的顺序来排列文档

未完待续

至此关于各种属性值(字符串、数字、地理空间、数组、二进制、元)的查询和修改对应的函数已梳理完毕,接下来是 聚合查询。