【mongoDB查询进阶】聚合管道(三)--表达式操作符
https://segmentfault.com/a/1190000010910985
管道操作符的分类
管道操作符可以分为三类:
- 阶段操作符(Stage Operators)
- 表达式操作符(Expression Operators)--主要用于$project
- 累加器(Accumulators)--主要用于$group分组
表达式操作符(Expression Operators)
表达式操作符主要用于在管道中构建表达式时使用,使用类似于函数那样需要参数,主要用于$project操作符中,用于构建表达式,使用方法一般如下:
方法1:
{ <operator>: [ <argument1>, <argument2> ... ] }
方法2:
{ <operator>: <argument> }
表达式操作符分类
- 布尔值操作符(Boolean Operators)
- 集合操作符(Set Operators)
- 比较操作符(Comparison Operators)
- 数学操作符(Arithmetic Operators)
- 字符串操作符(String Operators)
- 文本搜索操作符(Text Search Operators)
- 数组操作符(Array Operators)
- 变量操作符(Variable Operators)
- 字面量操作符(Literal Operators)
- 日期操作符(Date Operators)
- 条件操作符(Conditional Operators)
- 数据类型操作符(Data Type Operators)
常用表达式操作符
- 布尔值操作符(Boolean Operators)
| 操作符 | 简述 | 
|---|---|
| $and | 逻辑与操作符,当他的表达式中所有值都是true的时候,才返回true。 用法: { $and: [ <expression1>, <expression2>, ... ] }。 | 
| $or | 逻辑或操作符,当他的表达式中有值是true的时候,就会返回true。用法: { $or: [ <expression1>, <expression2>, ... ] } | 
| $not | 取反操作符,返回表达式中取反后的布尔值。用法: { $not: [ <expression> ] } | 
示例
| 例子 | 结果 | 
|---|---|
| { $and: [ 1, "green" ] } | true | 
| { $and: [ ] } | true | 
| { $and: [ [ null ], [ false ], [ 0 ] ] } | true | 
| { $and: [ null, true ] } | false | 
| { $and: [ 0, true ] } | false | 
| { $or: [ true, false ] } | true | 
| { $or: [ [ false ], false ] } | true | 
| { $or: [ null, 0, undefined ] } | false | 
| { $or: [ ] } | false | 
| { $not: [ true ] } | false | 
| { $not: [ [ false ] ] } | false | 
| { $not: [ false ] } | true | 
| { $not: [ null ] } | true | 
| { $not: [ 0 ] } | true | 
- 比较操作符(Comparison Operators)
| 操作符 | 简述 | 
|---|---|
| $cmp | 比较操作符,比较表达式中两个值的大小,如果第一个值小于第二个值则返回-1,相等返回0,大于返回1。用法 { $cmp: [ <expression1>, <expression2> ] } | 
| $eq | 比较表达式中两个是否相等,是则返回true,否则返回false。用法 { $eq: [ <expression1>, <expression2> ] } | 
| $gt | 比较表达式中第一个值是否大于第二个值,是则返回true,否则返回false。用法 { $gt: [ <expression1>, <expression2> ] } | 
| $gte | 比较表达式中第一个值是否大于等于第二个值,是则返回true,否则返回false。用法 { $gte: [ <expression1>, <expression2> ] } | 
| $lt | 比较表达式中第一个值是否小于第二个值,是则返回true,否则返回false。用法 { $lt: [ <expression1>, <expression2> ] } | 
| $lte | 比较表达式中第一个值是否小于等于第二个值,是则返回true,否则返回false。用法 { $lte: [ <expression1>, <expression2> ] } | 
| $ne | 比较表达式中两个是否相等,不过返回值与$eq相反,是则返回false,否则返回true。用法 { $ne: [ <expression1>, <expression2> ] } | 
示例
假设有一个关于考试成绩的集合:
{ "_id" : , "name" : "abc1",  score:  }
{ "_id" : , "name" : "avc1",  score:  }
{ "_id" : , "name" : "adc1",  score:  }
{ "_id" : , "name" : "awc1",  score:  }
{ "_id" : , "name" : "xyz1",  score:  }
{ "_id" : , "name" : "VWZ1",  score:  }
操作如下:
db.collection.aggregate(
[
{
$project:
{
name: ,
score: ,
cmp60: { $cmp: [ "$score", ] },
eq100: { $eq: [ "$score", ] },
gt80: { $gt: [ "$score", ] },
gte80: { $gte: [ "$score", ] },
lt80: { $lt: [ "$score", ] },
lte80: { $lte: [ "$score", ] },
ne100: { $ne: [ "$score", ] },
_id:
}
}
]
)
返回结果:
{ "name" : "abc1", score: , cmp60: , eq100: false, gt80: false, gte80: true, lt80: false, lte80: true, ne100: true }
{ "name" : "avc1", score: , cmp60: , eq100: false, gt80: true, gte80: true, lt80: false, lte80: false, ne100: true }
{ "name" : "adc1", score: , cmp60: , eq100: false, gt80: false, gte80: false, lt80: true, lte80: false, ne100: true }
{ "name" : "awc1", score: , cmp60: , eq100: false, gt80: false, gte80: false, lt80: true, lte80: true, ne100: true }
{ "name" : "xyz1", score: , cmp60: -, eq100: false, gt80: false, gte80: false, lt80: true, lte80: true, ne100: true }
{ "name" : "VWZ1", score: , cmp60: , eq100: true, gt80: true, gte80: true, lt80: false, lte80: false, ne100: false }
- 数学操作符(Arithmetic Operators)
| 操作符 | 简述 | 
|---|---|
| $abs | 求绝对值操作符,于v3.2版新加入。用法: { $abs: <number> } | 
| $add | 求和操作符,返回所有表达式相加起来的结果。用法: { $add: [ <expression1>, <expression2>, ... ] } | 
| $ceil | 进一法取整操作符,取 于v3.2版新加入。用法: { $ceil: <number> } | 
| $divide | 求商操作符,返回表达式1除以表达式2的商。用法: { $divide: [ <expression1>, <expression2> ] } | 
| $subtract | 求差操作符,返回表达式1减去表达式2的结果。用法: { $subtract: [ <expression1>, <expression2> ] } | 
| $multiply | 求积操作符,返回所有表达式相乘的结果。用法: { $multiply: [ <expression1>, <expression2>, ... ] } | 
| $mod | 求余操作符,返回所有表达式1除以表达式2所得到的余数。用法: { $multiply: [ <expression1>, <expression2>] } | 
示例
| 例子 | 结果 | 
|---|---|
| { $abs: -1 } | 1 | 
| { $abs: 1 } | 1 | 
| { $abs: null } | null | 
| { $add: [1, 1] } | 2 | 
| { $ceil: 1 } | 1 | 
| { $ceil: 7.80 } | 8 | 
| { $ceil: -2.8 } | -2 | 
| { $divide: [40, 8] } | 5 | 
| { $subtract: [10, 8] } | 2 | 
| { $multiply: [5, 8] } | 40 | 
| { $mob: [80, 7] } | 3 | 
| { $mob: [80, 8] } | 0 | 
Tips:
$add将一个日期类型和数字类型相加会变成日期类型。 这样的话,当数据库存储的是时间戳但是需要又想对其使用日期操作符的话,就可以通过这样的方法,先让其变成日期类型,然后再使用日期操作符,用法参考:{ $add: [ new Date(0), '$ts' ] }。
- 字符串操作符(String Operators)
| 操作符 | 简述 | 
|---|---|
| $concat | 连接操作符,将给定表达式中的字符串连接一起。用法: { $concat: [ <expression1>, <expression2>, ... ] } | 
| $split | 切割操作符,用于对字符串进行分切。用法: { $split: [ <string expression>, <delimiter> ] } | 
| $toLower | 用于返回字符串的小写形式。用法: { $toLower: <expression> } | 
| $toUpper | 用于返回字符串的大写形式。用法: { $toUpper: <expression> } | 
| $substr | 用于返回子字符串,v3.4+版本不建议使用,应该使用substrBytes或substrCP,v3.4+版本使用的话,相当于substrBytes。用法: { $substr: [ <string>, <start>, <length> ] } | 
| $substrBytes | 用于根据UTF-8下的字节位置返回子字符串(起始位置为0),于v3.4新增。用法: { $substrBytes: [ <string expression>, <byte index>, <byte count> ] } | 
| $substrCP | 用于根据UTF-8下的Code Point位置返回子字符串(起始位置为0),于v3.4新增。用法: { $substrCP: [ <string expression>, <code point index>, <code point count> ] } | 
Code Point: (1) Any value in the Unicode codespace; that is, the range of integers from 0 to 10FFFF16. Not all code points are assigned to encoded characters. See code point type. (2) A value, or position, for a character, in any coded character set.
示例
| 例子 | 结果 | 
|---|---|
| { $concat: [ "item", " - ", "a" ] } | item - a | 
| { $split: [ "June-15-2013", "-" ] } | [ "June", "15", "2013" ] | 
| { $split: [ "banana split", "a" ] } | [ "b", "n", "n", " split" ] | 
| { $split: [ "headphone jack", 7 ] } | $split第二个参数必须是一个字符串,不能是数字 | 
| { $toLower: "ITEM" } | "item" | 
| { $toLower: "Item" } | "item" | 
| { $toLower: null } | "" | 
| { $toUpper: "item" } | "ITEM" | 
| { $toUpper: "Item" } | "ITEM" | 
| { $toUpper: null } | "" | 
| { $substrBytes: [ "abcde", 1, 2 ] } | "bc" | 
| { $substrBytes: [ "Hello World!", 6, 5 ] } | "World" | 
| { $substrBytes: [ "cafétéria", 0, 5 ] } | "café" | 
| { $substrBytes: [ "cafétéria", 5, 4 ] } | "tér" | 
| { $substrBytes: [ "cafétéria", 7, 3 ] } | "Error: Invalid range, starting index is a UTF-8 continuation byte." | 
| { $substrBytes: [ "cafétéria", 3, 1 ] } | "Error: Invalid range, ending index is in the middle of a UTF-8 character." | 
| { $substrBytes: [ "寿司sushi", 0, 3 ] } | "寿" | 
| { $substrCP: [ "abcde", 1, 2 ] } | "bc" | 
| { $substrCP: [ "Hello World!", 6, 5 ] } | "World" | 
| { $substrCP: [ "cafétéria", 0, 5 ] } | "cafét" | 
| { $substrCP: [ "cafétéria", 5, 4 ] } | "tér" | 
| { $substrCP: [ "cafétéria", 7, 3 ] } | "ia" | 
| { $substrCP: [ "cafétéria", 3, 1 ] } | "é" | 
| { $substrCP: [ "寿司sushi", 0, 3 ] } | "寿司s" | 
- 日期操作符(Date Operators)
| 操作符 | 简述 | 
|---|---|
| $dayOfYear | 返回一年中的一天,值在1和366(闰年)之间。用法: { $dayOfYear: <expression> } | 
| $dayOfMonth | 返回一个月中的一天,值在1和31之间。用法: { $dayOfMonth: <expression> } | 
| $dayOfWeek | 返回一周中的一天,值在1(周日)和7(周六)之间。用法: { $dayOfWeek: <expression> } | 
| $year | 返回年份,eg:2017。用法: { $year: <expression> } | 
| $month | 返回月份,值在1和12之间。用法: { $month: <expression> } | 
| $week | 返回周 ,值在0和53之间。用法: { $week: <expression> } | 
| $hour | 返回时 ,值在0和23之间。用法: { $hour: <expression> } | 
| $minute | 返回分 ,值在0和59之间。用法: { $minute: <expression> } | 
| $second | 返回秒,值在0和60之间(闰秒)。用法: { $second: <expression> } | 
| $millisecond | 返回毫秒,值在0和999之间。用法: { $millisecond: <expression> } | 
| $dateToString | 返回日期的字符串。用法: { $dateToString: { format: <formatString>, date: <dateExpression> } } | 
示例
假如有以下数据:
{ "_id" : , "item" : "abc", "price" : , "quantity" : , "date" : ISODate("2014-01-01T08:15:39.736Z") }
进行如下操作:
db.collection.aggregate(
[
{
$project:
{
year: { $year: "$date" },
month: { $month: "$date" },
day: { $dayOfMonth: "$date" },
hour: { $hour: "$date" },
minutes: { $minute: "$date" },
seconds: { $second: "$date" },
milliseconds: { $millisecond: "$date" },
dayOfYear: { $dayOfYear: "$date" },
dayOfWeek: { $dayOfWeek: "$date" },
week: { $week: "$date" },
yearMonthDayUTC: { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
time: { $dateToString: { format: "%H:%M:%S:%L", date: "$date" } }
}
}
]
)
返回结果:
{
  "_id" : ,
  "year" : ,
  "month" : ,
  "day" : ,
  "hour" : ,
  "minutes" : ,
  "seconds" : ,
  "milliseconds" : ,
  "dayOfYear" : ,
  "dayOfWeek" : ,
  "week" : ,
  "yearMonthDayUTC" : "2014-01-01",
  "time" : "08:15:39:736"
}
- 条件操作符(Conditional Operators)
| 操作符 | 简述 | 
|---|---|
| $cond | 用法: { $cond: [ <boolean-expression>, <true-case>, <false-case> ] }或者 v2.6+还支持{ $cond: { if: <boolean-expression>, then: <true-case>, else: <false-case-> } } | 
| $ifNull | 用法: { $ifNull: [ <expression>, <replacement-expression-if-null> ] } | 
示例
假设有一个关于考试成绩的集合:
{ "_id" : , "name" : "a",  score:  }
{ "_id" : , "name" : "b",  score:  }
{ "_id" : , "name" : "c",  score:  }
{ "_id" : , "name" : null,  score:  }
操作如下:
db.collection.aggregate(
[
{
$project:
{
_id: ,
score: ,
pass:
{
$cond: [ { $gte: [ "$score", ] }, , ]
},
description: { $ifNull: [ "$name", "Unspecified" ] }
}
}
]
)
返回结果:
{ "name" : "a",  score: , pass:  }
{ "name" : "b",  score: , pass:  }
{ "name" : "c",  score: , pass:  }
{ "name" : "Unspecified",  score: , pass:  }
总结
本文介绍表达式操作符的分类和常用的表达式操作符的用法,表达式操作符主要作用于$project下,通过使用这些操作符可以对文档中的字面量进行处理并返回,进而返回更多有用的数据。
【mongoDB查询进阶】聚合管道(三)--表达式操作符的更多相关文章
- 【mongoDB查询进阶】聚合管道(二) -- 阶段操作符
		https://segmentfault.com/a/1190000010826809 什么是管道操作符(Aggregation Pipeline Operators) mongoDB有4类操作符用于 ... 
- [.net 面向对象程序设计进阶] (4) 正则表达式 (三) 表达式助手
		[.net 面向对象程序设计进阶] (2) 正则表达式(三) 表达式助手 上面两节对正则表达式的使用及.NET下使用正则表达式作了详细说明,本节主要搜集整理了常用的正则表达式提供参考. 此外为了使用方 ... 
- 【mongoDB查询进阶】聚合管道(一) -- 初识
		https://segmentfault.com/a/1190000010618355 前言:一般查询可以通过find方法,但如果是比较复杂的查询或者数据统计的话,find可能就无能为力了,这时也许你 ... 
- MongoDB学习day06--高级查询aggregate聚合管道和nodejs操作aggregate
		一.MongoDB聚合管道(Aggregation Pilpeline) 使用聚合管道可以对集合中的文档进行变换和组合. 主要功能:表的关联查询.数据统计 二.aggregate 管道操作符与表达式 ... 
- MongoDB 高级查询_aggregate聚合管道
		MongoDB 聚合管道(AggregationPipeline) 使用聚合管道可以对集合中的文档进行变换和组合.实际项目应用主要是表关联查询.数据的统计. MongoDB 中使用 db.COLLEC ... 
- MongoDB 聚合(管道与表达式)
		MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果.有点类似sql语句中的 count(*). aggregate() 方法 MongoDB中 ... 
- C# MongoDB 查询,分组,聚合,排序,条件,分页
		先下载个C#的驱动.MongoDB提供各种主流与非主流预言的开发驱动. C# Driver 下载地址:这里 CSharp Driver Tutorial:这里 下载文件安装或者解压缩包 如果您是安装, ... 
- MongoDB小结27 - 聚合管道【$project】
		我们有这样的数据 { "_id" : 1, title: "abcdef", isbn: "6969696969", author: { l ... 
- Mongodb - 解决 ( aggregate聚合管道 ) $match  根据 id 匹配 返回 [ ] 的问题
		需要对 id 进行转换 const mongoose = require('mongoose') var ObjectId = mongoose.Types.ObjectId; await Use ... 
随机推荐
- Mysql 子查询
			一个 SELECT 语句中包含另一个或多个 SELECT 语句就是子查询 WHERE 后: 把 SELECT 查询出来的结果当做条件 # 查询和李四同性别的人 SELECT * FROM studen ... 
- 三星450R5J windows8.1系统重装小结
			本人一台三星450R5J,到今年也差不多五六年了.虽然颜值很高,但是用久了真的不行,毕竟是属于商务型笔记本,这里我就不晒配置了.  比较一下四五年前的三星与现在使用的华硕,三星看起来更鲜.  准 ... 
- iOS----------关于UDID和UUID的一些理解
			一.UDID(Unique Device Identifier) UDID是Unique Device Identifier的缩写,中文意思是设备唯一标识. 在很多需要限制一台设备一个账号的应用中经 ... 
- java内存分配与垃圾回收
			JVM的内存分配主要基于两种,堆和栈. 我们来看一下java程序运行时候的内存分配策略: 1):静态存储区(方法区): 2):栈区: 3):堆区: 1):主要存放静态数据,全局static数据和常量. ... 
- 浅谈Kotlin(三):类
			浅谈Kotlin(一):简介及Android Studio中配置 浅谈Kotlin(二):基本类型.基本语法.代码风格 浅谈Kotlin(三):类 浅谈Kotlin(四):控制流 前言: 已经学习了前 ... 
- web-worker 的使用
			JavaScript采用的是单线程模式,它每次也只能执行一个事件,所以它在加载大量的事件的时候会比较慢. 而web-worker的作用就是给JavaScript提供一个多线程的模式. 注意的是 web ... 
- Linux/Unix 中 wheel 组的来源
			使用过 Linux/Unix 的朋友应该知道,将用户添加都 wheel用户组,让用户可以通过在命令在前加 sudo 临时获取 root 用户的权限.但是有没有朋友会想知道为何这个用户组要交 wheel ... 
- 网站流量统计PV&UV
			统计网站pv和uv PV是网站分析的一个术语,用以衡量网站用户访问的网页的数量. 对于广告主,PV值可预期它可以带来多少广告收入.一般来说,PV与来访者的数量成正比,但是PV并不直接决定页面的真实来访 ... 
- 使用Visual Studio Team Services敏捷规划和项目组合管理(二)——VSTS中的工作项
			使用Visual Studio Team Services敏捷规划和项目组合管理(二)--VSTS中的工作项 1.通过project/team下拉菜单选择MyHealthClinic\Web,导航到W ... 
- 微信小程序中的循环遍历问题
			比如:如果在微信小程序中要遍历输出 0-9 的数,我们会使用for循环 ;i<;i++){ console.log(i); } 确实结果也是这样: 但是,如果我在循环时同时调用wx的api接口1 ... 
