聚合操作符

算术操作符

abs

聚合操作符。返回一个数字的绝对值。

API 说明

语法如下:

  1. db.command.aggregate.abs(<number>)

abs 传入的值除了数字常量外,也可以是任何最终解析成一个数字的表达式。

如果表达式解析为 null 或者指向一个不存在的字段,则 abs 的结果是 null。如果值解析为 NaN,则结果是 NaN

示例代码

假设集合 ratings 有如下记录:

  1. { _id: 1, start: 5, end: 8 }
  2. { _id: 2, start: 4, end: 4 }
  3. { _id: 3, start: 9, end: 7 }
  4. { _id: 4, start: 6, end: 7 }

···可以用如下方式求得各个记录的 startend 之间的绝对差异大小:

  1. const $ = db.command.aggregate
  2. db.collection('ratings').aggregate()
  3. .project({
  4. delta: $.abs($.subtract(['$start', '$end']))
  5. })
  6. .end()

返回结果如下:

  1. { "_id" : 1, "delta" : 3 }
  2. { "_id" : 2, "delta" : 0 }
  3. { "_id" : 3, "delta" : 2 }
  4. { "_id" : 4, "delta" : 1 }

add

聚合操作符。将数字相加或将数字加在日期上。如果数组中的其中一个值是日期,那么其他值将被视为毫秒数加在该日期上。

API 说明

语法如下:

  1. db.command.aggregate.add([<表达式1>, <表达式2>, ...])

表达式可以是形如 $ + 指定字段,也可以是普通字符串。只要能够被解析成字符串即可。

示例代码

假设集合 staff 有如下记录:

  1. { _id: 1, department: "x", sales: 5, engineer: 10, lastUpdate: ISODate("2019-05-01T00:00:00Z") }
  2. { _id: 2, department: "y", sales: 10, engineer: 20, lastUpdate: ISODate("2019-05-01T02:00:00Z") }
  3. { _id: 3, department: "z", sales: 20, engineer: 5, lastUpdate: ISODate("2019-05-02T03:00:00Z") }

数字求和

可以用如下方式求得各个记录人数总数:

  1. const $ = db.command.aggregate
  2. db.collection('staff').aggregate()
  3. .project({
  4. department: 1,
  5. total: $.add(['$sales', '$engineer'])
  6. })
  7. .end()

返回结果如下:

  1. { _id: 1, department: "x", total: 15 }
  2. { _id: 2, department: "y", total: 30 }
  3. { _id: 3, department: "z", total: 25 }

增加日期值

如下操作可以获取各个记录的 lastUpdate 加一个小时之后的值:

  1. const $ = db.command.aggregate
  2. db.collection('staff').aggregate()
  3. .project({
  4. department: 1,
  5. lastUpdate: $.add(['$lastUpdate', 60*60*1000])
  6. })
  7. .end()

返回结果如下:

  1. { _id: 1, department: "x", lastUpdate: ISODate("2019-05-01T01:00:00Z") }
  2. { _id: 2, department: "y", lastUpdate: ISODate("2019-05-01T03:00:00Z") }
  3. { _id: 3, department: "z", lastUpdate: ISODate("2019-05-02T04:00:00Z") }

ceil

聚合操作符。向上取整,返回大于或等于给定数字的最小整数。

API 说明

语法如下:

  1. db.command.aggregate.ceil(<number>)

<number> 可以是任意解析为数字的表达式。如果表达式解析为 null 或指向一个不存在的字段,则返回 null,如果解析为 NaN,则返回 NaN

示例代码

假设集合 sales 有如下记录:

  1. { _id: 1, sales: 5.2 }
  2. { _id: 2, sales: 1.32 }
  3. { _id: 3, sales: -3.2 }

可以用如下方式取各个数字的向上取整值:

  1. const $ = db.command.aggregate
  2. db.collection('sales').aggregate()
  3. .project({
  4. sales: $.ceil('$sales')
  5. })
  6. .end()

返回结果如下:

  1. { _id: 1, sales: 6 }
  2. { _id: 2, sales: 2 }
  3. { _id: 3, sales: -3 }

divide

聚合操作符。传入被除数和除数,求商。

API 说明

语法如下:

  1. db.command.aggregate.divide([<被除数表达式>, <除数表达式>])

表达式可以是任意解析为数字的表达式。

示例代码

假设集合 railroads 有如下记录:

  1. { _id: 1, meters: 5300 }
  2. { _id: 2, meters: 64000 }
  3. { _id: 3, meters: 130 }

可以用如下方式取各个数字转换为千米之后的值:

  1. const $ = db.command.aggregate
  2. db.collection('railroads').aggregate()
  3. .project({
  4. km: $.divide(['$meters', 1000])
  5. })
  6. .end()

返回结果如下:

  1. { _id: 1, km: 5.3 }
  2. { _id: 2, km: 64 }
  3. { _id: 3, km: 0.13 }

exp

聚合操作符。取 e(自然对数的底数,欧拉数) 的 n 次方。

API 说明

语法如下:

  1. db.command.aggregate.exp(<exponent>)

<exponent> 可以是任意解析为数字的表达式。如果表达式解析为 null 或指向一个不存在的字段,则返回 null,如果解析为 NaN,则返回 NaN

示例代码

假设集合 math 有如下记录:

  1. { _id: 1, exp: 0 }
  2. { _id: 2, exp: 1 }
  3. { _id: 3, exp: 2 }
  1. const $ = db.command.aggregate
  2. db.collection('math').aggregate()
  3. .project({
  4. result: $.exp('$exp')
  5. })
  6. .end()

返回结果如下:

  1. { _id: 1, result: 1 }
  2. { _id: 2, result: 2.71828182845905 }
  3. { _id: 3, result: 7.38905609893065 }

floor

聚合操作符。向下取整,返回大于或等于给定数字的最小整数。

API 说明

语法如下:

  1. db.command.aggregate.floor(<number>)

<number> 可以是任意解析为数字的表达式。如果表达式解析为 null 或指向一个不存在的字段,则返回 null,如果解析为 NaN,则返回 NaN

示例代码

假设集合 sales 有如下记录:

  1. { _id: 1, sales: 5.2 }
  2. { _id: 2, sales: 1.32 }
  3. { _id: 3, sales: -3.2 }

可以用如下方式取各个数字的向下取整值:

  1. const $ = db.command.aggregate
  2. db.collection('sales').aggregate()
  3. .project({
  4. sales: $.floor('$sales')
  5. })
  6. .end()

返回结果如下:

  1. { _id: 1, sales: 5 }
  2. { _id: 2, sales: 1 }
  3. { _id: 3, sales: -6 }

ln

聚合操作符。计算给定数字在自然对数值。

API 说明

语法如下:

  1. db.command.aggregate.ln(<number>)

<number> 可以是任意解析为非负数字的表达式。

ln 等价于 log([<number>, Math.E]),其中 Math.EJavaScript 获取 e 的值的方法。

示例代码
db.command.aggregate.ln

聚合操作符。计算给定数字在自然对数值。

语法如下:

  1. db.command.aggregate.ln(<number>)

<number> 可以是任意解析为非负数字的表达式。

ln 等价于 log([<number>, Math.E]),其中 Math.EJavaScript 获取 e 的值的方法。

log

聚合操作符。计算给定数字在给定对数底下的 log 值。

API 说明

语法如下:

  1. db.command.aggregate.log([<number>, <base>])

<number> 可以是任意解析为非负数字的表达式。<base> 可以是任意解析为大于 1 的数字的表达式。

如果任一参数解析为 null 或指向任意一个不存在的字段,log 返回 null。如果任一参数解析为 NaNlog 返回 NaN

示例代码

假设集合 curve 有如下记录:

  1. { _id: 1, x: 1 }
  2. { _id: 2, x: 2 }
  3. { _id: 3, x: 3 }

计算 log2(x) 的值:

  1. const $ = db.command.aggregate
  2. db.collection('staff').aggregate()
  3. .project({
  4. log: $.log(['$x', 2])
  5. })
  6. .end()

返回结果如下:

  1. { _id: 1, log: 0 }
  2. { _id: 2, log: 1 }
  3. { _id: 3, log: 1.58496250072 }

log10

聚合操作符。计算给定数字在对数底为 10 下的 log 值。

API 说明

语法如下:

  1. db.command.aggregate.log(<number>)

<number> 可以是任意解析为非负数字的表达式。

log10 等同于 log 方法的第二个参数固定为 10。

示例代码
db.command.aggregate.log10

聚合操作符。计算给定数字在对数底为 10 下的 log 值。

语法如下:

  1. db.command.aggregate.log(<number>)

<number> 可以是任意解析为非负数字的表达式。

log10 等同于 log 方法的第二个参数固定为 10。

mod

聚合操作符。取模运算,取数字取模后的值。

API 说明

语法如下:

  1. db.command.aggregate.mod([<dividend>, <divisor>])

第一个数字是被除数,第二个数字是除数。参数可以是任意解析为数字的表达式。

示例代码

假设集合 shopping 有如下记录:

  1. { _id: 1, bags: 3, items: 5 }
  2. { _id: 2, bags: 2, items: 8 }
  3. { _id: 3, bags: 5, items: 16 }

各记录取 items 除以 bags 的余数(items % bags):

  1. const $ = db.command.aggregate
  2. db.collection('shopping').aggregate()
  3. .project({
  4. overflow: $.mod(['$items', '$bags'])
  5. })
  6. .end()

返回结果如下:

  1. { _id: 1, log: 2 }
  2. { _id: 2, log: 0 }
  3. { _id: 3, log: 1 }

multiply

聚合操作符。取传入的数字参数相乘的结果。

API 说明

语法如下:

  1. db.command.aggregate.multiply([<expression1>, <expression2>, ...])

参数可以是任意解析为数字的表达式。

示例代码

假设集合 fruits 有如下记录:

  1. { "_id": 1, "name": "apple", "price": 10, "quantity": 100 }
  2. { "_id": 2, "name": "orange", "price": 15, "quantity": 50 }
  3. { "_id": 3, "name": "lemon", "price": 5, "quantity": 20 }

求各个水果的的总价值:

  1. const $ = db.command.aggregate
  2. db.collection('fruits').aggregate()
  3. .project({
  4. name: 1,
  5. total: $.multiply(['$price', '$quantity']),
  6. })
  7. .end()

返回结果如下:

  1. { "_id": 1, "name": "apple", "total": 1000 }
  2. { "_id": 2, "name": "orange", "total": 750 }
  3. { "_id": 3, "name": "lemo", "total": 100 }

pow

聚合操作符。求给定基数的指数次幂。

API 说明

语法如下:

  1. db.command.aggregate.pow([<base>, <exponent>])

参数可以是任意解析为数字的表达式。

示例代码

假设集合 stats 有如下记录:

  1. { "_id": 1, "x": 2, "y": 3 }
  2. { "_id": 2, "x": 5, "y": 7 }
  3. { "_id": 3, "x": 10, "y": 20 }

xy 的平方和:

  1. const $ = db.command.aggregate
  2. db.collection('stats').aggregate()
  3. .project({
  4. sumOfSquares: $.add([$.pow(['$x', 2]), $.pow(['$y', 2])]),
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "sumOfSquares": 13 }
  2. { "_id": 2, "sumOfSquares": 74 }
  3. { "_id": 3, "sumOfSquares": 500 }

sqrt

聚合操作符。求平方根。

API 说明

语法如下:

  1. db.command.aggregate.sqrt([<number>])

参数可以是任意解析为非负数字的表达式。

示例代码

假设直角三角形集合 triangle 有如下记录:

  1. { "_id": 1, "x": 2, "y": 3 }
  2. { "_id": 2, "x": 5, "y": 7 }
  3. { "_id": 3, "x": 10, "y": 20 }

假设 xy 分别为两直角边,则求斜边长:

  1. const $ = db.command.aggregate
  2. db.collection('triangle').aggregate()
  3. .project({
  4. len: $.sqrt([$.add([$.pow(['$x', 2]), $.pow(['$y', 2])])]),
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "len": 3.605551275463989 }
  2. { "_id": 2, "len": 8.602325267042627 }
  3. { "_id": 3, "len": 22.360679774997898 }

subtract

聚合操作符。将两个数字相减然后返回差值,或将两个日期相减然后返回相差的毫秒数,或将一个日期减去一个数字返回结果的日期。

API 说明

语法如下:

  1. db.command.aggregate.subtract([<expression1>, <expression2>])

参数可以是任意解析为数字或日期的表达式。

示例代码

假设集合 scores 有如下记录:

  1. { "_id": 1, "max": 10, "min": 1 }
  2. { "_id": 2, "max": 7, "min": 5 }
  3. { "_id": 3, "max": 6, "min": 6 }

求各个记录的 maxmin 的差值。:

  1. const $ = db.command.aggregate
  2. db.collection('scores').aggregate()
  3. .project({
  4. diff: $.subtract(['$max', '$min'])
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "diff": 9 }
  2. { "_id": 2, "diff": 2 }
  3. { "_id": 3, "diff": 0 }

trunc

聚合操作符。将数字截断为整形。

API 说明

语法如下:

  1. db.command.aggregate.trunc(<number>)

参数可以是任意解析为数字的表达式。

示例代码

假设集合 scores 有如下记录:

  1. { "_id": 1, "value": 1.21 }
  2. { "_id": 2, "value": 3.83 }
  3. { "_id": 3, "value": -4.94 }
  1. const $ = db.command.aggregate
  2. db.collection('scores').aggregate()
  3. .project({
  4. int: $.trunc('$value')
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "value": 1 }
  2. { "_id": 2, "value": 3 }
  3. { "_id": 3, "value": -4 }

数组操作符

arrayElemAt

聚合操作符。返回在指定数组下标的元素。

API 说明

语法如下:

  1. db.command.aggregate.arrayElemAt([<array>, <index>])

<array> 可以是任意解析为数字的表达式。

<index> 可以是任意解析为整形的表达式。如果是正数,arrayElemAt 返回在 index 位置的元素,如果是负数,arrayElemAt 返回从数组尾部算起的 index 位置的元素。

示例代码

假设集合 exams 有如下记录:

  1. { "_id": 1, "scores": [80, 60, 65, 90] }
  2. { "_id": 2, "scores": [78] }
  3. { "_id": 3, "scores": [95, 88, 92] }

求各个第一次考试的分数和和最后一次的分数:

  1. const $ = db.command.aggregate
  2. db.collection('exams').aggregate()
  3. .project({
  4. first: $.arraElemAt(['$scores', 0]),
  5. last: $.arraElemAt(['$scores', -1]),
  6. })
  7. .end()

返回结果如下:

  1. { "_id": 1, "first": 80, "last": 90 }
  2. { "_id": 2, "first": 78, "last": 78 }
  3. { "_id": 3, "first": 95, "last": 92 }

arrayToObject

聚合操作符。将一个数组转换为对象。

API 说明

语法可以取两种:

第一种:传入一个二维数组,第二维的数组长度必须为 2,其第一个值为字段名,第二个值为字段值

  1. db.command.aggregate.arrayToObject([
  2. [<key1>, <value1>],
  3. [<key2>, <value2>],
  4. ...
  5. ])

第二种:传入一个对象数组,各个对象必须包含字段 kv,分别指定字段名和字段值

  1. db.command.aggregate.arrayToObject([
  2. { "k": <key1>, "v": <value1> },
  3. { "k": <key2>, "v": <value2> },
  4. ...
  5. ])

传入 arrayToObject 的参数只要可以解析为上述两种表示法之一即可。

示例代码

假设集合 shops 有如下记录:

  1. { "_id": 1, "sales": [ ["max", 100], ["min", 50] ] }
  2. { "_id": 2, "sales": [ ["max", 70], ["min", 60] ] }
  3. { "_id": 3, "sales": [ { "k": "max", "v": 50 }, { "k": "min", "v": 30 } ] }

求各个第一次考试的分数和和最后一次的分数:

  1. const $ = db.command.aggregate
  2. db.collection('shops').aggregate()
  3. .project({
  4. sales: $.arrayToObject('$sales'),
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "sales": { "max": 100, "min": 50 } }
  2. { "_id": 2, "sales": { "max": 70, "min": 60 } }
  3. { "_id": 3, "sales": { "max": 50, "min": 30 } }

concatArrays

聚合操作符。将多个数组拼接成一个数组。

API 说明

语法如下:

  1. db.command.aggregate.arrayToObject([ <array1>, <array2>, ... ])

参数可以是任意解析为数组的表达式。

示例代码

假设集合 items 有如下记录:

  1. { "_id": 1, "fruits": [ "apple" ], "vegetables": [ "carrot" ] }
  2. { "_id": 2, "fruits": [ "orange", "lemon" ], "vegetables": [ "cabbage" ] }
  3. { "_id": 3, "fruits": [ "strawberry" ], "vegetables": [ "spinach" ] }
  1. const $ = db.command.aggregate
  2. db.collection('items').aggregate()
  3. .project({
  4. list: $.concatArrays(['$fruits', '$vegetables']),
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "list": [ "apple", "carrot" ] }
  2. { "_id": 2, "list": [ "orange", "lemon", "cabbage" ] }
  3. { "_id": 3, "list": [ "strawberry", "spinach" ] }

filter

聚合操作符。根据给定条件返回满足条件的数组的子集。

API 说明

语法如下:

  1. db.command.aggregate.filter({
  2. input: <array>,
  3. as: <string>,
  4. cond: <expression>
  5. })
字段说明
input一个可以解析为数组的表达式
as可选,用于表示数组各个元素的变量,默认为 this
cond一个可以解析为布尔值的表达式,用于判断各个元素是否满足条件,各个元素的名字由 as 参数决定(参数名需加 $$ 前缀,如 $$this)

参数可以是任意解析为数组的表达式。

示例代码

假设集合 fruits 有如下记录:

  1. {
  2. "_id": 1,
  3. "stock": [
  4. { "name": "apple", "price": 10 },
  5. { "name": "orange", "price": 20 }
  6. ],
  7. }
  8. {
  9. "_id": 2,
  10. "stock": [
  11. { "name": "lemon", "price": 15 },
  12. ],
  13. }
  1. const _ = db.command
  2. const $ = db.command.aggregate
  3. db.collection('fruits').aggregate()
  4. .project({
  5. stock: $.filter({
  6. input: '$stock',
  7. as: 'item',
  8. cond: $.gte(['$$item.price', 15])
  9. })
  10. })
  11. .end()

返回结果如下:

  1. { "_id": 1, "stock": [ { "name": "orange", "price": 20} ] }
  2. { "_id": 2, "stock": [ { "name": "lemon", "price": 15 } ] }

in

聚合操作符。给定一个值和一个数组,如果值在数组中则返回 true,否则返回 false

API 说明

语法如下:

  1. db.command.aggregate.in([<value>, <array>])

<value> 可以是任意表达式。

<array> 可以是任意解析为数组的表达式。

示例代码

假设集合 shops 有如下记录:

  1. { "_id": 1, "topsellers": ["bread", "ice cream", "butter"] }
  2. { "_id": 2, "topsellers": ["ice cream", "cheese", "yagurt"] }
  3. { "_id": 3, "topsellers": ["croissant", "cucumber", "coconut"] }

标记销量最高的商品包含 ice cream 的记录。

  1. const $ = db.command.aggregate
  2. db.collection('price').aggregate()
  3. .project({
  4. included: $.in(['ice cream', '$topsellers'])
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "included": true }
  2. { "_id": 2, "included": true }
  3. { "_id": 3, "included": false }

indexOfArray

聚合操作符。在数组中找出等于给定值的第一个元素的下标,如果找不到则返回 -1。

API 说明

语法如下:

  1. db.command.aggregate.indexOfArray([ <array expression>, <search expression>, <start>, <end> ])
字段类型说明
-string一个可以解析为数组的表达式,如果解析为 null,则 indexOfArray 返回 null
-string对数据各个元素应用的条件匹配表达式
-integer可选,用于指定搜索的开始下标,必须是非负整数
-integer可选,用于指定搜索的结束下标,必须是非负整数,指定了 时也应指定 ,否则 默认当做

参数可以是任意解析为数组的表达式。

示例代码

假设集合 stats 有如下记录:

  1. {
  2. "_id": 1,
  3. "sales": [ 1, 6, 2, 2, 5 ]
  4. }
  5. {
  6. "_id": 2,
  7. "sales": [ 4, 2, 1, 5, 2 ]
  8. }
  9. {
  10. "_id": 3,
  11. "sales": [ 2, 5, 3, 3, 1 ]
  12. }
  1. const $ = db.command.aggregate
  2. db.collection('stats').aggregate()
  3. .project({
  4. index: $.indexOfArray(['$sales', 2, 2])
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "index": 2 }
  2. { "_id": 2, "index": 4 }
  3. { "_id": 3, "index": -1 }

isArray

聚合操作符。判断给定表达式是否是数组,返回布尔值。

API 说明

语法如下:

  1. db.command.aggregate.isArray(<expression>)

参数可以是任意表达式。

示例代码

假设集合 stats 有如下记录:

  1. {
  2. "_id": 1,
  3. "base": 10,
  4. "sales": [ 1, 6, 2, 2, 5 ]
  5. }
  6. {
  7. "_id": 2,
  8. "base": 1,
  9. "sales": 100
  10. }

计算总销量,如果 sales 是数字,则求 sales * base,如果 sales 是数组,则求数组元素之和与 base 的乘积。

  1. const $ = db.command.aggregate
  2. db.collection('stats').aggregate()
  3. .project({
  4. sum: $.cond({
  5. if: $.isArray('$sales'),
  6. then: $.multiply([$.sum(['$sales']), '$base']),
  7. else: $.multiply(['$sales', '$base']),
  8. })
  9. })
  10. .end()

返回结果如下:

  1. { "_id": 1, "index": 160 }
  2. { "_id": 2, "index": 100 }

map

聚合操作符。类似 JavaScript Array 上的 map 方法,将给定数组的每个元素按给定转换方法转换后得出新的数组。

API 说明

语法如下:

  1. db.command.aggregate.map({
  2. input: <expression>,
  3. as: <string>,
  4. in: <expression>
  5. })
字段说明
input一个可以解析为数组的表达式
as可选,用于表示数组各个元素的变量,默认为 this
in一个可以应用在给定数组的各个元素上的表达式,各个元素的名字由 as 参数决定(参数名需加 $$ 前缀,如 $$this)
示例代码

假设集合 stats 有如下记录:

  1. {
  2. "_id": 1,
  3. "sales": [ 1.32, 6.93, 2.48, 2.82, 5.74 ]
  4. }
  5. {
  6. "_id": 2,
  7. "sales": [ 2.97, 7.13, 1.58, 6.37, 3.69 ]
  8. }

将各个数字截断为整形,然后求和

  1. const $ = db.command.aggregate
  2. db.collection('stats').aggregate()
  3. .project({
  4. truncated: $.map({
  5. input: '$sales',
  6. as: 'num',
  7. in: $.trunc('$$num'),
  8. })
  9. })
  10. .project({
  11. total: $.sum('$truncated')
  12. })
  13. .end()

返回结果如下:

  1. { "_id": 1, "index": 16 }
  2. { "_id": 2, "index": 19 }

objectToArray

聚合操作符。将一个对象转换为数组。方法把对象的每个键值对都变成输出数组的一个元素,元素形如 { k: <key>, v: <value> }

API 说明

语法如下:

  1. db.command.aggregate.objectToArray(<object>)
示例代码

假设集合 items 有如下记录:

  1. { "_id": 1, "attributes": { "color": "red", "price": 150 } }
  2. { "_id": 2, "attributes": { "color": "blue", "price": 50 } }
  3. { "_id": 3, "attributes": { "color": "yellow", "price": 10 } }
  1. const $ = db.command.aggregate
  2. db.collection('items').aggregate()
  3. .project({
  4. array: $.objectToArray('$attributes')
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "array": [{ "k": "color", "v": "red" }, { "k": "price", "v": 150 }] }
  2. { "_id": 2, "array": [{ "k": "color", "v": "blue" }, { "k": "price", "v": 50 }] }
  3. { "_id": 3, "array": [{ "k": "color", "v": "yellow" }, { "k": "price", "v": 10 }] }

range

聚合操作符。返回一组生成的序列数字。给定开始值、结束值、非零的步长,range 会返回从开始值开始逐步增长、步长为给定步长、但不包括结束值的序列。

API 说明

语法如下:

  1. db.command.aggregate.range([<start>, <end>, <non-zero step>])
字段说明
start开始值,一个可以解析为整形的表达式
end结束值,一个可以解析为整形的表达式
non-zero step可选,步长,一个可以解析为非零整形的表达式,默认为 1
示例代码

假设集合 stats 有如下记录:

  1. { "_id": 1, "max": 52 }
  2. { "_id": 2, "max": 38 }
  1. const $ = db.command.aggregate
  2. db.collection('stats').aggregate()
  3. .project({
  4. points: $.range([0, '$max', 10])
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "points": [0, 10, 20, 30, 40, 50] }
  2. { "_id": 2, "points": [0, 10, 20] }

reduce

聚合操作符。类似 JavaScript 的 reduce 方法,应用一个表达式于数组各个元素然后归一成一个元素。

API 说明

语法如下:

  1. db.command.aggregate.reduce({
  2. input: <array>
  3. initialValue: <expression>,
  4. in: <expression>
  5. })
字段说明
input输入数组,可以是任意解析为数组的表达式
initialValue初始值
in用来作用于每个元素的表达式,在 in 中有两个可用变量,value 是表示累计值的变量,this 是表示当前数组元素的变量
示例代码

简易字符串拼接

假设集合 player 有如下记录:

  1. { "_id": 1, "fullname": [ "Stephen", "Curry" ] }
  2. { "_id": 2, "fullname": [ "Klay", "Thompsom" ] }

获取各个球员的全名,并加 Player: 前缀:

  1. const $ = db.command.aggregate
  2. db.collection('player').aggregate()
  3. .project({
  4. info: $.reduce({
  5. input: '$fullname',
  6. initialValue: 'Player:',
  7. in: $.concat(['$$value', ' ', '$$this']),
  8. })
  9. })
  10. .end()

返回结果如下:

  1. { "_id": 1, "info": "Player: Stephen Curry" }
  2. { "_id": 2, "info": "Player: Klay Thompson" }

获取各个球员的全名,不加前缀:

  1. const $ = db.command.aggregate
  2. db.collection('player').aggregate()
  3. .project({
  4. name: $.reduce({
  5. input: '$fullname',
  6. initialValue: '',
  7. in: $.concat([
  8. '$$value',
  9. $.cond({
  10. if: $.eq(['$$value', '']),
  11. then: '',
  12. else: ' ',
  13. }),
  14. '$$this',
  15. ]),
  16. })
  17. })
  18. .end()

返回结果如下:

  1. { "_id": 1, "name": "Stephen Curry" }
  2. { "_id": 2, "name": "Klay Thompson" }

reverseArray

聚合操作符。返回给定数组的倒序形式。

API 说明

语法如下:

  1. db.command.aggregate.reverseArray(<array>)

参数可以是任意解析为数组表达式。

示例代码

假设集合 stats 有如下记录:

  1. {
  2. "_id": 1,
  3. "sales": [ 1, 2, 3, 4, 5 ]
  4. }

sales 倒序:

  1. const $ = db.command.aggregate
  2. db.collection('stats').aggregate()
  3. .project({
  4. reversed: $.reverseArray('$sales'),
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "reversed": [5, 4, 3, 2, 1] }

size

聚合操作符。返回数组长度。

API 说明

语法如下:

  1. db.command.aggregate.size(<array>)

<array> 可以是任意解析为数组的表达式。

示例代码

假设集合 shops 有如下记录:

  1. { "_id": 1, "staff": [ "John", "Middleton", "George" ] }
  2. { "_id": 2, "staff": [ "Steph", "Jack" ] }

计算各个商店的雇员数量:

  1. const $ = db.command.aggregate
  2. db.collection('staff').aggregate()
  3. .project({
  4. totalStaff: $.size('$staff')
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "totalStaff": 3 }
  2. { "_id": 2, "totalStaff": 2 }

slice

聚合操作符。类似 JavaScritp 的 slice 方法。返回给定数组的指定子集。

API 说明

语法有两种:

返回从开头或结尾开始的 n 个元素:

  1. db.command.aggregate.slice([<array>, <n>])

返回从指定位置算作数组开头、再向后或向前的 n 个元素:

  1. db.command.aggregate.slice([<array>, <position>, <n>])

<array> 可以是任意解析为数组的表达式。

<position> 可以是任意解析为整形的表达式。如果是正数,则将数组的第 <position> 个元素作为数组开始;如果 <position> 比数组长度更长,slice 返回空数组。如果是负数,则将数组倒数第 <position> 个元素作为数组开始;如果 <position> 的绝对值大于数组长度,则开始位置即为数组开始位置。

<n> 可以是任意解析为整形的表达式。如果 <position> 有提供,则 <n> 必须为正整数。如果是正数,slice 返回前 n 个元素。如果是负数,slice 返回后 n 个元素。

示例代码

假设集合 people 有如下记录:

  1. { "_id": 1, "hobbies": [ "basketball", "football", "tennis", "badminton" ] }
  2. { "_id": 2, "hobbies": [ "golf", "handball" ] }
  3. { "_id": 3, "hobbies": [ "table tennis", "swimming", "rowing" ] }

统一返回前两个爱好:

  1. const $ = db.command.aggregate
  2. db.collection('fruits').aggregate()
  3. .project({
  4. hobbies: $.slice(['$hobbies', 2]),
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "hobbies": [ "basketball", "football" ] }
  2. { "_id": 2, "hobbies": [ "golf", "handball" ] }
  3. { "_id": 3, "hobbies": [ "table tennis", "swimming" ] }

zip

聚合操作符。把二维数组的第二维数组中的相同序号的元素分别拼装成一个新的数组进而组装成一个新的二维数组。如可将 [ [ 1, 2, 3 ], [ "a", "b", "c" ] ] 转换成 [ [ 1, "a" ], [ 2, "b" ], [ 3, "c" ] ]

API 说明

语法如下:

  1. db.command.aggregate.zip({
  2. inputs: [<array1>, <array2>, ...],
  3. useLongestLength: <boolean>,
  4. defaults: <array>
  5. })

inputs 是一个二维数组(inputs 不可以是字段引用),其中每个元素的表达式(这个可以是字段引用)都可以解析为数组。如果其中任意一个表达式返回 null<inputs> 也返回 null。如果其中任意一个表达式不是指向一个合法的字段 / 解析为数组 / 解析为 null,则返回错误。

useLongestLength 决定输出数组的长度是否采用输入数组中的最长数组的长度。默认为 false,即输入数组中的最短的数组的长度即是输出数组的各个元素的长度。

defaults 是一个数组,用于指定在输入数组长度不一的情况下时采用的数组各元素默认值。指定这个字段则必须指定 useLongestLength,否则返回错误。如果 useLongestLengthtrue 但是 defaults 是空或没有指定,则 zipnull 做数组元素的缺省默认值。指定各元素默认值时 defaults 数组的长度必须是输入数组最大的长度。

示例代码

假设集合 stats 有如下记录:

  1. { "_id": 1, "zip1": [1, 2], "zip2": [3, 4], "zip3": [5, 6] ] }
  2. { "_id": 2, "zip1": [1, 2], "zip2": [3], "zip3": [4, 5, 6] ] }
  3. { "_id": 3, "zip1": [1, 2], "zip2": [3] ] }

只传 inputs

  1. const $ = db.command.aggregate
  2. db.collection('items').aggregate()
  3. .project({
  4. zip: $.zip({
  5. inputs: [
  6. '$zip1', // 字段引用
  7. '$zip2',
  8. '$zip3',
  9. ],
  10. })
  11. })
  12. .end()

返回结果如下:

  1. { "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] }
  2. { "_id": 2, "zip": [ [1, 3, 4] ] }
  3. { "_id": 3, "zip": null }

设置 useLongestLength

如果设 useLongestLengthtrue

  1. const $ = db.command.aggregate
  2. db.collection('items').aggregate()
  3. .project({
  4. zip: $.zip({
  5. inputs: [
  6. '$zip1', // 字段引用
  7. '$zip2',
  8. '$zip3',
  9. ],
  10. useLongestLength: true,
  11. })
  12. })
  13. .end()

返回结果如下:

  1. { "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] }
  2. { "_id": 2, "zip": [ [1, 3, 4], [2, null, 5], [null, null, 6] ] }
  3. { "_id": 3, "zip": null }

设置 defaults

  1. const $ = db.command.aggregate
  2. db.collection('items').aggregate()
  3. .project({
  4. zip: $.zip({
  5. inputs: [
  6. '$zip1', // 字段引用
  7. '$zip2',
  8. '$zip3',
  9. ],
  10. useLongestLength: true,
  11. defaults: [-300, -200, -100],
  12. })
  13. })
  14. .end()

返回结果如下:

  1. { "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] }
  2. { "_id": 2, "zip": [ [1, 3, 4], [2, -200, 5], [-300, -200, 6] ] }
  3. { "_id": 3, "zip": null }

布尔操作符

and

聚合操作符。给定多个表达式,and 仅在所有表达式都返回 true 时返回 true,否则返回 false

API 说明

语法如下:

  1. db.command.aggregate.and([<expression1>, <expression2>, ...])

如果表达式返回 falsenull0、或 undefined,表达式会解析为 false,否则对其他返回值都认为是 true

示例代码

假设集合 price 有如下记录:

  1. { "_id": 1, "min": 10, "max": 100 }
  2. { "_id": 2, "min": 60, "max": 80 }
  3. { "_id": 3, "min": 30, "max": 50 }

min 大于等于 30 且 max 小于等于 80 的记录。

  1. const $ = db.command.aggregate
  2. db.collection('price').aggregate()
  3. .project({
  4. fullfilled: $.and([$.gte(['$min', 30]), $.lte(['$max', 80])])
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "fullfilled": false }
  2. { "_id": 2, "fullfilled": true }
  3. { "_id": 3, "fullfilled": true }

not

聚合操作符。给定一个表达式,如果表达式返回 true,则 not 返回 false,否则返回 true。注意表达式不能为逻辑表达式(andornornot)。

API 说明

语法如下:

  1. db.command.aggregate.not(<expression>)

如果表达式返回 falsenull0、或 undefined,表达式会解析为 false,否则对其他返回值都认为是 true

示例代码

假设集合 price 有如下记录:

  1. { "_id": 1, "min": 10, "max": 100 }
  2. { "_id": 2, "min": 60, "max": 80 }
  3. { "_id": 3, "min": 30, "max": 50 }

min 不大于 40 的记录。

  1. const $ = db.command.aggregate
  2. db.collection('price').aggregate()
  3. .project({
  4. fullfilled: $.not($.gt(['$min', 40]))
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "fullfilled": true }
  2. { "_id": 2, "fullfilled": false }
  3. { "_id": 3, "fullfilled": true }

or

聚合操作符。给定多个表达式,如果任意一个表达式返回 true,则 or 返回 true,否则返回 false

API 说明

语法如下:

  1. db.command.aggregate.or([<expression1>, <expression2>, ...])

如果表达式返回 falsenull0、或 undefined,表达式会解析为 false,否则对其他返回值都认为是 true

示例代码

假设集合 price 有如下记录:

  1. { "_id": 1, "min": 10, "max": 100 }
  2. { "_id": 2, "min": 60, "max": 80 }
  3. { "_id": 3, "min": 30, "max": 50 }

min 小于 40 且 max 大于 60 的记录。

  1. const $ = db.command.aggregate
  2. db.collection('price').aggregate()
  3. .project({
  4. fullfilled: $.or([$.lt(['$min', 30]), $.gt(['$max', 60])])
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "fullfilled": true }
  2. { "_id": 2, "fullfilled": false }
  3. { "_id": 3, "fullfilled": true }

比较操作符

cmp

聚合操作符。给定两个值,返回其比较值:

API 说明

如果第一个值小于第二个值,返回 -1如果第一个值大于第二个值,返回 1如果两个值相等,返回 0

语法如下:

  1. db.command.aggregate.cmp([<expression1>, <expression2>])
示例代码

假设集合 price 有如下记录:

  1. { "_id": 1, "shop1": 10, "shop2": 100 }
  2. { "_id": 2, "shop1": 80, "shop2": 20 }
  3. { "_id": 3, "shop1": 50, "shop2": 50 }

shop1shop2 的各个物品的价格对比。

  1. const $ = db.command.aggregate
  2. db.collection('price').aggregate()
  3. .project({
  4. compare: $.cmp(['$shop1', '$shop2']))
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "compare": -1 }
  2. { "_id": 2, "compare": 1 }
  3. { "_id": 3, "compare": 0 }

eq

聚合操作符。匹配两个值,如果相等则返回 true,否则返回 false

API 说明

语法如下:

  1. db.command.aggregate.eq([<value1>, <value2>])
示例代码

假设集合 price 有如下记录:

  1. { "_id": 1, "value": 10 }
  2. { "_id": 2, "value": 80 }
  3. { "_id": 3, "value": 50 }

value 等于 50 的记录。

  1. const $ = db.command.aggregate
  2. db.collection('price').aggregate()
  3. .project({
  4. matched: $.eq(['$value', 50])
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "matched": false }
  2. { "_id": 2, "matched": false }
  3. { "_id": 3, "matched": true }

gt

聚合操作符。匹配两个值,如果前者大于后者则返回 true,否则返回 false

API 说明

语法如下:

  1. db.command.aggregate.gt([<value1>, <value2>])
示例代码

假设集合 price 有如下记录:

  1. { "_id": 1, "value": 10 }
  2. { "_id": 2, "value": 80 }
  3. { "_id": 3, "value": 50 }

判断 value 是否大于 50。

  1. const $ = db.command.aggregate
  2. db.collection('price').aggregate()
  3. .project({
  4. matched: $.gt(['$value', 50])
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "matched": false }
  2. { "_id": 2, "matched": true }
  3. { "_id": 3, "matched": false }

gte

聚合操作符。匹配两个值,如果前者大于或等于后者则返回 true,否则返回 false

API 说明

语法如下:

  1. db.command.aggregate.gte([<value1>, <value2>])
示例代码

假设集合 price 有如下记录:

  1. { "_id": 1, "value": 10 }
  2. { "_id": 2, "value": 80 }
  3. { "_id": 3, "value": 50 }

判断 value 是否大于或等于 50。

  1. const $ = db.command.aggregate
  2. db.collection('price').aggregate()
  3. .project({
  4. matched: $.gte(['$value', 50])
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "matched": false }
  2. { "_id": 2, "matched": true }
  3. { "_id": 3, "matched": true }

lt

聚合操作符。匹配两个值,如果前者小于后者则返回 true,否则返回 false

API 说明

语法如下:

  1. db.command.aggregate.lt([<value1>, <value2>])
示例代码

假设集合 price 有如下记录:

  1. { "_id": 1, "value": 10 }
  2. { "_id": 2, "value": 80 }
  3. { "_id": 3, "value": 50 }

判断 value 是否小于 50。

  1. const $ = db.command.aggregate
  2. db.collection('price').aggregate()
  3. .project({
  4. matched: $.lt(['$value', 50])
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "matched": true }
  2. { "_id": 2, "matched": false }
  3. { "_id": 3, "matched": false }

lte

聚合操作符。匹配两个值,如果前者小于或等于后者则返回 true,否则返回 false

API 说明

语法如下:

  1. db.command.aggregate.lte([<value1>, <value2>])
示例代码

假设集合 price 有如下记录:

  1. { "_id": 1, "value": 10 }
  2. { "_id": 2, "value": 80 }
  3. { "_id": 3, "value": 50 }

判断 value 是否小于 50。

  1. const $ = db.command.aggregate
  2. db.collection('price').aggregate()
  3. .project({
  4. matched: $.lte(['$value', 50])
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "matched": true }
  2. { "_id": 2, "matched": false }
  3. { "_id": 3, "matched": true }

neq

聚合操作符。匹配两个值,如果不相等则返回 true,否则返回 false

API 说明

语法如下:

  1. db.command.aggregate.neq([<value1>, <value2>])
示例代码

假设集合 price 有如下记录:

  1. { "_id": 1, "value": 10 }
  2. { "_id": 2, "value": 80 }
  3. { "_id": 3, "value": 50 }

value 不等于 50 的记录。

  1. const $ = db.command.aggregate
  2. db.collection('price').aggregate()
  3. .project({
  4. matched: $.neq(['$value', 50])
  5. })
  6. .end()

返回结果如下:

  1. { "_id": 1, "matched": true }
  2. { "_id": 2, "matched": true }
  3. { "_id": 3, "matched": false }

条件操作符

cond

聚合操作符。计算布尔表达式,返回指定的两个值其中之一。

API 说明

cond 的使用形式如下:

  1. cond({ if: <布尔表达式>, then: <真值>, else: <假值> })

或者:

  1. cond([ <布尔表达式>, <真值>, <假值> ])

两种形式中,三个参数(ifthenelse)都是必须的。

如果布尔表达式为真,那么 $cond 将会返回 <真值>,否则会返回 <假值>

示例代码

假设集合 items 的记录如下:

  1. { "_id": "0", "name": "item-a", "amount": 100 }
  2. { "_id": "1", "name": "item-b", "amount": 200 }
  3. { "_id": "2", "name": "item-c", "amount": 300 }

我们可以使用 cond,根据 amount 字段,来生成新的字段 discount

  1. const $ = db.command.aggregate
  2. db.collection('items').aggregate()
  3. .project({
  4. name: 1,
  5. discount: $.cond({
  6. if: $.gte(['$amount', 200]),
  7. then: 0.7,
  8. else: 0.9
  9. })
  10. })
  11. .end()

输出如下:

  1. { "_id": "0", "name": "item-a", "discount": 0.9 }
  2. { "_id": "1", "name": "item-b", "discount": 0.7 }
  3. { "_id": "2", "name": "item-c", "discount": 0.7 }

ifNull

聚合操作符。计算给定的表达式,如果表达式结果为 null、undefined 或者不存在,那么返回一个替代值;否则返回原值。

API 说明

ifNull 的使用形式如下:

  1. ifNull([ <表达式>, <替代值> ])
示例代码

假设集合 items 的记录如下:

  1. { "_id": "0", "name": "A", "description": "这是商品A" }
  2. { "_id": "1", "name": "B", "description": null }
  3. { "_id": "2", "name": "C" }

我们可以使用 ifNull,对不存在 desc 字段的文档,或者 desc 字段为 null 的文档,补充一个替代值。

  1. const $ = db.command.aggregate
  2. db.collection('items').aggregate()
  3. .project({
  4. _id: 0,
  5. name: 1,
  6. description: $.ifNull(['$description', '商品描述空缺'])
  7. })
  8. .end()

输出如下:

  1. { "name": "A", "description": "这是商品A" }
  2. { "name": "B", "description": "商品描述空缺" }
  3. { "name": "C", "description": "商品描述空缺" }

switch

聚合操作符。根据给定的 switch-case-default 计算返回值、

API 说明

switch 的使用形式如下:

  1. switch({
  2. branches: [
  3. case: <表达式>, then: <表达式>,
  4. case: <表达式>, then: <表达式>,
  5. ...
  6. ],
  7. default: <表达式>
  8. })
示例代码

假设集合 items 的记录如下:

  1. { "_id": "0", "name": "item-a", "amount": 100 }
  2. { "_id": "1", "name": "item-b", "amount": 200 }
  3. { "_id": "2", "name": "item-c", "amount": 300 }

我们可以使用 switch,根据 amount 字段,来生成新的字段 discount

  1. const $ = db.command.aggregate
  2. db.collection('items').aggregate()
  3. .project({
  4. name: 1,
  5. discount: $.switch({
  6. branches: [
  7. { case: $.gt(['$amount', 250]), then: 0.8 },
  8. { case: $.gt(['$amount', 150]), then: 0.9 }
  9. ],
  10. default: 1
  11. })
  12. })
  13. .end()

输出如下:

  1. { "_id": "0", "name": "item-a", "discount": 1 }
  2. { "_id": "1", "name": "item-b", "discount": 0.9 }
  3. { "_id": "2", "name": "item-c", "discount": 0.8 }

日期操作符

dateFromParts

聚合操作符。给定日期的相关信息,构建并返回一个日期对象。

平台差异说明

阿里云腾讯云
×
API 说明

语法如下:

  1. db.command.aggregate.dateFromParts({
  2. year: <year>,
  3. month: <month>,
  4. day: <day>,
  5. hour: <hour>,
  6. minute: <minute>,
  7. second: <second>,
  8. millisecond: <ms>,
  9. timezone: <tzExpression>
  10. })

你也可以使用 ISO 8601 的标准:

  1. db.command.aggregate.dateFromParts({
  2. isoWeekYear: <year>,
  3. isoWeek: <week>,
  4. isoDayOfWeek: <day>,
  5. hour: <hour>,
  6. minute: <minute>,
  7. second: <second>,
  8. millisecond: <ms>,
  9. timezone: <tzExpression>
  10. })

说明

示例代码
  1. const $ = db.command.aggregate
  2. db
  3. .collection('dates')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. date: $.dateFromParts({
  8. year: 2017,
  9. month: 2,
  10. day: 8,
  11. hour: 12,
  12. timezone: 'America/New_York'
  13. }),
  14. })
  15. .end()

输出如下:

  1. {
  2. "date": ISODate("2017-02-08T17:00:00.000Z")
  3. }

dateFromString

聚合操作符。将一个日期/时间字符串转换为日期对象

平台差异说明

阿里云腾讯云
×
API 说明

语法如下:

  1. db.command.aggregate.dateFromString({
  2. dateString: <dateStringExpression>,
  3. timezone: <tzExpression>
  4. })
示例代码
  1. const $ = db.command.aggregate
  2. db
  3. .collection('dates')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. date: $.dateFromString({
  8. dateString: "2019-05-14T09:38:51.686Z"
  9. })
  10. })
  11. .end()

输出如下:

  1. {
  2. "date": ISODate("2019-05-14T09:38:51.686Z")
  3. }

dateToString

聚合操作符。根据指定的表达式将日期对象格式化为符合要求的字符串。

平台差异说明

阿里云腾讯云
×
API 说明

dateToString 的调用形式如下:

  1. db.command.aggregate.dateToString({
  2. date: <日期表达式>,
  3. format: <格式化表达式>,
  4. timezone: <时区表达式>,
  5. onNull: <空值表达式>
  6. })

下面是四种表达式的详细说明:

名称描述
日期表达式必选。指定字段值应该是能转化为字符串的日期。
格式化表达式可选。它可以是任何包含“格式说明符”的有效字符串。
时区表达式可选。指明运算结果的时区。它可以解析格式为 UTC Offset 或者 Olson Timezone Identifier 的字符串。
空值表达式可选。当 <日期表达式> 返回空或者不存在的时候,会返回此表达式指明的值。

下面是格式说明符的详细说明:

说明符描述合法值
%d月份的日期(2位数,0填充)01 - 31
%GISO 8601 格式的年份0000 - 9999
%H小时(2位数,0填充,24小时制)00 - 23
%j一年中的一天(3位数,0填充)001 - 366
%L毫秒(3位数,0填充)000 - 999
%m月份(2位数,0填充)01 - 12
%M分钟(2位数,0填充)00 - 59
%S秒(2位数,0填充)00 - 60
%w星期几1 - 7
%uISO 8601 格式的星期几1 - 7
%U一年中的一周(2位数,0填充)00 - 53
%VISO 8601 格式的一年中的一周1 - 53
%Y年份(4位数,0填充)0000 - 9999
%z与 UTC 的时区偏移量+/-[hh][mm]
%Z以分钟为单位,与 UTC 的时区偏移量+/-mmm
%%百分号作为字符%
示例代码

假设集合 students 有如下记录:

  1. { "date": "1999-12-11T16:00:00.000Z", "firstName": "Yuanxin", "lastName": "Dong" }
  2. { "date": "1998-11-10T16:00:00.000Z", "firstName": "Weijia", "lastName": "Wang" }
  3. { "date": "1997-10-09T16:00:00.000Z", "firstName": "Chengxi", "lastName": "Li" }

格式化日期

下面是将 date 字段的值,格式化成形如 年份-月份-日期 的字符串:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. formatDate: $.dateToString({
  8. date: '$date',
  9. format: '%Y-%m-%d'
  10. })
  11. })
  12. .end()

返回的结果如下:

  1. { "formatDate": "1999-12-11" }
  2. { "formatDate": "1998-11-10" }
  3. { "formatDate": "1997-10-09" }

时区时间

下面是将 date 字段值格式化为上海时区时间的例子:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. formatDate: $.dateToString({
  8. date: '$date',
  9. format: '%H:%M:%S',
  10. timezone: 'Asia/Shanghai'
  11. })
  12. })
  13. .end()

返回的结果如下:

  1. { "formatDate": "00:00:00" }
  2. { "formatDate": "00:00:00" }
  3. { "formatDate": "00:00:00" }

缺失情况的默认值

当指定的 <日期表达式> 返回空或者不存在的时候,可以设置缺失情况下的默认值:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. formatDate: $.dateToString({
  8. date: '$empty',
  9. onNull: 'null'
  10. })
  11. })
  12. .end()

返回的结果如下:

  1. { "formatDate": "null" }
  2. { "formatDate": "null" }
  3. { "formatDate": "null" }

dayOfMonth

聚合操作符。返回日期字段对应的天数(一个月中的哪一天),是一个介于 1 至 31 之间的数字。

API 说明

语法如下:

  1. db.command.aggregate.dayOfMonth(<日期字段>)
示例代码

假设集合 dates 有以下文档:

  1. {
  2. "_id": 1,
  3. "date": ISODate("2019-05-14T09:38:51.686Z")
  4. }

我们使用 dayOfMonth()date 字段进行投影,获取对应的日期:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('dates')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. dayOfMonth: $.dayOfMonth('$date')
  8. })
  9. .end()

输出如下:

  1. {
  2. "dayOfMonth": 14
  3. }

dayOfWeek

聚合操作符。返回日期字段对应的天数(一周中的第几天),是一个介于 1(周日)到 7(周六)之间的整数。

API 说明

注意:周日是每周的第 1 天*

语法如下:

  1. db.command.aggregate.dayOfWeek(<日期字段>)
示例代码

假设集合 dates 有以下文档:

  1. {
  2. "_id": 1,
  3. "date": ISODate("2019-05-14T09:38:51.686Z")
  4. }

我们使用 dayOfWeek()date 字段进行投影,获取对应的天数(一周中的第几天):

  1. const $ = db.command.aggregate
  2. db
  3. .collection('dates')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. dayOfWeek: $.dayOfWeek('$date')
  8. })
  9. .end()

输出如下:

  1. {
  2. "dayOfWeek": 3
  3. }

dayOfYear

聚合操作符。返回日期字段对应的天数(一年中的第几天),是一个介于 1 到 366 之间的整数。

API 说明

语法如下:

  1. db.command.aggregate.dayOfYear(<日期字段>)
示例代码

假设集合 dates 有以下文档:

  1. {
  2. "_id": 1,
  3. "date": ISODate("2019-05-14T09:38:51.686Z")
  4. }

我们使用 dayOfYear()date 字段进行投影,获取对应的天数(一年中的第几天):

  1. const $ = db.command.aggregate
  2. db
  3. .collection('dates')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. dayOfYear: $.dayOfYear('$date')
  8. })
  9. .end()

输出如下:

  1. {
  2. "dayOfYear": 134
  3. }

hour

聚合操作符。返回日期字段对应的小时数,是一个介于 0 到 23 之间的整数。

API 说明

语法如下:

  1. db.command.aggregate.hour(<日期字段>)
示例代码

假设集合 dates 有以下文档:

  1. {
  2. "_id": 1,
  3. "date": ISODate("2019-05-14T09:38:51.686Z")
  4. }

我们使用 hour()date 字段进行投影,获取对应的小时数:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('dates')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. hour: $.hour('$date')
  8. })
  9. .end()

输出如下:

  1. {
  2. "hour": 9
  3. }

isoDayOfWeek

聚合操作符。返回日期字段对应的 ISO 8601 标准的天数(一周中的第几天),是一个介于 1(周一)到 7(周日)之间的整数。

API 说明

语法如下:

  1. db.command.aggregate.month(<日期字段>)
示例代码

假设集合 dates 有以下文档:

  1. {
  2. "_id": 1,
  3. "date": ISODate("2019-05-14T09:38:51.686Z")
  4. }

我们使用 month()date 字段进行投影,获取对应的 ISO 8601 标准的天数(一周中的第几天):

  1. const $ = db.command.aggregate
  2. db
  3. .collection('dates')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. isoDayOfWeek: $.isoDayOfWeek('$date')
  8. })
  9. .end()

输出如下:

  1. {
  2. "isoDayOfWeek": 2
  3. }

isoWeek

聚合操作符。返回日期字段对应的 ISO 8601 标准的周数(一年中的第几周),是一个介于 1 到 53 之间的整数。

API 说明

根据 ISO 8601 标准,周一到周日视为一周,本年度第一个周四所在的那周,视为本年度的第 1 周。

例如:2016 年 1 月 7 日是那年的第一个周四,那么 2016.01.04(周一)到 2016.01.10(周日) 即为第 1 周。同理,2016 年 1 月 1 日的周数为 53。

语法如下:

  1. db.command.aggregate.isoWeek(<日期字段>)
示例代码

假设集合 dates 有以下文档:

  1. {
  2. "_id": 1,
  3. "date": ISODate("2019-05-14T09:38:51.686Z")
  4. }

我们使用 isoWeek()date 字段进行投影,获取对应的 ISO 8601 标准的周数(一年中的第几周):

  1. const $ = db.command.aggregate
  2. db
  3. .collection('dates')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. isoWeek: $.isoWeek('$date')
  8. })
  9. .end()

输出如下:

  1. {
  2. "isoWeek": 20
  3. }

isoWeekYear

聚合操作符。返回日期字段对应的 ISO 8601 标准的天数(一年中的第几天)。

API 说明

此处的“年”以第一周的周一为开始,以最后一周的周日为结束。

语法如下:

  1. db.command.aggregate.isoWeekYear(<日期字段>)
示例代码

假设集合 dates 有以下文档:

  1. {
  2. "_id": 1,
  3. "date": ISODate("2019-05-14T09:38:51.686Z")
  4. }

我们使用 isoWeekYear()date 字段进行投影,获取对应的 ISO 8601 标准的天数(一年中的第几天):

  1. const $ = db.command.aggregate
  2. db
  3. .collection('dates')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. isoWeekYear: $.isoWeekYear('$date')
  8. })
  9. .end()

输出如下:

  1. {
  2. "isoWeekYear": 2019
  3. }

millisecond

聚合操作符。返回日期字段对应的毫秒数,是一个介于 0 到 999 之间的整数。

API 说明

语法如下:

  1. db.command.aggregate.millisecond(<日期字段>)
示例代码

假设集合 dates 有以下文档:

  1. {
  2. "_id": 1,
  3. "date": ISODate("2019-05-14T09:38:51.686Z")
  4. }

我们使用 millisecond()date 字段进行投影,获取对应的毫秒数:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('dates')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. millisecond: $.millisecond('$date'),
  8. })
  9. .end()

输出如下:

  1. {
  2. "millisecond": 686
  3. }

minute

聚合操作符。返回日期字段对应的分钟数,是一个介于 0 到 59 之间的整数。

API 说明

语法如下:

  1. db.command.aggregate.minute(<日期字段>)
示例代码

假设集合 dates 有以下文档:

  1. {
  2. "_id": 1,
  3. "date": ISODate("2019-05-14T09:38:51.686Z")
  4. }

我们使用 minute()date 字段进行投影,获取对应的分钟数:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('dates')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. minute: $.minute('$date')
  8. })
  9. .end()

输出如下:

  1. {
  2. "minute": 38
  3. }

month

聚合操作符。返回日期字段对应的月份,是一个介于 1 到 12 之间的整数。

API 说明

语法如下:

  1. db.command.aggregate.month(<日期字段>)
示例代码

假设集合 dates 有以下文档:

  1. {
  2. "_id": 1,
  3. "date": ISODate("2019-05-14T09:38:51.686Z")
  4. }

我们使用 month()date 字段进行投影,获取对应的月份:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('dates')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. month: $.month('$date')
  8. })
  9. .end()

输出如下:

  1. {
  2. "month": 5
  3. }

second

聚合操作符。返回日期字段对应的秒数,是一个介于 0 到 59 之间的整数,在特殊情况下(闰秒)可能等于 60。

API 说明

语法如下:

  1. db.command.aggregate.second(<日期字段>)
示例代码

假设集合 dates 有以下文档:

  1. {
  2. "_id": 1,
  3. "date": ISODate("2019-05-14T09:38:51.686Z")
  4. }

我们使用 second()date 字段进行投影,获取对应的秒数:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('dates')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. second: $.second('$date')
  8. })
  9. .end()

输出如下:

  1. {
  2. "second": 51
  3. }

week

聚合操作符。返回日期字段对应的周数(一年中的第几周),是一个介于 0 到 53 之间的整数。

API 说明

每周以周日为开头,每年的第一个周日即为 week 1 的开始,这天之前是 week 0

语法如下:

  1. db.command.aggregate.week(<日期字段>)
示例代码

假设集合 dates 有以下文档:

  1. {
  2. "_id": 1,
  3. "date": ISODate("2019-05-14T09:38:51.686Z")
  4. }

我们使用 week()date 字段进行投影,获取对应的周数(一年中的第几周):

  1. const $ = db.command.aggregate
  2. db
  3. .collection('dates')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. week: $.week('$date')
  8. })
  9. .end()

输出如下:

  1. {
  2. "week": 19
  3. }

year

聚合操作符。返回日期字段对应的年份。

API 说明

语法如下:

  1. db.command.aggregate.year(<日期字段>)
示例代码

假设集合 dates 有以下文档:

  1. {
  2. "_id": 1,
  3. "date": ISODate("2019-05-14T09:38:51.686Z")
  4. }

我们使用 year()date 字段进行投影,获取对应的年份:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('dates')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. year: $.year('$date')
  8. })
  9. .end()

输出如下:

  1. {
  2. "year": 2019
  3. }

subtract

subtract

常量操作符

literal

聚合操作符。直接返回一个值的字面量,不经过任何解析和处理。

API 说明

literal 使用形式如下:

  1. literal(<值>)

如果 <值> 是一个表达式,那么 literal 不会解析或者计算这个表达式,而是直接返回这个表达式。

示例代码

比如我们有一个 items 集合,其中数据如下:

  1. { "_id": "0", "price": "$1" }
  2. { "_id": "1", "price": "$5.60" }
  3. { "_id": "2", "price": "$8.90" }

以字面量的形式使用 $

下面的代码使用 literal,生成了一个新的字段 isOneDollar,表示 price 字段是否严格等于 "$1"

注意:我们这里无法使用 eq(['$price', '$1']),因为 "$1" 是一个表达式,代表 "1" 字段对应的值,而不是字符串字面量 "$1"

  1. const $ = db.command.aggregate
  2. db.collection('items').aggregate()
  3. .project({
  4. isOneDollar: $.eq(['$price', $.literal('$1')])
  5. })
  6. .end()

输出如下:

  1. { "_id": "0", "isOneDollar": true }
  2. { "_id": "1", "isOneDollar": false }
  3. { "_id": "2", "isOneDollar": false }

投影一个字段,对应的值为 1

下面的代码使用 literal,投影了一个新的字段 amount,其值为 1

  1. const $ = db.command.aggregate
  2. db.collection('items').aggregate()
  3. .project({
  4. price: 1,
  5. amount: $.literal(1)
  6. })
  7. .end()

输出如下:

  1. { "_id": "0", "price": "$1", "amount": 1 }
  2. { "_id": "1", "price": "$5.60", "amount": 1 }
  3. { "_id": "2", "price": "$8.90", "amount": 1 }

对象操作符

mergeObjects

聚合操作符。将多个文档合并为单个文档。

平台差异说明

阿里云腾讯云
×
API 说明

使用形式如下:在 group() 中使用时:

  1. mergeObjects(<document>)

在其它表达式中使用时:

  1. mergeObjects([<document1>, <document2>, ...])
示例代码

搭配 group() 使用

假设集合 sales 存在以下文档:

  1. { "_id": 1, "year": 2018, "name": "A", "volume": { "2018Q1": 500, "2018Q2": 500 } }
  2. { "_id": 2, "year": 2017, "name": "A", "volume": { "2017Q1": 400, "2017Q2": 300, "2017Q3": 0, "2017Q4": 0 } }
  3. { "_id": 3, "year": 2018, "name": "B", "volume": { "2018Q1": 100 } }
  4. { "_id": 4, "year": 2017, "name": "B", "volume": { "2017Q3": 100, "2017Q4": 250 } }

下面的代码使用 mergeObjects(),将用相同 name 的文档合并:

  1. const $ = db.command.aggregate
  2. db.collection('sales').aggregate()
  3. .group({
  4. _id: '$name',
  5. mergedVolume: $.mergeObjects('$volume')
  6. })
  7. .end()

输出如下:

  1. { "_id": "A", "mergedVolume": { "2017Q1": 400, "2017Q2": 300, "2017Q3": 0, "2017Q4": 0, "2018Q1": 500, "2018Q2": 500 } }
  2. { "_id": "B", "mergedVolume": { "2017Q3": 100, "2017Q4": 250, "2018Q1": 100 } }

一般用法

假设集合 test 存在以下文档:

  1. { "_id": 1, "foo": { "a": 1 }, "bar": { "b": 2 } }
  2. { "_id": 2, "foo": { "c": 1 }, "bar": { "d": 2 } }
  3. { "_id": 3, "foo": { "e": 1 }, "bar": { "f": 2 } }

下面的代码使用 mergeObjects(),将文档中的 foobar 字段合并为 foobar

  1. const $ = db.command.aggregate
  2. db.collection('sales').aggregate()
  3. .project({
  4. foobar: $.mergeObjects(['$foo', '$bar'])
  5. })
  6. .end()

输出结果如下:

  1. { "_id": 1, "foobar": { "a": 1, "b": 2 } }
  2. { "_id": 2, "foobar": { "c": 1, "d": 2 } }
  3. { "_id": 3, "foobar": { "e": 1, "f": 2 } }

objectToArray

objectToArray

集合操作符

allElementsTrue

聚合操作符。输入一个数组,或者数组字段的表达式。如果数组中所有元素均为真值,那么返回 true,否则返回 false。空数组永远返回 true

API 说明

语法如下:

  1. allElementsTrue([<expression>])
示例代码

假设集合 test 有如下记录:

  1. { "_id": 1, "array": [ true ] }
  2. { "_id": 2, "array": [ ] }
  3. { "_id": 3, "array": [ false ] }
  4. { "_id": 4, "array": [ true, false ] }
  5. { "_id": 5, "array": [ 0 ] }
  6. { "_id": 6, "array": [ "stark" ] }

下面的代码使用 allElementsTrue(),判断 array 字段中是否均为真值:

  1. const $ = db.command.aggregate
  2. db.collection('price')
  3. .aggregate()
  4. .project({
  5. isAllTrue: $.allElementsTrue(['$array'])
  6. })
  7. .end()

返回结果如下:

  1. { "_id": 1, "isAllTrue": true }
  2. { "_id": 2, "isAllTrue": true }
  3. { "_id": 3, "isAllTrue": false }
  4. { "_id": 4, "isAllTrue": false }
  5. { "_id": 5, "isAllTrue": false }
  6. { "_id": 6, "isAllTrue": true }

anyElementTrue

聚合操作符。输入一个数组,或者数组字段的表达式。如果数组中任意一个元素为真值,那么返回 true,否则返回 false。空数组永远返回 false

API 说明

语法如下:

  1. anyElementTrue([<expression>])
示例代码

假设集合 test 有如下记录:

  1. { "_id": 1, "array": [ true ] }
  2. { "_id": 2, "array": [ ] }
  3. { "_id": 3, "array": [ false ] }
  4. { "_id": 4, "array": [ true, false ] }
  5. { "_id": 5, "array": [ 0 ] }
  6. { "_id": 6, "array": [ "stark" ] }

下面的代码使用 anyElementTrue(),判断 array 字段中是否含有真值:

  1. const $ = db.command.aggregate
  2. db.collection('price')
  3. .aggregate()
  4. .project({
  5. isAnyTrue: $.anyElementTrue(['$array'])
  6. })
  7. .end()

返回结果如下:

  1. { "_id": 1, "isAnyTrue": true }
  2. { "_id": 2, "isAnyTrue": false }
  3. { "_id": 3, "isAnyTrue": false }
  4. { "_id": 4, "isAnyTrue": true }
  5. { "_id": 5, "isAnyTrue": false }
  6. { "_id": 6, "isAnyTrue": true }

setDifference

聚合操作符,输入两个集合,输出只存在于第一个集合中的元素。

API 说明

使用形式如下:

  1. setDifference([<expression1>, <expression2>])
示例代码

假设集合 test 存在以下数据:

  1. { "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] }
  2. { "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] }
  3. { "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] }
  4. { "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] }
  5. { "_id": 5, "A": [ 1, 2 ], "B": [ ] }
  6. { "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] }
  7. { "_id": 7, "A": [ ], "B": [ ] }
  8. { "_id": 8, "A": [ ], "B": [ 1 ] }

下面的代码使用 setDifference,找到只存在于 B 中的数字:

  1. db.collection('test')
  2. .aggregate()
  3. .project({
  4. isBOnly: $.setDifference(['$B', '$A'])
  5. })
  6. .end()
  1. { "_id": 1, "isBOnly": [] }
  2. { "_id": 2, "isBOnly": [3] }
  3. { "_id": 3, "isBOnly": [3] }
  4. { "_id": 4, "isBOnly": [5] }
  5. { "_id": 5, "isBOnly": [] }
  6. { "_id": 6, "isBOnly": [{}, []] }
  7. { "_id": 7, "isBOnly": [] }
  8. { "_id": 8, "isBOnly": [1] }

setEquals

聚合操作符,输入两个集合,判断两个集合中包含的元素是否相同(不考虑顺序、去重)。

API 说明

使用形式如下:

  1. setEquals([<expression1>, <expression2>])
示例代码

假设集合 test 存在以下数据:

  1. { "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] }
  2. { "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] }
  3. { "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] }
  4. { "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] }
  5. { "_id": 5, "A": [ 1, 2 ], "B": [ ] }
  6. { "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] }
  7. { "_id": 7, "A": [ ], "B": [ ] }
  8. { "_id": 8, "A": [ ], "B": [ 1 ] }

下面的代码使用 setEquals,判断两个集合中包含的元素是否相同:

  1. db.collection('test')
  2. .aggregate()
  3. .project({
  4. sameElements: $.setEquals(['$A', '$B'])
  5. })
  6. .end()
  1. { "_id": 1, "sameElements": true }
  2. { "_id": 2, "sameElements": true }
  3. { "_id": 3, "sameElements": false }
  4. { "_id": 4, "sameElements": false }
  5. { "_id": 5, "sameElements": false }
  6. { "_id": 6, "sameElements": false }
  7. { "_id": 7, "sameElements": true }
  8. { "_id": 8, "sameElements": false }

setIntersection

聚合操作符,输入两个集合,输出两个集合的交集。

API 说明

使用形式如下:

  1. setIntersection([<expression1>, <expression2>])
示例代码

假设集合 test 存在以下数据:

  1. { "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] }
  2. { "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] }
  3. { "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] }
  4. { "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] }
  5. { "_id": 5, "A": [ 1, 2 ], "B": [ ] }
  6. { "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] }
  7. { "_id": 7, "A": [ ], "B": [ ] }
  8. { "_id": 8, "A": [ ], "B": [ 1 ] }

下面的代码使用 setIntersection,输出两个集合的交集:

  1. db.collection('test')
  2. .aggregate()
  3. .project({
  4. commonToBoth: $.setIntersection(['$A', '$B'])
  5. })
  6. .end()

输出如下:

  1. { "_id": 1, "commonToBoth": [ 1, 2 ] }
  2. { "_id": 2, "commonToBoth": [ 1, 2 ] }
  3. { "_id": 3, "commonToBoth": [ 1, 2 ] }
  4. { "_id": 4, "commonToBoth": [ 1 ] }
  5. { "_id": 5, "commonToBoth": [ ] }
  6. { "_id": 6, "commonToBoth": [ ] }
  7. { "_id": 7, "commonToBoth": [ ] }
  8. { "_id": 8, "commonToBoth": [ ] }

setIsSubset

聚合操作符,输入两个集合,判断第一个集合是否是第二个集合的子集。

API 说明

使用形式如下:

  1. setIsSubset([<expression1>, <expression2>])
示例代码

假设集合 test 存在以下数据:

  1. { "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] }
  2. { "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] }
  3. { "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] }
  4. { "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] }
  5. { "_id": 5, "A": [ 1, 2 ], "B": [ ] }
  6. { "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] }
  7. { "_id": 7, "A": [ ], "B": [ ] }
  8. { "_id": 8, "A": [ ], "B": [ 1 ] }

下面的代码使用 setIsSubset,判断第一个集合是否是第二个集合的子集:

  1. db.collection('test')
  2. .aggregate()
  3. .project({
  4. AisSubsetOfB: $.setIsSubset(['$A', '$B'])
  5. })
  6. .end()
  1. { "_id": 1, "AisSubsetOfB": true }
  2. { "_id": 2, "AisSubsetOfB": true }
  3. { "_id": 3, "AisSubsetOfB": true }
  4. { "_id": 4, "AisSubsetOfB": false }
  5. { "_id": 5, "AisSubsetOfB": false }
  6. { "_id": 6, "AisSubsetOfB": false }
  7. { "_id": 7, "AisSubsetOfB": true }
  8. { "_id": 8, "AisSubsetOfB": true }

setUnion

聚合操作符,输入两个集合,输出两个集合的并集。

API 说明

使用形式如下:

  1. setUnion([<expression1>, <expression2>])
示例代码

假设集合 test 存在以下数据:

  1. { "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] }
  2. { "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] }
  3. { "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] }
  4. { "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] }
  5. { "_id": 5, "A": [ 1, 2 ], "B": [ ] }
  6. { "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] }
  7. { "_id": 7, "A": [ ], "B": [ ] }
  8. { "_id": 8, "A": [ ], "B": [ 1 ] }

下面的代码使用 setUnion,输出两个集合的并集:

  1. db.collection('test')
  2. .aggregate()
  3. .project({
  4. AB: $.setUnion(['$A', '$B'])
  5. })
  6. .end()

输出如下:

  1. { "_id": 1, "AB": [ 1, 2 ] }
  2. { "_id": 2, "AB": [ 1, 2 ] }
  3. { "_id": 3, "AB": [ 1, 2, 3 ] }
  4. { "_id": 4, "AB": [ 1, 2, 3 ] }
  5. { "_id": 5, "AB": [ 1, 2 ] }
  6. { "_id": 6, "AB": [ 1, 2, {}, [] ] }
  7. { "_id": 7, "AB": [ ] }
  8. { "_id": 8, "AB": [ 1 ] }

字符串操作符

concat

聚合操作符。连接字符串,返回拼接后的字符串。

API 说明

concat 的语法如下:

  1. db.command.aggregate.concat([<表达式1>, <表达式2>, ...])

表达式可以是形如 $ + 指定字段,也可以是普通字符串。只要能够被解析成字符串即可。

示例代码

假设集合 students 的记录如下:

  1. { "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }
  2. { "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }
  3. { "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }

借助 concat 可以拼接 lastNamefirstName 字段,得到每位学生的名字全称:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. fullName: $.concat(['$firstName', ' ', '$lastName'])
  8. })
  9. .end()

返回的结果如下:

  1. { "fullName": "Yuanxin Dong" }
  2. { "fullName": "Weijia Wang" }
  3. { "fullName": "Chengxi Li" }

dateFromString

dateFromString

dateToString

dateToString

indexOfBytes

聚合操作符。在目标字符串中查找子字符串,并返回第一次出现的 UTF-8 的字节索引(从0开始)。如果不存在子字符串,返回 -1。

API 说明

indexOfBytes 的语法如下:

  1. db.command.aggregate.indexOfBytes([<目标字符串表达式>, <子字符串表达式>, <开始位置表达式>, <结束位置表达式>])

下面是 4 种表达式的详细描述:

表达式描述
目标字符串表达式任何可以被解析为字符串的表达式
子字符串表达式任何可以被解析为字符串的表达式
开始位置表达式任何可以被解析为非负整数的表达式
结束位置表达式任何可以被解析为非负整数的表达式
示例代码

假设集合 students 的记录如下:

  1. { "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }
  2. { "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }
  3. { "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }

借助 indexOfBytes 查找字符 "a" 在字段 firstName 中的位置:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. aStrIndex: $.indexOfBytes(['$firstName', 'a'])
  8. })
  9. .end()

返回的结果如下:

  1. { "aStrIndex": 2 }
  2. { "aStrIndex": 5 }
  3. { "aStrIndex": -1 }

indexOfCP

聚合操作符。在目标字符串中查找子字符串,并返回第一次出现的 UTF-8code point 索引(从0开始)。如果不存在子字符串,返回 -1。

API 说明

code point 是“码位”,又名“编码位置”。这里特指 Unicode 包中的码位,范围是从0(16进制)到10FFFF(16进制)。

indexOfCP 的语法如下:

  1. db.command.aggregate.indexOfCP([<目标字符串表达式>, <子字符串表达式>, <开始位置表达式>, <结束位置表达式>])

下面是 4 种表达式的详细描述:

表达式描述
目标字符串表达式任何可以被解析为字符串的表达式
子字符串表达式任何可以被解析为字符串的表达式
开始位置表达式任何可以被解析为非负整数的表达式
结束位置表达式任何可以被解析为非负整数的表达式
示例代码

假设集合 students 的记录如下:

  1. { "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }
  2. { "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }
  3. { "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }

借助 indexOfCP 查找字符 "a" 在字段 firstName 中的位置:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. aStrIndex: $.indexOfCP(['$firstName', 'a'])
  8. })
  9. .end()

返回的结果如下:

  1. { "aStrIndex": 2 }
  2. { "aStrIndex": 5 }
  3. { "aStrIndex": -1 }

split

聚合操作符。按照分隔符分隔数组,并且删除分隔符,返回子字符串组成的数组。如果字符串无法找到分隔符进行分隔,返回原字符串作为数组的唯一元素。

API 说明

split 的语法如下:

  1. db.command.aggregate.split([<字符串表达式>, <分隔符表达式>])

字符串表达式和分隔符表达式可以是任意形式的表达式,只要它可以被解析为字符串即可。

示例代码

假设集合 students 的记录如下:

  1. { "birthday": "1999/12/12" }
  2. { "birthday": "1998/11/11" }
  3. { "birthday": "1997/10/10" }

通过 split 将每条记录中的 birthday 字段对应值分隔成数组,每个数组分别由代表年、月、日的3个元素组成:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. birthday: $.split(['$birthday', '/'])
  8. })
  9. .end()

返回的结果如下:

  1. { "birthday": [ "1999", "12", "12" ] }
  2. { "birthday": [ "1998", "11", "11" ] }
  3. { "birthday": [ "1997", "10", "10" ] }

strLenBytes

聚合操作符。计算并返回指定字符串中 utf-8 编码的字节数量。

API 说明

strLenBytes 的语法如下:

  1. db.command.aggregate.strLenBytes(<表达式>)

只要表达式可以被解析成字符串,那么它就是有效表达式。

示例代码

假设集合 students 的记录如下:

  1. { "name": "dongyuanxin", "nickname": "心谭" }

借助 strLenBytes 计算 name 字段和 nickname 字段对应值的字节长度:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. nameLength: $.strLenBytes('$name'),
  8. nicknameLength: $.strLenBytes('$nickname')
  9. })
  10. .end()

返回结果如下:

  1. { "nameLength": 11, "nicknameLength": 6 }

strLenCP

聚合操作符。计算并返回指定字符串的UTF-8 code points 数量。

API 说明

strLenCP 的语法如下:

  1. db.command.aggregate.strLenCP(<表达式>)

只要表达式可以被解析成字符串,那么它就是有效表达式。

示例代码

假设集合 students 的记录如下:

  1. { "name": "dongyuanxin", "nickname": "心谭" }

借助 strLenCP 计算 name 字段和 nickname 字段对应值的UTF-8 code points的数量:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. nameLength: $.strLenCP('$name'),
  8. nicknameLength: $.strLenCP('$nickname')
  9. })
  10. .end()

返回结果如下:

  1. { "nameLength": 11, "nicknameLength": 2 }

strcasecmp

聚合操作符。对两个字符串在不区分大小写的情况下进行大小比较,并返回比较的结果。

API 说明

strcasecmp 的语法如下:

  1. db.command.aggregate.strcasecmp([<表达式1>, <表达式2>])

只要 表达式1表达式2 可以被解析成字符串,那么它们就是有效的。

返回的比较结果有1,0和-1三种:

  • 1:表达式1 解析的字符串 > 表达式2 解析的字符串 - 0:表达式1 解析的字符串 = 表达式2 解析的字符串 - -1:表达式1 解析的字符串 < 表达式2 解析的字符串
示例代码

假设集合 students 的记录如下:

  1. { "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }
  2. { "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }
  3. { "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }

借助 strcasecmp 比较 firstName 字段值和 lastName 字段值的大小:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. result: $.strcasecmp(['$firstName', '$lastName']),
  8. })
  9. .end()

返回结果如下:

  1. { "result": 1 }
  2. { "result": 1 }
  3. { "result": -1 }

substr

聚合操作符。返回字符串从指定位置开始的指定长度的子字符串。它是 db.command.aggregate.substrBytes 的别名,更推荐使用后者。

API 说明

substr 的语法如下:

  1. db.command.aggregate.substr([<表达式1>, <表达式2>, <表达式3>])

表达式1 是任何可以解析为字符串的有效表达式,表达式2表达式3 是任何可以解析为数字的有效表达式。

如果 表达式2 是负数,返回的结果为 ""

如果 表达式3 是负数,返回的结果为从 表达式2 指定的开始位置以及之后其余部分的子字符串。

示例代码

假设集合 students 的记录如下:

  1. { "birthday": "1999/12/12", "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }
  2. { "birthday": "1998/11/11", "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }
  3. { "birthday": "1997/10/10", "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }

借助 substr 可以提取 birthday 中的年、月、日信息,代码如下:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. year: $.substr(['$birthday', 0, 4]),
  8. month: $.substr(['$birthday', 5, 2]),
  9. day: $.substr(['$birthday', 8, -1])
  10. })
  11. .end()

返回的结果如下:

  1. { "day": "12", "month": "12", "year": "1999" }
  2. { "day": "11", "month": "11", "year": "1998" }
  3. { "day": "10", "month": "10", "year": "1997" }

substrBytes

聚合操作符。返回字符串从指定位置开始的指定长度的子字符串。子字符串是由字符串中指定的 UTF-8 字节索引的字符开始,长度为指定的字节数。

API 说明

substrBytes 的语法如下:

  1. db.command.aggregate.substrBytes([<表达式1>, <表达式2>, <表达式3>])

表达式1 是任何可以解析为字符串的有效表达式,表达式2表达式3 是任何可以解析为数字的有效表达式。

如果 表达式2 是负数,返回的结果为 ""

如果 表达式3 是负数,返回的结果为从 表达式2 指定的开始位置以及之后其余部分的子字符串。

示例代码

假设集合 students 的记录如下:

  1. { "birthday": "1999/12/12", "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }
  2. { "birthday": "1998/11/11", "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }
  3. { "birthday": "1997/10/10", "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }

借助 substrBytes 可以提取 birthday 中的年、月、日信息,代码如下:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. year: $.substrBytes(['$birthday', 0, 4]),
  8. month: $.substrBytes(['$birthday', 5, 2]),
  9. day: $.substrBytes(['$birthday', 8, -1])
  10. })
  11. .end()

返回的结果如下:

  1. { "day": "12", "month": "12", "year": "1999" }
  2. { "day": "11", "month": "11", "year": "1998" }
  3. { "day": "10", "month": "10", "year": "1997" }

substrCP

聚合操作符。返回字符串从指定位置开始的指定长度的子字符串。子字符串是由字符串中指定的 UTF-8 字节索引的字符开始,长度为指定的字节数。

API 说明

substrCP 的语法如下:

  1. db.command.aggregate.substrCP([<表达式1>, <表达式2>, <表达式3>])

表达式1 是任何可以解析为字符串的有效表达式,表达式2表达式3 是任何可以解析为数字的有效表达式。

如果 表达式2 是负数,返回的结果为 ""

如果 表达式3 是负数,返回的结果为从 表达式2 指定的开始位置以及之后其余部分的子字符串。

示例代码

假设集合 students 的记录如下:

  1. { "name": "dongyuanxin", "nickname": "心谭" }

借助 substrCP 可以提取 nickname 字段值的第一个汉字:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. firstCh: $.substrCP(['$nickname', 0, 1])
  8. })
  9. .end()

返回的结果如下:

  1. { "firstCh": "心" }

toLower

聚合操作符。将字符串转化为小写并返回。

API 说明

toLower 的语法如下:

  1. db.command.aggregate.toLower(表达式)

只要表达式可以被解析成字符串,那么它就是有效表达式。例如:$ + 指定字段

示例代码

假设集合 students 的记录如下:

  1. { "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }
  2. { "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }
  3. { "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }

借助 toLowerfirstName 的字段值转化为小写:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. result: $.toLower('$firstName'),
  8. })
  9. .end()

返回的结果如下:

  1. { "result": "yuanxin" }
  2. { "result": "weijia" }
  3. { "result": "chengxi" }

toUpper

聚合操作符。将字符串转化为大写并返回。

API 说明

toUpper 的语法如下:

  1. db.command.aggregate.toUpper(表达式)

只要表达式可以被解析成字符串,那么它就是有效表达式。例如:$ + 指定字段

示例代码

假设集合 students 的记录如下:

  1. { "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }
  2. { "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }
  3. { "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }

借助 toUpperlastName 的字段值转化为大写:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .project({
  6. _id: 0,
  7. result: $.toUpper('$lastName'),
  8. })
  9. .end()

返回的结果如下:

  1. { "result": "DONG" }
  2. { "result": "WANG" }
  3. { "result": "LI" }

累计器操作符

addToSet

聚合操作符。聚合运算符。向数组中添加值,如果数组中已存在该值,不执行任何操作。它只能在 group stage 中使用。

API 说明

addToSet 语法如下:

  1. db.command.aggregate.addToSet(<表达式>)

表达式是形如 $ + 指定字段 的字符串。如果指定字段的值是数组,那么整个数组会被当作一个元素。

示例代码

假设集合 passages 的记录如下:

  1. { "category": "web", "tags": [ "JavaScript", "CSS" ], "title": "title1" }
  2. { "category": "System", "tags": [ "C++", "C" ], "title": "title2" }

非数组字段

每条记录的 category 对应值的类型是非数组,利用 addToSet 统计所有分类:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('passages')
  4. .aggregate()
  5. .group({
  6. _id: null,
  7. categories: $.addToSet('$category')
  8. })
  9. .end()

返回的结果如下:

  1. { "_id": null, "categories": [ "System", "web" ] }

数组字段

每条记录的 tags 对应值的类型是数组,数组不会被自动展开:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('passages')
  4. .aggregate()
  5. .group({
  6. _id: null,
  7. tagsList: $.addToSet('$tags')
  8. })
  9. .end()

返回的结果如下:

  1. { "_id": null, "tagsList": [ [ "C++", "C" ], [ "JavaScript", "CSS" ] ] }

avg

聚合操作符。返回一组集合中,指定字段对应数据的平均值。

API 说明

avg 的语法如下:

  1. db.command.aggregate.avg(<number>)

avg 传入的值除了数字常量外,也可以是任何最终解析成一个数字的表达式。它会忽略非数字值。

示例代码

假设集合 students 的记录如下:

  1. { "group": "a", "name": "stu1", "score": 84 }
  2. { "group": "a", "name": "stu2", "score": 96 }
  3. { "group": "b", "name": "stu3", "score": 80 }
  4. { "group": "b", "name": "stu4", "score": 100 }

借助 avg 可以计算所有记录的 score 的平均值:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .group({
  6. _id: null,
  7. average: $.avg('$score')
  8. })
  9. .end()

返回的结果如下:

  1. { "_id": null, "average": 90 }

first

聚合操作符。返回指定字段在一组集合的第一条记录对应的值。仅当这组集合是按照某种定义排序( sort )后,此操作才有意义。

API 说明

first 的语法如下:

  1. db.command.aggregate.first(<表达式>)

表达式是形如 $ + 指定字段 的字符串。

first 只能在 group 阶段被使用,并且需要配合 sort 才有意义。

示例代码

假设集合 students 的记录如下:

  1. { "group": "a", "name": "stu1", "score": 84 }
  2. { "group": "a", "name": "stu2", "score": 96 }
  3. { "group": "b", "name": "stu3", "score": 80 }
  4. { "group": "b", "name": "stu4", "score": 100 }

如果需要得到所有记录中 score 的最小值,可以先将所有记录按照 score 排序,然后取出第一条记录的 first

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .sort({
  6. score: 1
  7. })
  8. .group({
  9. _id: null,
  10. min: $.first('$score')
  11. })
  12. .end()

返回的数据结果如下:

  1. { "_id": null, "min": 80 }

last

聚合操作符。返回指定字段在一组集合的最后一条记录对应的值。仅当这组集合是按照某种定义排序( sort )后,此操作才有意义。

API 说明

last 的语法如下:

  1. db.command.aggregate.last(<表达式>)

表达式是形如 $ + 指定字段 的字符串。

last 只能在 group 阶段被使用,并且需要配合 sort 才有意义。

示例代码

假设集合 students 的记录如下:

  1. { "group": "a", "name": "stu1", "score": 84 }
  2. { "group": "a", "name": "stu2", "score": 96 }
  3. { "group": "b", "name": "stu3", "score": 80 }
  4. { "group": "b", "name": "stu4", "score": 100 }

如果需要得到所有记录中 score 的最大值,可以先将所有记录按照 score 排序,然后取出最后一条记录的 last

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .sort({
  6. score: 1
  7. })
  8. .group({
  9. _id: null,
  10. max: $.last('$score')
  11. })
  12. .end()

返回的数据结果如下:

  1. { "_id": null, "max": 100 }

max

聚合操作符。返回一组数值的最大值。

API 说明

max 的语法如下:

  1. db.command.aggregate.max(<表达式>)

表达式是形如 $ + 指定字段 的字符串。

示例代码

假设集合 students 的记录如下:

  1. { "group": "a", "name": "stu1", "score": 84 }
  2. { "group": "a", "name": "stu2", "score": 96 }
  3. { "group": "b", "name": "stu3", "score": 80 }
  4. { "group": "b", "name": "stu4", "score": 100 }

借助 max 可以统计不同组( group )中成绩的最高值,代码如下:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .group({
  6. _id: '$group',
  7. maxScore: $.max('$score')
  8. })
  9. .end()

返回的数据结果如下:

  1. { "_id": "b", "maxScore": 100 }
  2. { "_id": "a", "maxScore": 96 }
  3. ```.

mergeObjects

mergeObjects

min

聚合操作符。返回一组数值的最小值。

API 说明

min 的语法如下:

  1. db.command.aggregate.min(<表达式>)

表达式是形如 $ + 指定字段 的字符串。

示例代码

假设集合 students 的记录如下:

  1. { "group": "a", "name": "stu1", "score": 84 }
  2. { "group": "a", "name": "stu2", "score": 96 }
  3. { "group": "b", "name": "stu3", "score": 80 }
  4. { "group": "b", "name": "stu4", "score": 100 }

借助 min 可以统计不同组( group )中成绩的最低值,代码如下:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .group({
  6. _id: '$group',
  7. minScore: $.min('$score')
  8. })
  9. .end()

返回的数据结果如下:

  1. { "_id": "b", "minScore": 80 }
  2. { "_id": "a", "minScore": 84 }

push

聚合操作符。在 group 阶段,返回一组中表达式指定列与对应的值,一起组成的数组。

API 说明

push 语法如下:

  1. db.command.aggregate.push({
  2. <字段名1>: <指定字段1>,
  3. <字段名2>: <指定字段2>,
  4. ...
  5. })
示例代码

假设集合 students 的记录如下:

  1. { "group": "a", "name": "stu1", "score": 84 }
  2. { "group": "a", "name": "stu2", "score": 96 }
  3. { "group": "b", "name": "stu3", "score": 80 }
  4. { "group": "b", "name": "stu4", "score": 100 }

借助 push 操作,对不同分组( group )的所有记录,聚合所有数据并且将其放入一个新的字段中,进一步结构化和语义化数据。

  1. const $ = db.command.aggregate
  2. db
  3. .collection('students')
  4. .aggregate()
  5. .group({
  6. _id: '$group',
  7. students: $.push({
  8. name: '$name',
  9. score: '$score'
  10. })
  11. })
  12. .end()

输出结果如下:

  1. { "_id": "b", "students": [{ "name": "stu3", "score": 80 }, { "name": "stu4", "score": 100 }] }
  2. { "_id": "a", "students": [{ "name": "stu1", "score": 84 }, { "name": "stu2", "score": 96 }] }

stdDevPop

聚合操作符。返回一组字段对应值的标准差。

API 说明

stdDevPop 的使用形式如下:

  1. db.command.aggregate.stdDevPop(<表达式>)

表达式传入的是指定字段,指定字段对应的值的数据类型必须是 number ,否则结果会返回 null

示例代码

假设集合 students 的记录如下:a 组同学的成绩分别是84和96,b组同学的成绩分别是80和100。

  1. { "group":"a", "score":84 }
  2. { "group":"a", "score":96 }
  3. { "group":"b", "score":80 }
  4. { "group":"b", "score":100 }

可以用 stdDevPop 来分别计算 ab 两组同学成绩的标准差,以此来比较哪一组同学的成绩更稳定。代码如下:

  1. const $ = db.command.aggregate
  2. db.collection('students').aggregate()
  3. .group({
  4. _id: '$group',
  5. stdDev: $.stdDevPop('$score')
  6. })
  7. .end()

返回的数据结果如下:

  1. { "_id": "b", "stdDev": 10 }
  2. { "_id": "a", "stdDev": 6 }

stdDevSamp

聚合操作符。计算输入值的样本标准偏差。如果输入值代表数据总体,或者不概括更多的数据,请改用 db.command.aggregate.stdDevPop

API 说明

stdDevSamp 的使用形式如下:

  1. db.command.aggregate.stdDevSamp(<表达式>)

表达式传入的是指定字段,stdDevSamp 会自动忽略非数字值。如果指定字段所有的值均是非数字,那么结果返回 null

示例代码

假设集合 students 的记录如下:

  1. { "score": 80 }
  2. { "score": 100 }

可以用 stdDevSamp 来计算成绩的标准样本偏差。代码如下:

  1. const $ = db.command.aggregate
  2. db.collection('students').aggregate()
  3. .group({
  4. _id: null,
  5. ageStdDev: $.stdDevSamp('$score')
  6. })
  7. .end()

返回的数据结果如下:

  1. { "_id": null, "ageStdDev": 14.142135623730951 }

如果向集合 students 添加一条新记录,它的 score 字段类型是 string

  1. { "score": "aa" }

用上面代码计算标准样本偏差时,stdDevSamp 会自动忽略类型不为 number 的记录,返回结果保持不变。

sum

聚合操作符。计算并且返回一组字段所有数值的总和。

API 说明

sum 的使用形式如下:

  1. db.command.aggregate.sum(<表达式>)

表达式可以传入指定字段,也可以传入指定字段组成的列表。sum 会自动忽略非数字值。如果字段下的所有值均是非数字,那么结果返回 0。若传入数字常量,则当做所有记录该字段的值都给给定常量,在聚合时相加,最终值为输入记录数乘以常量。

示例代码

假设代表商品的集合 goods 的记录如下:price 代表商品销售额,cost 代表商品成本

  1. { "cost": -10, "price": 100 }
  2. { "cost": -15, "price": 1 }
  3. { "cost": -10, "price": 10 }

单独字段

借助 sum 可以计算所有商品的销售总和,代码如下:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('goods')
  4. .aggregate()
  5. .group({
  6. _id: null,
  7. totalPrice: $.sum('$price')
  8. })
  9. .end()

返回的数据结果如下:销售额是 111

  1. { "_id": null, "totalPrice": 111 }

字段列表

如果需要计算所有商品的利润总额,那么需要将每条记录的 costprice 相加得到此记录对应商品的利润。最后再计算所有商品的利润总额。

借助 sum,代码如下:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('goods')
  4. .aggregate()
  5. .group({
  6. _id: null,
  7. totalProfit: $.sum(
  8. $.sum(['$price', '$cost'])
  9. )
  10. })
  11. .end()

返回的数据结果如下:利润总额为 76

  1. { "_id": null, "totalProfit": 76 }

变量操作符

let

聚合操作符。自定义变量,并且在指定表达式中使用,返回的结果是表达式的结果。

API 说明

let 的语法如下:

  1. db.command.aggregate.let({
  2. vars: {
  3. <变量1>: <变量表达式>,
  4. <变量2>: <变量表达式>,
  5. ...
  6. },
  7. in: <结果表达式>
  8. })

vars 中可以定义多个变量,变量的值由 变量表达式 计算而来,并且被定义的变量只有在 in 中的 结果表达式 才可以访问。

in 的结果表达式中访问自定义变量时候,请在变量名前加上双美元符号( $$ )并用引号括起来。

示例代码

假设代表商品的集合 goods 的记录如下:price 代表商品价格,discount 代表商品折扣率,cost 代表商品成本

  1. { "cost": -10, "discount": 0.95, "price": 100 }
  2. { "cost": -15, "discount": 0.98, "price": 1 }
  3. { "cost": -10, "discount": 1, "price": 10 }

借助 let 可以定义并计算每件商品实际的销售价格,并将其赋值给自定义变量 priceTotal。最后再将 priceTotalcost 进行取和( sum )运算,得到每件商品的利润。

代码如下:

  1. const $ = db.command.aggregate
  2. db
  3. .collection('goods')
  4. .aggregate()
  5. .project({
  6. profit: $.let({
  7. vars: {
  8. priceTotal: $.multiply(['$price', '$discount'])
  9. },
  10. in: $.sum(['$$priceTotal', '$cost'])
  11. })
  12. })
  13. .end()

返回的数据结果如下:

  1. { "profit": 85 }
  2. { "profit": -14.02 }
  3. { "profit": 0 }

发现错误?想参与编辑?在 GitHub 上编辑此页面!