语法 | 解释 |
---|---|
$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/f04810bfdc44 、https://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 | 使用磁盘上文档的顺序来排列文档 |
至此关于各种属性值(字符串、数字、地理空间、数组、二进制、元)的查询和修改对应的函数已梳理完毕,接下来是 聚合查询。