聚合操作符
算术操作符
abs
聚合操作符。返回一个数字的绝对值。
API 说明
语法如下:
db.command.aggregate.abs(<number>)
abs 传入的值除了数字常量外,也可以是任何最终解析成一个数字的表达式。
null 或者指向一个不存在的字段,则 abs 的结果是 null。如果值解析为 NaN,则结果是 NaN。
示例代码
ratings 有如下记录:
{ _id: 1, start: 5, end: 8 }{ _id: 2, start: 4, end: 4 }{ _id: 3, start: 9, end: 7 }{ _id: 4, start: 6, end: 7 }
start 和 end 之间的绝对差异大小:
const $ = db.command.aggregatedb.collection('ratings').aggregate() .project({ delta: $.abs($.subtract(['$start', '$end'])) }) .end()
返回结果如下:
{ "_id" : 1, "delta" : 3 }{ "_id" : 2, "delta" : 0 }{ "_id" : 3, "delta" : 2 }{ "_id" : 4, "delta" : 1 }
add
聚合操作符。将数字相加或将数字加在日期上。如果数组中的其中一个值是日期,那么其他值将被视为毫秒数加在该日期上。
API 说明
语法如下:
db.command.aggregate.add([<表达式1>, <表达式2>, ...])
$ + 指定字段,也可以是普通字符串。只要能够被解析成字符串即可。
示例代码
staff 有如下记录:
{ _id: 1, department: "x", sales: 5, engineer: 10, lastUpdate: ISODate("2019-05-01T00:00:00Z") }{ _id: 2, department: "y", sales: 10, engineer: 20, lastUpdate: ISODate("2019-05-01T02:00:00Z") }{ _id: 3, department: "z", sales: 20, engineer: 5, lastUpdate: ISODate("2019-05-02T03:00:00Z") }
数字求和 可以用如下方式求得各个记录人数总数:
const $ = db.command.aggregatedb.collection('staff').aggregate() .project({ department: 1, total: $.add(['$sales', '$engineer']) }) .end()
返回结果如下:
{ _id: 1, department: "x", total: 15 }{ _id: 2, department: "y", total: 30 }{ _id: 3, department: "z", total: 25 }
增加日期值
lastUpdate 加一个小时之后的值:
const $ = db.command.aggregatedb.collection('staff').aggregate() .project({ department: 1, lastUpdate: $.add(['$lastUpdate', 60*60*1000]) }) .end()
返回结果如下:
{ _id: 1, department: "x", lastUpdate: ISODate("2019-05-01T01:00:00Z") }{ _id: 2, department: "y", lastUpdate: ISODate("2019-05-01T03:00:00Z") }{ _id: 3, department: "z", lastUpdate: ISODate("2019-05-02T04:00:00Z") }
ceil
聚合操作符。向上取整,返回大于或等于给定数字的最小整数。
API 说明
语法如下:
db.command.aggregate.ceil(<number>)
<number> 可以是任意解析为数字的表达式。如果表达式解析为 null 或指向一个不存在的字段,则返回 null,如果解析为 NaN,则返回 NaN。
示例代码
sales 有如下记录:
{ _id: 1, sales: 5.2 }{ _id: 2, sales: 1.32 }{ _id: 3, sales: -3.2 }
可以用如下方式取各个数字的向上取整值:
const $ = db.command.aggregatedb.collection('sales').aggregate() .project({ sales: $.ceil('$sales') }) .end()
返回结果如下:
{ _id: 1, sales: 6 }{ _id: 2, sales: 2 }{ _id: 3, sales: -3 }
divide
聚合操作符。传入被除数和除数,求商。
API 说明
语法如下:
db.command.aggregate.divide([<被除数表达式>, <除数表达式>])
表达式可以是任意解析为数字的表达式。
示例代码
railroads 有如下记录:
{ _id: 1, meters: 5300 }{ _id: 2, meters: 64000 }{ _id: 3, meters: 130 }
可以用如下方式取各个数字转换为千米之后的值:
const $ = db.command.aggregatedb.collection('railroads').aggregate() .project({ km: $.divide(['$meters', 1000]) }) .end()
返回结果如下:
{ _id: 1, km: 5.3 }{ _id: 2, km: 64 }{ _id: 3, km: 0.13 }
exp
聚合操作符。取 e(自然对数的底数,欧拉数) 的 n 次方。
API 说明
语法如下:
db.command.aggregate.exp(<exponent>)
<exponent> 可以是任意解析为数字的表达式。如果表达式解析为 null 或指向一个不存在的字段,则返回 null,如果解析为 NaN,则返回 NaN。
示例代码
math 有如下记录:
{ _id: 1, exp: 0 }{ _id: 2, exp: 1 }{ _id: 3, exp: 2 }
const $ = db.command.aggregatedb.collection('math').aggregate() .project({ result: $.exp('$exp') }) .end()
返回结果如下:
{ _id: 1, result: 1 }{ _id: 2, result: 2.71828182845905 }{ _id: 3, result: 7.38905609893065 }
floor
聚合操作符。向下取整,返回大于或等于给定数字的最小整数。
API 说明
语法如下:
db.command.aggregate.floor(<number>)
<number> 可以是任意解析为数字的表达式。如果表达式解析为 null 或指向一个不存在的字段,则返回 null,如果解析为 NaN,则返回 NaN。
示例代码
sales 有如下记录:
{ _id: 1, sales: 5.2 }{ _id: 2, sales: 1.32 }{ _id: 3, sales: -3.2 }
可以用如下方式取各个数字的向下取整值:
const $ = db.command.aggregatedb.collection('sales').aggregate() .project({ sales: $.floor('$sales') }) .end()
返回结果如下:
{ _id: 1, sales: 5 }{ _id: 2, sales: 1 }{ _id: 3, sales: -6 }
ln
聚合操作符。计算给定数字在自然对数值。
API 说明
语法如下:
db.command.aggregate.ln(<number>)
<number> 可以是任意解析为非负数字的表达式。
ln 等价于 log([<number>, Math.E]),其中 Math.E 是 JavaScript 获取 e 的值的方法。
示例代码
db.command.aggregate.ln
聚合操作符。计算给定数字在自然对数值。 语法如下:
db.command.aggregate.ln(<number>)
<number> 可以是任意解析为非负数字的表达式。
ln 等价于 log([<number>, Math.E]),其中 Math.E 是 JavaScript 获取 e 的值的方法。
log
聚合操作符。计算给定数字在给定对数底下的 log 值。
API 说明
语法如下:
db.command.aggregate.log([<number>, <base>])
<number> 可以是任意解析为非负数字的表达式。<base> 可以是任意解析为大于 1 的数字的表达式。
null 或指向任意一个不存在的字段,log 返回 null。如果任一参数解析为 NaN,log 返回 NaN。
示例代码
curve 有如下记录:
{ _id: 1, x: 1 }{ _id: 2, x: 2 }{ _id: 3, x: 3 }
log2(x) 的值:
const $ = db.command.aggregatedb.collection('staff').aggregate() .project({ log: $.log(['$x', 2]) }) .end()
返回结果如下:
{ _id: 1, log: 0 }{ _id: 2, log: 1 }{ _id: 3, log: 1.58496250072 }
log10
聚合操作符。计算给定数字在对数底为 10 下的 log 值。
API 说明
语法如下:
db.command.aggregate.log(<number>)
<number> 可以是任意解析为非负数字的表达式。
log10 等同于 log 方法的第二个参数固定为 10。
示例代码
db.command.aggregate.log10
聚合操作符。计算给定数字在对数底为 10 下的 log 值。 语法如下:
db.command.aggregate.log(<number>)
<number> 可以是任意解析为非负数字的表达式。
log10 等同于 log 方法的第二个参数固定为 10。
mod
聚合操作符。取模运算,取数字取模后的值。
API 说明
语法如下:
db.command.aggregate.mod([<dividend>, <divisor>])
第一个数字是被除数,第二个数字是除数。参数可以是任意解析为数字的表达式。
示例代码
shopping 有如下记录:
{ _id: 1, bags: 3, items: 5 }{ _id: 2, bags: 2, items: 8 }{ _id: 3, bags: 5, items: 16 }
items 除以 bags 的余数(items % bags):
const $ = db.command.aggregatedb.collection('shopping').aggregate() .project({ overflow: $.mod(['$items', '$bags']) }) .end()
返回结果如下:
{ _id: 1, log: 2 }{ _id: 2, log: 0 }{ _id: 3, log: 1 }
multiply
聚合操作符。取传入的数字参数相乘的结果。
API 说明
语法如下:
db.command.aggregate.multiply([<expression1>, <expression2>, ...])
参数可以是任意解析为数字的表达式。
示例代码
fruits 有如下记录:
{ "_id": 1, "name": "apple", "price": 10, "quantity": 100 }{ "_id": 2, "name": "orange", "price": 15, "quantity": 50 }{ "_id": 3, "name": "lemon", "price": 5, "quantity": 20 }
求各个水果的的总价值:
const $ = db.command.aggregatedb.collection('fruits').aggregate() .project({ name: 1, total: $.multiply(['$price', '$quantity']), }) .end()
返回结果如下:
{ "_id": 1, "name": "apple", "total": 1000 }{ "_id": 2, "name": "orange", "total": 750 }{ "_id": 3, "name": "lemo", "total": 100 }
pow
聚合操作符。求给定基数的指数次幂。
API 说明
语法如下:
db.command.aggregate.pow([<base>, <exponent>])
参数可以是任意解析为数字的表达式。
示例代码
stats 有如下记录:
{ "_id": 1, "x": 2, "y": 3 }{ "_id": 2, "x": 5, "y": 7 }{ "_id": 3, "x": 10, "y": 20 }
x 和 y 的平方和:
const $ = db.command.aggregatedb.collection('stats').aggregate() .project({ sumOfSquares: $.add([$.pow(['$x', 2]), $.pow(['$y', 2])]), }) .end()
返回结果如下:
{ "_id": 1, "sumOfSquares": 13 }{ "_id": 2, "sumOfSquares": 74 }{ "_id": 3, "sumOfSquares": 500 }
sqrt
聚合操作符。求平方根。
API 说明
语法如下:
db.command.aggregate.sqrt([<number>])
参数可以是任意解析为非负数字的表达式。
示例代码
triangle 有如下记录:
{ "_id": 1, "x": 2, "y": 3 }{ "_id": 2, "x": 5, "y": 7 }{ "_id": 3, "x": 10, "y": 20 }
x 和 y 分别为两直角边,则求斜边长:
const $ = db.command.aggregatedb.collection('triangle').aggregate() .project({ len: $.sqrt([$.add([$.pow(['$x', 2]), $.pow(['$y', 2])])]), }) .end()
返回结果如下:
{ "_id": 1, "len": 3.605551275463989 }{ "_id": 2, "len": 8.602325267042627 }{ "_id": 3, "len": 22.360679774997898 }
subtract
聚合操作符。将两个数字相减然后返回差值,或将两个日期相减然后返回相差的毫秒数,或将一个日期减去一个数字返回结果的日期。
API 说明
语法如下:
db.command.aggregate.subtract([<expression1>, <expression2>])
参数可以是任意解析为数字或日期的表达式。
示例代码
scores 有如下记录:
{ "_id": 1, "max": 10, "min": 1 }{ "_id": 2, "max": 7, "min": 5 }{ "_id": 3, "max": 6, "min": 6 }
max 和 min 的差值。:
const $ = db.command.aggregatedb.collection('scores').aggregate() .project({ diff: $.subtract(['$max', '$min']) }) .end()
返回结果如下:
{ "_id": 1, "diff": 9 }{ "_id": 2, "diff": 2 }{ "_id": 3, "diff": 0 }
trunc
聚合操作符。将数字截断为整形。
API 说明
语法如下:
db.command.aggregate.trunc(<number>)
参数可以是任意解析为数字的表达式。
示例代码
scores 有如下记录:
{ "_id": 1, "value": 1.21 }{ "_id": 2, "value": 3.83 }{ "_id": 3, "value": -4.94 }
const $ = db.command.aggregatedb.collection('scores').aggregate() .project({ int: $.trunc('$value') }) .end()
返回结果如下:
{ "_id": 1, "value": 1 }{ "_id": 2, "value": 3 }{ "_id": 3, "value": -4 }
数组操作符
arrayElemAt
聚合操作符。返回在指定数组下标的元素。
API 说明
语法如下:
db.command.aggregate.arrayElemAt([<array>, <index>])
<array> 可以是任意解析为数字的表达式。
<index> 可以是任意解析为整形的表达式。如果是正数,arrayElemAt 返回在 index 位置的元素,如果是负数,arrayElemAt 返回从数组尾部算起的 index 位置的元素。
示例代码
exams 有如下记录:
{ "_id": 1, "scores": [80, 60, 65, 90] }{ "_id": 2, "scores": [78] }{ "_id": 3, "scores": [95, 88, 92] }
求各个第一次考试的分数和和最后一次的分数:
const $ = db.command.aggregatedb.collection('exams').aggregate() .project({ first: $.arraElemAt(['$scores', 0]), last: $.arraElemAt(['$scores', -1]), }) .end()
返回结果如下:
{ "_id": 1, "first": 80, "last": 90 }{ "_id": 2, "first": 78, "last": 78 }{ "_id": 3, "first": 95, "last": 92 }
arrayToObject
聚合操作符。将一个数组转换为对象。
API 说明
语法可以取两种: 第一种:传入一个二维数组,第二维的数组长度必须为 2,其第一个值为字段名,第二个值为字段值
db.command.aggregate.arrayToObject([ [<key1>, <value1>], [<key2>, <value2>], ...])
k 和 v,分别指定字段名和字段值
db.command.aggregate.arrayToObject([ { "k": <key1>, "v": <value1> }, { "k": <key2>, "v": <value2> }, ...])
arrayToObject 的参数只要可以解析为上述两种表示法之一即可。
示例代码
shops 有如下记录:
{ "_id": 1, "sales": [ ["max", 100], ["min", 50] ] }{ "_id": 2, "sales": [ ["max", 70], ["min", 60] ] }{ "_id": 3, "sales": [ { "k": "max", "v": 50 }, { "k": "min", "v": 30 } ] }
求各个第一次考试的分数和和最后一次的分数:
const $ = db.command.aggregatedb.collection('shops').aggregate() .project({ sales: $.arrayToObject('$sales'), }) .end()
返回结果如下:
{ "_id": 1, "sales": { "max": 100, "min": 50 } }{ "_id": 2, "sales": { "max": 70, "min": 60 } }{ "_id": 3, "sales": { "max": 50, "min": 30 } }
concatArrays
聚合操作符。将多个数组拼接成一个数组。
API 说明
语法如下:
db.command.aggregate.arrayToObject([ <array1>, <array2>, ... ])
参数可以是任意解析为数组的表达式。
示例代码
items 有如下记录:
{ "_id": 1, "fruits": [ "apple" ], "vegetables": [ "carrot" ] }{ "_id": 2, "fruits": [ "orange", "lemon" ], "vegetables": [ "cabbage" ] }{ "_id": 3, "fruits": [ "strawberry" ], "vegetables": [ "spinach" ] }
const $ = db.command.aggregatedb.collection('items').aggregate() .project({ list: $.concatArrays(['$fruits', '$vegetables']), }) .end()
返回结果如下:
{ "_id": 1, "list": [ "apple", "carrot" ] }{ "_id": 2, "list": [ "orange", "lemon", "cabbage" ] }{ "_id": 3, "list": [ "strawberry", "spinach" ] }
filter
聚合操作符。根据给定条件返回满足条件的数组的子集。
API 说明
语法如下:
db.command.aggregate.filter({ input: <array>, as: <string>, cond: <expression>})
参数可以是任意解析为数组的表达式。
示例代码
fruits 有如下记录:
{ "_id": 1, "stock": [ { "name": "apple", "price": 10 }, { "name": "orange", "price": 20 } ],}{ "_id": 2, "stock": [ { "name": "lemon", "price": 15 }, ],}
const _ = db.commandconst $ = db.command.aggregatedb.collection('fruits').aggregate() .project({ stock: $.filter({ input: '$stock', as: 'item', cond: $.gte(['$$item.price', 15]) }) }) .end()
返回结果如下:
{ "_id": 1, "stock": [ { "name": "orange", "price": 20} ] }{ "_id": 2, "stock": [ { "name": "lemon", "price": 15 } ] }
in
true,否则返回 false。
API 说明
语法如下:
db.command.aggregate.in([<value>, <array>])
<value> 可以是任意表达式。
<array> 可以是任意解析为数组的表达式。
示例代码
shops 有如下记录:
{ "_id": 1, "topsellers": ["bread", "ice cream", "butter"] }{ "_id": 2, "topsellers": ["ice cream", "cheese", "yagurt"] }{ "_id": 3, "topsellers": ["croissant", "cucumber", "coconut"] }
ice cream 的记录。
const $ = db.command.aggregatedb.collection('price').aggregate() .project({ included: $.in(['ice cream', '$topsellers']) }) .end()
返回结果如下:
{ "_id": 1, "included": true }{ "_id": 2, "included": true }{ "_id": 3, "included": false }
indexOfArray
聚合操作符。在数组中找出等于给定值的第一个元素的下标,如果找不到则返回 -1。
API 说明
语法如下:
db.command.aggregate.indexOfArray([ <array expression>, <search expression>, <start>, <end> ])
参数可以是任意解析为数组的表达式。
示例代码
stats 有如下记录:
{ "_id": 1, "sales": [ 1, 6, 2, 2, 5 ]}{ "_id": 2, "sales": [ 4, 2, 1, 5, 2 ]}{ "_id": 3, "sales": [ 2, 5, 3, 3, 1 ]}
const $ = db.command.aggregatedb.collection('stats').aggregate() .project({ index: $.indexOfArray(['$sales', 2, 2]) }) .end()
返回结果如下:
{ "_id": 1, "index": 2 }{ "_id": 2, "index": 4 }{ "_id": 3, "index": -1 }
isArray
聚合操作符。判断给定表达式是否是数组,返回布尔值。
API 说明
语法如下:
db.command.aggregate.isArray(<expression>)
参数可以是任意表达式。
示例代码
stats 有如下记录:
{ "_id": 1, "base": 10, "sales": [ 1, 6, 2, 2, 5 ]}{ "_id": 2, "base": 1, "sales": 100}
sales 是数字,则求 sales * base,如果 sales 是数组,则求数组元素之和与 base 的乘积。
const $ = db.command.aggregatedb.collection('stats').aggregate() .project({ sum: $.cond({ if: $.isArray('$sales'), then: $.multiply([$.sum(['$sales']), '$base']), else: $.multiply(['$sales', '$base']), }) }) .end()
返回结果如下:
{ "_id": 1, "index": 160 }{ "_id": 2, "index": 100 }
map
map 方法,将给定数组的每个元素按给定转换方法转换后得出新的数组。
API 说明
语法如下:
db.command.aggregate.map({ input: <expression>, as: <string>, in: <expression>})
示例代码
stats 有如下记录:
{ "_id": 1, "sales": [ 1.32, 6.93, 2.48, 2.82, 5.74 ]}{ "_id": 2, "sales": [ 2.97, 7.13, 1.58, 6.37, 3.69 ]}
将各个数字截断为整形,然后求和
const $ = db.command.aggregatedb.collection('stats').aggregate() .project({ truncated: $.map({ input: '$sales', as: 'num', in: $.trunc('$$num'), }) }) .project({ total: $.sum('$truncated') }) .end()
返回结果如下:
{ "_id": 1, "index": 16 }{ "_id": 2, "index": 19 }
objectToArray
{ k: <key>, v: <value> }。
API 说明
语法如下:
db.command.aggregate.objectToArray(<object>)
示例代码
items 有如下记录:
{ "_id": 1, "attributes": { "color": "red", "price": 150 } }{ "_id": 2, "attributes": { "color": "blue", "price": 50 } }{ "_id": 3, "attributes": { "color": "yellow", "price": 10 } }
const $ = db.command.aggregatedb.collection('items').aggregate() .project({ array: $.objectToArray('$attributes') }) .end()
返回结果如下:
{ "_id": 1, "array": [{ "k": "color", "v": "red" }, { "k": "price", "v": 150 }] }{ "_id": 2, "array": [{ "k": "color", "v": "blue" }, { "k": "price", "v": 50 }] }{ "_id": 3, "array": [{ "k": "color", "v": "yellow" }, { "k": "price", "v": 10 }] }
range
range 会返回从开始值开始逐步增长、步长为给定步长、但不包括结束值的序列。
API 说明
语法如下:
db.command.aggregate.range([<start>, <end>, <non-zero step>])
示例代码
stats 有如下记录:
{ "_id": 1, "max": 52 }{ "_id": 2, "max": 38 }
const $ = db.command.aggregatedb.collection('stats').aggregate() .project({ points: $.range([0, '$max', 10]) }) .end()
返回结果如下:
{ "_id": 1, "points": [0, 10, 20, 30, 40, 50] }{ "_id": 2, "points": [0, 10, 20] }
reduce
reduce 方法,应用一个表达式于数组各个元素然后归一成一个元素。
API 说明
语法如下:
db.command.aggregate.reduce({ input: <array> initialValue: <expression>, in: <expression>})
示例代码
简易字符串拼接
player 有如下记录:
{ "_id": 1, "fullname": [ "Stephen", "Curry" ] }{ "_id": 2, "fullname": [ "Klay", "Thompsom" ] }
Player: 前缀:
const $ = db.command.aggregatedb.collection('player').aggregate() .project({ info: $.reduce({ input: '$fullname', initialValue: 'Player:', in: $.concat(['$$value', ' ', '$$this']), }) }) .end()
返回结果如下:
{ "_id": 1, "info": "Player: Stephen Curry" }{ "_id": 2, "info": "Player: Klay Thompson" }
获取各个球员的全名,不加前缀:
const $ = db.command.aggregatedb.collection('player').aggregate() .project({ name: $.reduce({ input: '$fullname', initialValue: '', in: $.concat([ '$$value', $.cond({ if: $.eq(['$$value', '']), then: '', else: ' ', }), '$$this', ]), }) }) .end()
返回结果如下:
{ "_id": 1, "name": "Stephen Curry" }{ "_id": 2, "name": "Klay Thompson" }
reverseArray
聚合操作符。返回给定数组的倒序形式。
API 说明
语法如下:
db.command.aggregate.reverseArray(<array>)
参数可以是任意解析为数组表达式。
示例代码
stats 有如下记录:
{ "_id": 1, "sales": [ 1, 2, 3, 4, 5 ]}
sales 倒序:
const $ = db.command.aggregatedb.collection('stats').aggregate() .project({ reversed: $.reverseArray('$sales'), }) .end()
返回结果如下:
{ "_id": 1, "reversed": [5, 4, 3, 2, 1] }
size
聚合操作符。返回数组长度。
API 说明
语法如下:
db.command.aggregate.size(<array>)
<array> 可以是任意解析为数组的表达式。
示例代码
shops 有如下记录:
{ "_id": 1, "staff": [ "John", "Middleton", "George" ] }{ "_id": 2, "staff": [ "Steph", "Jack" ] }
计算各个商店的雇员数量:
const $ = db.command.aggregatedb.collection('staff').aggregate() .project({ totalStaff: $.size('$staff') }) .end()
返回结果如下:
{ "_id": 1, "totalStaff": 3 }{ "_id": 2, "totalStaff": 2 }
slice
slice 方法。返回给定数组的指定子集。
API 说明
语法有两种:
n 个元素:
db.command.aggregate.slice([<array>, <n>])
n 个元素:
db.command.aggregate.slice([<array>, <position>, <n>])
<array> 可以是任意解析为数组的表达式。
<position> 可以是任意解析为整形的表达式。如果是正数,则将数组的第 <position> 个元素作为数组开始;如果 <position> 比数组长度更长,slice 返回空数组。如果是负数,则将数组倒数第 <position> 个元素作为数组开始;如果 <position> 的绝对值大于数组长度,则开始位置即为数组开始位置。
<n> 可以是任意解析为整形的表达式。如果 <position> 有提供,则 <n> 必须为正整数。如果是正数,slice 返回前 n 个元素。如果是负数,slice 返回后 n 个元素。
示例代码
people 有如下记录:
{ "_id": 1, "hobbies": [ "basketball", "football", "tennis", "badminton" ] }{ "_id": 2, "hobbies": [ "golf", "handball" ] }{ "_id": 3, "hobbies": [ "table tennis", "swimming", "rowing" ] }
统一返回前两个爱好:
const $ = db.command.aggregatedb.collection('fruits').aggregate() .project({ hobbies: $.slice(['$hobbies', 2]), }) .end()
返回结果如下:
{ "_id": 1, "hobbies": [ "basketball", "football" ] }{ "_id": 2, "hobbies": [ "golf", "handball" ] }{ "_id": 3, "hobbies": [ "table tennis", "swimming" ] }
zip
[ [ 1, 2, 3 ], [ "a", "b", "c" ] ] 转换成 [ [ 1, "a" ], [ 2, "b" ], [ 3, "c" ] ]。
API 说明
语法如下:
db.command.aggregate.zip({ inputs: [<array1>, <array2>, ...], useLongestLength: <boolean>, defaults: <array>})
inputs 是一个二维数组(inputs 不可以是字段引用),其中每个元素的表达式(这个可以是字段引用)都可以解析为数组。如果其中任意一个表达式返回 null,<inputs> 也返回 null。如果其中任意一个表达式不是指向一个合法的字段 / 解析为数组 / 解析为 null,则返回错误。
useLongestLength 决定输出数组的长度是否采用输入数组中的最长数组的长度。默认为 false,即输入数组中的最短的数组的长度即是输出数组的各个元素的长度。
defaults 是一个数组,用于指定在输入数组长度不一的情况下时采用的数组各元素默认值。指定这个字段则必须指定 useLongestLength,否则返回错误。如果 useLongestLength 是 true 但是 defaults 是空或没有指定,则 zip 用 null 做数组元素的缺省默认值。指定各元素默认值时 defaults 数组的长度必须是输入数组最大的长度。
示例代码
stats 有如下记录:
{ "_id": 1, "zip1": [1, 2], "zip2": [3, 4], "zip3": [5, 6] ] }{ "_id": 2, "zip1": [1, 2], "zip2": [3], "zip3": [4, 5, 6] ] }{ "_id": 3, "zip1": [1, 2], "zip2": [3] ] }
只传 inputs
const $ = db.command.aggregatedb.collection('items').aggregate() .project({ zip: $.zip({ inputs: [ '$zip1', // 字段引用 '$zip2', '$zip3', ], }) }) .end()
返回结果如下:
{ "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] }{ "_id": 2, "zip": [ [1, 3, 4] ] }{ "_id": 3, "zip": null }
设置 useLongestLength
useLongestLength 为 true:
const $ = db.command.aggregatedb.collection('items').aggregate() .project({ zip: $.zip({ inputs: [ '$zip1', // 字段引用 '$zip2', '$zip3', ], useLongestLength: true, }) }) .end()
返回结果如下:
{ "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] }{ "_id": 2, "zip": [ [1, 3, 4], [2, null, 5], [null, null, 6] ] }{ "_id": 3, "zip": null }
设置 defaults
const $ = db.command.aggregatedb.collection('items').aggregate() .project({ zip: $.zip({ inputs: [ '$zip1', // 字段引用 '$zip2', '$zip3', ], useLongestLength: true, defaults: [-300, -200, -100], }) }) .end()
返回结果如下:
{ "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] }{ "_id": 2, "zip": [ [1, 3, 4], [2, -200, 5], [-300, -200, 6] ] }{ "_id": 3, "zip": null }
布尔操作符
and
and 仅在所有表达式都返回 true 时返回 true,否则返回 false。
API 说明
语法如下:
db.command.aggregate.and([<expression1>, <expression2>, ...])
false、null、0、或 undefined,表达式会解析为 false,否则对其他返回值都认为是 true。
示例代码
price 有如下记录:
{ "_id": 1, "min": 10, "max": 100 }{ "_id": 2, "min": 60, "max": 80 }{ "_id": 3, "min": 30, "max": 50 }
min 大于等于 30 且 max 小于等于 80 的记录。
const $ = db.command.aggregatedb.collection('price').aggregate() .project({ fullfilled: $.and([$.gte(['$min', 30]), $.lte(['$max', 80])]) }) .end()
返回结果如下:
{ "_id": 1, "fullfilled": false }{ "_id": 2, "fullfilled": true }{ "_id": 3, "fullfilled": true }
not
true,则 not 返回 false,否则返回 true。注意表达式不能为逻辑表达式(and、or、nor、not)。
API 说明
语法如下:
db.command.aggregate.not(<expression>)
false、null、0、或 undefined,表达式会解析为 false,否则对其他返回值都认为是 true。
示例代码
price 有如下记录:
{ "_id": 1, "min": 10, "max": 100 }{ "_id": 2, "min": 60, "max": 80 }{ "_id": 3, "min": 30, "max": 50 }
min 不大于 40 的记录。
const $ = db.command.aggregatedb.collection('price').aggregate() .project({ fullfilled: $.not($.gt(['$min', 40])) }) .end()
返回结果如下:
{ "_id": 1, "fullfilled": true }{ "_id": 2, "fullfilled": false }{ "_id": 3, "fullfilled": true }
or
true,则 or 返回 true,否则返回 false。
API 说明
语法如下:
db.command.aggregate.or([<expression1>, <expression2>, ...])
false、null、0、或 undefined,表达式会解析为 false,否则对其他返回值都认为是 true。
示例代码
price 有如下记录:
{ "_id": 1, "min": 10, "max": 100 }{ "_id": 2, "min": 60, "max": 80 }{ "_id": 3, "min": 30, "max": 50 }
min 小于 40 且 max 大于 60 的记录。
const $ = db.command.aggregatedb.collection('price').aggregate() .project({ fullfilled: $.or([$.lt(['$min', 30]), $.gt(['$max', 60])]) }) .end()
返回结果如下:
{ "_id": 1, "fullfilled": true }{ "_id": 2, "fullfilled": false }{ "_id": 3, "fullfilled": true }
比较操作符
cmp
聚合操作符。给定两个值,返回其比较值:
API 说明
如果第一个值小于第二个值,返回 -1如果第一个值大于第二个值,返回 1如果两个值相等,返回 0 语法如下:
db.command.aggregate.cmp([<expression1>, <expression2>])
示例代码
price 有如下记录:
{ "_id": 1, "shop1": 10, "shop2": 100 }{ "_id": 2, "shop1": 80, "shop2": 20 }{ "_id": 3, "shop1": 50, "shop2": 50 }
shop1 和 shop2 的各个物品的价格对比。
const $ = db.command.aggregatedb.collection('price').aggregate() .project({ compare: $.cmp(['$shop1', '$shop2'])) }) .end()
返回结果如下:
{ "_id": 1, "compare": -1 }{ "_id": 2, "compare": 1 }{ "_id": 3, "compare": 0 }
eq
true,否则返回 false。
API 说明
语法如下:
db.command.aggregate.eq([<value1>, <value2>])
示例代码
price 有如下记录:
{ "_id": 1, "value": 10 }{ "_id": 2, "value": 80 }{ "_id": 3, "value": 50 }
value 等于 50 的记录。
const $ = db.command.aggregatedb.collection('price').aggregate() .project({ matched: $.eq(['$value', 50]) }) .end()
返回结果如下:
{ "_id": 1, "matched": false }{ "_id": 2, "matched": false }{ "_id": 3, "matched": true }
gt
true,否则返回 false。
API 说明
语法如下:
db.command.aggregate.gt([<value1>, <value2>])
示例代码
price 有如下记录:
{ "_id": 1, "value": 10 }{ "_id": 2, "value": 80 }{ "_id": 3, "value": 50 }
value 是否大于 50。
const $ = db.command.aggregatedb.collection('price').aggregate() .project({ matched: $.gt(['$value', 50]) }) .end()
返回结果如下:
{ "_id": 1, "matched": false }{ "_id": 2, "matched": true }{ "_id": 3, "matched": false }
gte
true,否则返回 false。
API 说明
语法如下:
db.command.aggregate.gte([<value1>, <value2>])
示例代码
price 有如下记录:
{ "_id": 1, "value": 10 }{ "_id": 2, "value": 80 }{ "_id": 3, "value": 50 }
value 是否大于或等于 50。
const $ = db.command.aggregatedb.collection('price').aggregate() .project({ matched: $.gte(['$value', 50]) }) .end()
返回结果如下:
{ "_id": 1, "matched": false }{ "_id": 2, "matched": true }{ "_id": 3, "matched": true }
lt
true,否则返回 false。
API 说明
语法如下:
db.command.aggregate.lt([<value1>, <value2>])
示例代码
price 有如下记录:
{ "_id": 1, "value": 10 }{ "_id": 2, "value": 80 }{ "_id": 3, "value": 50 }
value 是否小于 50。
const $ = db.command.aggregatedb.collection('price').aggregate() .project({ matched: $.lt(['$value', 50]) }) .end()
返回结果如下:
{ "_id": 1, "matched": true }{ "_id": 2, "matched": false }{ "_id": 3, "matched": false }
lte
true,否则返回 false。
API 说明
语法如下:
db.command.aggregate.lte([<value1>, <value2>])
示例代码
price 有如下记录:
{ "_id": 1, "value": 10 }{ "_id": 2, "value": 80 }{ "_id": 3, "value": 50 }
value 是否小于 50。
const $ = db.command.aggregatedb.collection('price').aggregate() .project({ matched: $.lte(['$value', 50]) }) .end()
返回结果如下:
{ "_id": 1, "matched": true }{ "_id": 2, "matched": false }{ "_id": 3, "matched": true }
neq
true,否则返回 false。
API 说明
语法如下:
db.command.aggregate.neq([<value1>, <value2>])
示例代码
price 有如下记录:
{ "_id": 1, "value": 10 }{ "_id": 2, "value": 80 }{ "_id": 3, "value": 50 }
value 不等于 50 的记录。
const $ = db.command.aggregatedb.collection('price').aggregate() .project({ matched: $.neq(['$value', 50]) }) .end()
返回结果如下:
{ "_id": 1, "matched": true }{ "_id": 2, "matched": true }{ "_id": 3, "matched": false }
条件操作符
cond
聚合操作符。计算布尔表达式,返回指定的两个值其中之一。
API 说明
cond 的使用形式如下:
cond({ if: <布尔表达式>, then: <真值>, else: <假值> })
或者:
cond([ <布尔表达式>, <真值>, <假值> ])
if、then、else)都是必须的。
$cond 将会返回 <真值>,否则会返回 <假值>
示例代码
items 的记录如下:
{ "_id": "0", "name": "item-a", "amount": 100 }{ "_id": "1", "name": "item-b", "amount": 200 }{ "_id": "2", "name": "item-c", "amount": 300 }
cond,根据 amount 字段,来生成新的字段 discount:
const $ = db.command.aggregatedb.collection('items').aggregate() .project({ name: 1, discount: $.cond({ if: $.gte(['$amount', 200]), then: 0.7, else: 0.9 }) }) .end()
输出如下:
{ "_id": "0", "name": "item-a", "discount": 0.9 }{ "_id": "1", "name": "item-b", "discount": 0.7 }{ "_id": "2", "name": "item-c", "discount": 0.7 }
ifNull
聚合操作符。计算给定的表达式,如果表达式结果为 null、undefined 或者不存在,那么返回一个替代值;否则返回原值。
API 说明
ifNull 的使用形式如下:
ifNull([ <表达式>, <替代值> ])
示例代码
items 的记录如下:
{ "_id": "0", "name": "A", "description": "这是商品A" }{ "_id": "1", "name": "B", "description": null }{ "_id": "2", "name": "C" }
ifNull,对不存在 desc 字段的文档,或者 desc 字段为 null 的文档,补充一个替代值。
const $ = db.command.aggregatedb.collection('items').aggregate() .project({ _id: 0, name: 1, description: $.ifNull(['$description', '商品描述空缺']) }) .end()
输出如下:
{ "name": "A", "description": "这是商品A" }{ "name": "B", "description": "商品描述空缺" }{ "name": "C", "description": "商品描述空缺" }
switch
switch-case-default 计算返回值、
API 说明
switch 的使用形式如下:
switch({ branches: [ case: <表达式>, then: <表达式>, case: <表达式>, then: <表达式>, ... ], default: <表达式>})
示例代码
items 的记录如下:
{ "_id": "0", "name": "item-a", "amount": 100 }{ "_id": "1", "name": "item-b", "amount": 200 }{ "_id": "2", "name": "item-c", "amount": 300 }
switch,根据 amount 字段,来生成新的字段 discount:
const $ = db.command.aggregatedb.collection('items').aggregate() .project({ name: 1, discount: $.switch({ branches: [ { case: $.gt(['$amount', 250]), then: 0.8 }, { case: $.gt(['$amount', 150]), then: 0.9 } ], default: 1 }) }) .end()
输出如下:
{ "_id": "0", "name": "item-a", "discount": 1 }{ "_id": "1", "name": "item-b", "discount": 0.9 }{ "_id": "2", "name": "item-c", "discount": 0.8 }
日期操作符
dateFromParts
聚合操作符。给定日期的相关信息,构建并返回一个日期对象。 平台差异说明
API 说明
语法如下:
db.command.aggregate.dateFromParts({ year: <year>, month: <month>, day: <day>, hour: <hour>, minute: <minute>, second: <second>, millisecond: <ms>, timezone: <tzExpression>})
你也可以使用 ISO 8601 的标准:
db.command.aggregate.dateFromParts({ isoWeekYear: <year>, isoWeek: <week>, isoDayOfWeek: <day>, hour: <hour>, minute: <minute>, second: <second>, millisecond: <ms>, timezone: <tzExpression>})
说明
timezone字段请参考Olson Timezone Identifier,形式类似:Asia/Shanghai示例代码
输出如下:const $ = db.command.aggregatedb .collection('dates') .aggregate() .project({ _id: 0, date: $.dateFromParts({ year: 2017, month: 2, day: 8, hour: 12, timezone: 'America/New_York' }), }) .end()
{ "date": ISODate("2017-02-08T17:00:00.000Z")}
dateFromString
聚合操作符。将一个日期/时间字符串转换为日期对象 平台差异说明API 说明
语法如下:db.command.aggregate.dateFromString({ dateString: <dateStringExpression>, timezone: <tzExpression>})
示例代码
输出如下:const $ = db.command.aggregatedb .collection('dates') .aggregate() .project({ _id: 0, date: $.dateFromString({ dateString: "2019-05-14T09:38:51.686Z" }) }) .end()
{ "date": ISODate("2019-05-14T09:38:51.686Z")}
dateToString
聚合操作符。根据指定的表达式将日期对象格式化为符合要求的字符串。 平台差异说明API 说明
dateToString的调用形式如下:
下面是四种表达式的详细说明: 下面是格式说明符的详细说明:db.command.aggregate.dateToString({ date: <日期表达式>, format: <格式化表达式>, timezone: <时区表达式>, onNull: <空值表达式>})
示例代码
students有如下记录:
格式化日期{ "date": "1999-12-11T16:00:00.000Z", "firstName": "Yuanxin", "lastName": "Dong" }{ "date": "1998-11-10T16:00:00.000Z", "firstName": "Weijia", "lastName": "Wang" }{ "date": "1997-10-09T16:00:00.000Z", "firstName": "Chengxi", "lastName": "Li" }
date字段的值,格式化成形如年份-月份-日期的字符串:
返回的结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .project({ _id: 0, formatDate: $.dateToString({ date: '$date', format: '%Y-%m-%d' }) }) .end()
时区时间{ "formatDate": "1999-12-11" }{ "formatDate": "1998-11-10" }{ "formatDate": "1997-10-09" }
date字段值格式化为上海时区时间的例子:
返回的结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .project({ _id: 0, formatDate: $.dateToString({ date: '$date', format: '%H:%M:%S', timezone: 'Asia/Shanghai' }) }) .end()
缺失情况的默认值{ "formatDate": "00:00:00" }{ "formatDate": "00:00:00" }{ "formatDate": "00:00:00" }
<日期表达式>返回空或者不存在的时候,可以设置缺失情况下的默认值:
返回的结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .project({ _id: 0, formatDate: $.dateToString({ date: '$empty', onNull: 'null' }) }) .end()
{ "formatDate": "null" }{ "formatDate": "null" }{ "formatDate": "null" }
dayOfMonth
聚合操作符。返回日期字段对应的天数(一个月中的哪一天),是一个介于 1 至 31 之间的数字。API 说明
语法如下:db.command.aggregate.dayOfMonth(<日期字段>)
示例代码
dates有以下文档:{ "_id": 1, "date": ISODate("2019-05-14T09:38:51.686Z")}
dayOfMonth()对date字段进行投影,获取对应的日期:
输出如下:const $ = db.command.aggregatedb .collection('dates') .aggregate() .project({ _id: 0, dayOfMonth: $.dayOfMonth('$date') }) .end()
{ "dayOfMonth": 14}
dayOfWeek
聚合操作符。返回日期字段对应的天数(一周中的第几天),是一个介于 1(周日)到 7(周六)之间的整数。API 说明
注意:周日是每周的第 1 天* 语法如下:db.command.aggregate.dayOfWeek(<日期字段>)
示例代码
dates有以下文档:{ "_id": 1, "date": ISODate("2019-05-14T09:38:51.686Z")}
dayOfWeek()对date字段进行投影,获取对应的天数(一周中的第几天):
输出如下:const $ = db.command.aggregatedb .collection('dates') .aggregate() .project({ _id: 0, dayOfWeek: $.dayOfWeek('$date') }) .end()
{ "dayOfWeek": 3}
dayOfYear
聚合操作符。返回日期字段对应的天数(一年中的第几天),是一个介于 1 到 366 之间的整数。API 说明
语法如下:db.command.aggregate.dayOfYear(<日期字段>)
示例代码
dates有以下文档:{ "_id": 1, "date": ISODate("2019-05-14T09:38:51.686Z")}
dayOfYear()对date字段进行投影,获取对应的天数(一年中的第几天):
输出如下:const $ = db.command.aggregatedb .collection('dates') .aggregate() .project({ _id: 0, dayOfYear: $.dayOfYear('$date') }) .end()
{ "dayOfYear": 134}
hour
聚合操作符。返回日期字段对应的小时数,是一个介于 0 到 23 之间的整数。API 说明
语法如下:db.command.aggregate.hour(<日期字段>)
示例代码
dates有以下文档:{ "_id": 1, "date": ISODate("2019-05-14T09:38:51.686Z")}
hour()对date字段进行投影,获取对应的小时数:
输出如下:const $ = db.command.aggregatedb .collection('dates') .aggregate() .project({ _id: 0, hour: $.hour('$date') }) .end()
{ "hour": 9}
isoDayOfWeek
聚合操作符。返回日期字段对应的 ISO 8601 标准的天数(一周中的第几天),是一个介于 1(周一)到 7(周日)之间的整数。API 说明
语法如下:db.command.aggregate.month(<日期字段>)
示例代码
dates有以下文档:{ "_id": 1, "date": ISODate("2019-05-14T09:38:51.686Z")}
month()对date字段进行投影,获取对应的 ISO 8601 标准的天数(一周中的第几天):
输出如下:const $ = db.command.aggregatedb .collection('dates') .aggregate() .project({ _id: 0, isoDayOfWeek: $.isoDayOfWeek('$date') }) .end()
{ "isoDayOfWeek": 2}
isoWeek
聚合操作符。返回日期字段对应的 ISO 8601 标准的周数(一年中的第几周),是一个介于 1 到 53 之间的整数。API 说明
根据 ISO 8601 标准,周一到周日视为一周,本年度第一个周四所在的那周,视为本年度的第 1 周。 例如:2016 年 1 月 7 日是那年的第一个周四,那么 2016.01.04(周一)到 2016.01.10(周日) 即为第 1 周。同理,2016 年 1 月 1 日的周数为 53。 语法如下:db.command.aggregate.isoWeek(<日期字段>)
示例代码
dates有以下文档:{ "_id": 1, "date": ISODate("2019-05-14T09:38:51.686Z")}
isoWeek()对date字段进行投影,获取对应的 ISO 8601 标准的周数(一年中的第几周):
输出如下:const $ = db.command.aggregatedb .collection('dates') .aggregate() .project({ _id: 0, isoWeek: $.isoWeek('$date') }) .end()
{ "isoWeek": 20}
isoWeekYear
聚合操作符。返回日期字段对应的 ISO 8601 标准的天数(一年中的第几天)。API 说明
此处的“年”以第一周的周一为开始,以最后一周的周日为结束。 语法如下:db.command.aggregate.isoWeekYear(<日期字段>)
示例代码
dates有以下文档:{ "_id": 1, "date": ISODate("2019-05-14T09:38:51.686Z")}
isoWeekYear()对date字段进行投影,获取对应的 ISO 8601 标准的天数(一年中的第几天):
输出如下:const $ = db.command.aggregatedb .collection('dates') .aggregate() .project({ _id: 0, isoWeekYear: $.isoWeekYear('$date') }) .end()
{ "isoWeekYear": 2019}
millisecond
聚合操作符。返回日期字段对应的毫秒数,是一个介于 0 到 999 之间的整数。API 说明
语法如下:db.command.aggregate.millisecond(<日期字段>)
示例代码
dates有以下文档:{ "_id": 1, "date": ISODate("2019-05-14T09:38:51.686Z")}
millisecond()对date字段进行投影,获取对应的毫秒数:
输出如下:const $ = db.command.aggregatedb .collection('dates') .aggregate() .project({ _id: 0, millisecond: $.millisecond('$date'), }) .end()
{ "millisecond": 686}
minute
聚合操作符。返回日期字段对应的分钟数,是一个介于 0 到 59 之间的整数。API 说明
语法如下:db.command.aggregate.minute(<日期字段>)
示例代码
dates有以下文档:{ "_id": 1, "date": ISODate("2019-05-14T09:38:51.686Z")}
minute()对date字段进行投影,获取对应的分钟数:
输出如下:const $ = db.command.aggregatedb .collection('dates') .aggregate() .project({ _id: 0, minute: $.minute('$date') }) .end()
{ "minute": 38}
month
聚合操作符。返回日期字段对应的月份,是一个介于 1 到 12 之间的整数。API 说明
语法如下:db.command.aggregate.month(<日期字段>)
示例代码
dates有以下文档:{ "_id": 1, "date": ISODate("2019-05-14T09:38:51.686Z")}
month()对date字段进行投影,获取对应的月份:
输出如下:const $ = db.command.aggregatedb .collection('dates') .aggregate() .project({ _id: 0, month: $.month('$date') }) .end()
{ "month": 5}
second
聚合操作符。返回日期字段对应的秒数,是一个介于 0 到 59 之间的整数,在特殊情况下(闰秒)可能等于 60。API 说明
语法如下:db.command.aggregate.second(<日期字段>)
示例代码
dates有以下文档:{ "_id": 1, "date": ISODate("2019-05-14T09:38:51.686Z")}
second()对date字段进行投影,获取对应的秒数:
输出如下:const $ = db.command.aggregatedb .collection('dates') .aggregate() .project({ _id: 0, second: $.second('$date') }) .end()
{ "second": 51}
week
聚合操作符。返回日期字段对应的周数(一年中的第几周),是一个介于 0 到 53 之间的整数。API 说明
每年的第一个周日即为week 1的开始,这天之前是week 0。 语法如下:db.command.aggregate.week(<日期字段>)
示例代码
dates有以下文档:{ "_id": 1, "date": ISODate("2019-05-14T09:38:51.686Z")}
week()对date字段进行投影,获取对应的周数(一年中的第几周):
输出如下:const $ = db.command.aggregatedb .collection('dates') .aggregate() .project({ _id: 0, week: $.week('$date') }) .end()
{ "week": 19}
year
聚合操作符。返回日期字段对应的年份。API 说明
语法如下:db.command.aggregate.year(<日期字段>)
示例代码
dates有以下文档:{ "_id": 1, "date": ISODate("2019-05-14T09:38:51.686Z")}
year()对date字段进行投影,获取对应的年份:
输出如下:const $ = db.command.aggregatedb .collection('dates') .aggregate() .project({ _id: 0, year: $.year('$date') }) .end()
{ "year": 2019}
subtract
subtract常量操作符
literal
聚合操作符。直接返回一个值的字面量,不经过任何解析和处理。API 说明
literal使用形式如下:literal(<值>)
<值>是一个表达式,那么literal不会解析或者计算这个表达式,而是直接返回这个表达式。示例代码
items集合,其中数据如下:
以字面量的形式使用 ${ "_id": "0", "price": "$1" }{ "_id": "1", "price": "$5.60" }{ "_id": "2", "price": "$8.90" }
literal,生成了一个新的字段isOneDollar,表示price字段是否严格等于"$1"。eq(['$price', '$1']),因为"$1"是一个表达式,代表"1"字段对应的值,而不是字符串字面量"$1"。
输出如下:const $ = db.command.aggregatedb.collection('items').aggregate() .project({ isOneDollar: $.eq(['$price', $.literal('$1')]) }) .end()
投影一个字段,对应的值为 1{ "_id": "0", "isOneDollar": true }{ "_id": "1", "isOneDollar": false }{ "_id": "2", "isOneDollar": false }
literal,投影了一个新的字段amount,其值为1。
输出如下:const $ = db.command.aggregatedb.collection('items').aggregate() .project({ price: 1, amount: $.literal(1) }) .end()
{ "_id": "0", "price": "$1", "amount": 1 }{ "_id": "1", "price": "$5.60", "amount": 1 }{ "_id": "2", "price": "$8.90", "amount": 1 }
对象操作符
mergeObjects
聚合操作符。将多个文档合并为单个文档。 平台差异说明API 说明
group()中使用时:
在其它表达式中使用时:mergeObjects(<document>)
mergeObjects([<document1>, <document2>, ...])
示例代码
搭配sales存在以下文档:{ "_id": 1, "year": 2018, "name": "A", "volume": { "2018Q1": 500, "2018Q2": 500 } }{ "_id": 2, "year": 2017, "name": "A", "volume": { "2017Q1": 400, "2017Q2": 300, "2017Q3": 0, "2017Q4": 0 } }{ "_id": 3, "year": 2018, "name": "B", "volume": { "2018Q1": 100 } }{ "_id": 4, "year": 2017, "name": "B", "volume": { "2017Q3": 100, "2017Q4": 250 } }
mergeObjects(),将用相同name的文档合并:
输出如下:const $ = db.command.aggregatedb.collection('sales').aggregate() .group({ _id: '$name', mergedVolume: $.mergeObjects('$volume') }) .end()
一般用法{ "_id": "A", "mergedVolume": { "2017Q1": 400, "2017Q2": 300, "2017Q3": 0, "2017Q4": 0, "2018Q1": 500, "2018Q2": 500 } }{ "_id": "B", "mergedVolume": { "2017Q3": 100, "2017Q4": 250, "2018Q1": 100 } }
test存在以下文档:{ "_id": 1, "foo": { "a": 1 }, "bar": { "b": 2 } }{ "_id": 2, "foo": { "c": 1 }, "bar": { "d": 2 } }{ "_id": 3, "foo": { "e": 1 }, "bar": { "f": 2 } }
mergeObjects(),将文档中的foo和bar字段合并为foobar:
输出结果如下:const $ = db.command.aggregatedb.collection('sales').aggregate() .project({ foobar: $.mergeObjects(['$foo', '$bar']) }) .end()
{ "_id": 1, "foobar": { "a": 1, "b": 2 } }{ "_id": 2, "foobar": { "c": 1, "d": 2 } }{ "_id": 3, "foobar": { "e": 1, "f": 2 } }
objectToArray
objectToArray集合操作符
allElementsTrue
true,否则返回false。空数组永远返回true。API 说明
语法如下:allElementsTrue([<expression>])
示例代码
test有如下记录:{ "_id": 1, "array": [ true ] }{ "_id": 2, "array": [ ] }{ "_id": 3, "array": [ false ] }{ "_id": 4, "array": [ true, false ] }{ "_id": 5, "array": [ 0 ] }{ "_id": 6, "array": [ "stark" ] }
allElementsTrue(),判断array字段中是否均为真值:
返回结果如下:const $ = db.command.aggregatedb.collection('price') .aggregate() .project({ isAllTrue: $.allElementsTrue(['$array']) }) .end()
{ "_id": 1, "isAllTrue": true }{ "_id": 2, "isAllTrue": true }{ "_id": 3, "isAllTrue": false }{ "_id": 4, "isAllTrue": false }{ "_id": 5, "isAllTrue": false }{ "_id": 6, "isAllTrue": true }
anyElementTrue
true,否则返回false。空数组永远返回false。API 说明
语法如下:anyElementTrue([<expression>])
示例代码
test有如下记录:{ "_id": 1, "array": [ true ] }{ "_id": 2, "array": [ ] }{ "_id": 3, "array": [ false ] }{ "_id": 4, "array": [ true, false ] }{ "_id": 5, "array": [ 0 ] }{ "_id": 6, "array": [ "stark" ] }
anyElementTrue(),判断array字段中是否含有真值:
返回结果如下:const $ = db.command.aggregatedb.collection('price') .aggregate() .project({ isAnyTrue: $.anyElementTrue(['$array']) }) .end()
{ "_id": 1, "isAnyTrue": true }{ "_id": 2, "isAnyTrue": false }{ "_id": 3, "isAnyTrue": false }{ "_id": 4, "isAnyTrue": true }{ "_id": 5, "isAnyTrue": false }{ "_id": 6, "isAnyTrue": true }
setDifference
聚合操作符,输入两个集合,输出只存在于第一个集合中的元素。API 说明
使用形式如下:setDifference([<expression1>, <expression2>])
示例代码
test存在以下数据:{ "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] }{ "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] }{ "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] }{ "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] }{ "_id": 5, "A": [ 1, 2 ], "B": [ ] }{ "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] }{ "_id": 7, "A": [ ], "B": [ ] }{ "_id": 8, "A": [ ], "B": [ 1 ] }
setDifference,找到只存在于B中的数字:db.collection('test') .aggregate() .project({ isBOnly: $.setDifference(['$B', '$A']) }) .end()
{ "_id": 1, "isBOnly": [] }{ "_id": 2, "isBOnly": [3] }{ "_id": 3, "isBOnly": [3] }{ "_id": 4, "isBOnly": [5] }{ "_id": 5, "isBOnly": [] }{ "_id": 6, "isBOnly": [{}, []] }{ "_id": 7, "isBOnly": [] }{ "_id": 8, "isBOnly": [1] }
setEquals
聚合操作符,输入两个集合,判断两个集合中包含的元素是否相同(不考虑顺序、去重)。API 说明
使用形式如下:setEquals([<expression1>, <expression2>])
示例代码
test存在以下数据:{ "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] }{ "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] }{ "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] }{ "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] }{ "_id": 5, "A": [ 1, 2 ], "B": [ ] }{ "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] }{ "_id": 7, "A": [ ], "B": [ ] }{ "_id": 8, "A": [ ], "B": [ 1 ] }
setEquals,判断两个集合中包含的元素是否相同:db.collection('test') .aggregate() .project({ sameElements: $.setEquals(['$A', '$B']) }) .end()
{ "_id": 1, "sameElements": true }{ "_id": 2, "sameElements": true }{ "_id": 3, "sameElements": false }{ "_id": 4, "sameElements": false }{ "_id": 5, "sameElements": false }{ "_id": 6, "sameElements": false }{ "_id": 7, "sameElements": true }{ "_id": 8, "sameElements": false }
setIntersection
聚合操作符,输入两个集合,输出两个集合的交集。API 说明
使用形式如下:setIntersection([<expression1>, <expression2>])
示例代码
test存在以下数据:{ "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] }{ "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] }{ "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] }{ "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] }{ "_id": 5, "A": [ 1, 2 ], "B": [ ] }{ "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] }{ "_id": 7, "A": [ ], "B": [ ] }{ "_id": 8, "A": [ ], "B": [ 1 ] }
setIntersection,输出两个集合的交集:
输出如下:db.collection('test') .aggregate() .project({ commonToBoth: $.setIntersection(['$A', '$B']) }) .end()
{ "_id": 1, "commonToBoth": [ 1, 2 ] }{ "_id": 2, "commonToBoth": [ 1, 2 ] }{ "_id": 3, "commonToBoth": [ 1, 2 ] }{ "_id": 4, "commonToBoth": [ 1 ] }{ "_id": 5, "commonToBoth": [ ] }{ "_id": 6, "commonToBoth": [ ] }{ "_id": 7, "commonToBoth": [ ] }{ "_id": 8, "commonToBoth": [ ] }
setIsSubset
聚合操作符,输入两个集合,判断第一个集合是否是第二个集合的子集。API 说明
使用形式如下:setIsSubset([<expression1>, <expression2>])
示例代码
test存在以下数据:{ "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] }{ "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] }{ "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] }{ "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] }{ "_id": 5, "A": [ 1, 2 ], "B": [ ] }{ "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] }{ "_id": 7, "A": [ ], "B": [ ] }{ "_id": 8, "A": [ ], "B": [ 1 ] }
setIsSubset,判断第一个集合是否是第二个集合的子集:db.collection('test') .aggregate() .project({ AisSubsetOfB: $.setIsSubset(['$A', '$B']) }) .end()
{ "_id": 1, "AisSubsetOfB": true }{ "_id": 2, "AisSubsetOfB": true }{ "_id": 3, "AisSubsetOfB": true }{ "_id": 4, "AisSubsetOfB": false }{ "_id": 5, "AisSubsetOfB": false }{ "_id": 6, "AisSubsetOfB": false }{ "_id": 7, "AisSubsetOfB": true }{ "_id": 8, "AisSubsetOfB": true }
setUnion
聚合操作符,输入两个集合,输出两个集合的并集。API 说明
使用形式如下:setUnion([<expression1>, <expression2>])
示例代码
test存在以下数据:{ "_id": 1, "A": [ 1, 2 ], "B": [ 1, 2 ] }{ "_id": 2, "A": [ 1, 2 ], "B": [ 2, 1, 2 ] }{ "_id": 3, "A": [ 1, 2 ], "B": [ 1, 2, 3 ] }{ "_id": 4, "A": [ 1, 2 ], "B": [ 3, 1 ] }{ "_id": 5, "A": [ 1, 2 ], "B": [ ] }{ "_id": 6, "A": [ 1, 2 ], "B": [ {}, [] ] }{ "_id": 7, "A": [ ], "B": [ ] }{ "_id": 8, "A": [ ], "B": [ 1 ] }
setUnion,输出两个集合的并集:
输出如下:db.collection('test') .aggregate() .project({ AB: $.setUnion(['$A', '$B']) }) .end()
{ "_id": 1, "AB": [ 1, 2 ] }{ "_id": 2, "AB": [ 1, 2 ] }{ "_id": 3, "AB": [ 1, 2, 3 ] }{ "_id": 4, "AB": [ 1, 2, 3 ] }{ "_id": 5, "AB": [ 1, 2 ] }{ "_id": 6, "AB": [ 1, 2, {}, [] ] }{ "_id": 7, "AB": [ ] }{ "_id": 8, "AB": [ 1 ] }
字符串操作符
concat
聚合操作符。连接字符串,返回拼接后的字符串。API 说明
concat的语法如下:db.command.aggregate.concat([<表达式1>, <表达式2>, ...])
$ + 指定字段,也可以是普通字符串。只要能够被解析成字符串即可。示例代码
students的记录如下:{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }
concat可以拼接lastName和firstName字段,得到每位学生的名字全称:
返回的结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .project({ _id: 0, fullName: $.concat(['$firstName', ' ', '$lastName']) }) .end()
{ "fullName": "Yuanxin Dong" }{ "fullName": "Weijia Wang" }{ "fullName": "Chengxi Li" }
dateFromString
dateFromStringdateToString
dateToStringindexOfBytes
UTF-8的字节索引(从0开始)。如果不存在子字符串,返回 -1。API 说明
indexOfBytes的语法如下:
下面是 4 种表达式的详细描述:db.command.aggregate.indexOfBytes([<目标字符串表达式>, <子字符串表达式>, <开始位置表达式>, <结束位置表达式>])
示例代码
students的记录如下:{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }
indexOfBytes查找字符"a"在字段firstName中的位置:
返回的结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .project({ _id: 0, aStrIndex: $.indexOfBytes(['$firstName', 'a']) }) .end()
{ "aStrIndex": 2 }{ "aStrIndex": 5 }{ "aStrIndex": -1 }
indexOfCP
UTF-8的code point索引(从0开始)。如果不存在子字符串,返回 -1。API 说明
code point是“码位”,又名“编码位置”。这里特指Unicode包中的码位,范围是从0(16进制)到10FFFF(16进制)。indexOfCP的语法如下:
下面是 4 种表达式的详细描述:db.command.aggregate.indexOfCP([<目标字符串表达式>, <子字符串表达式>, <开始位置表达式>, <结束位置表达式>])
示例代码
students的记录如下:{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }
indexOfCP查找字符"a"在字段firstName中的位置:
返回的结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .project({ _id: 0, aStrIndex: $.indexOfCP(['$firstName', 'a']) }) .end()
{ "aStrIndex": 2 }{ "aStrIndex": 5 }{ "aStrIndex": -1 }
split
聚合操作符。按照分隔符分隔数组,并且删除分隔符,返回子字符串组成的数组。如果字符串无法找到分隔符进行分隔,返回原字符串作为数组的唯一元素。API 说明
split的语法如下:
字符串表达式和分隔符表达式可以是任意形式的表达式,只要它可以被解析为字符串即可。db.command.aggregate.split([<字符串表达式>, <分隔符表达式>])
示例代码
students的记录如下:{ "birthday": "1999/12/12" }{ "birthday": "1998/11/11" }{ "birthday": "1997/10/10" }
split将每条记录中的birthday字段对应值分隔成数组,每个数组分别由代表年、月、日的3个元素组成:
返回的结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .project({ _id: 0, birthday: $.split(['$birthday', '/']) }) .end()
{ "birthday": [ "1999", "12", "12" ] }{ "birthday": [ "1998", "11", "11" ] }{ "birthday": [ "1997", "10", "10" ] }
strLenBytes
utf-8编码的字节数量。API 说明
strLenBytes的语法如下:
只要表达式可以被解析成字符串,那么它就是有效表达式。db.command.aggregate.strLenBytes(<表达式>)
示例代码
students的记录如下:{ "name": "dongyuanxin", "nickname": "心谭" }
strLenBytes计算name字段和nickname字段对应值的字节长度:
返回结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .project({ _id: 0, nameLength: $.strLenBytes('$name'), nicknameLength: $.strLenBytes('$nickname') }) .end()
{ "nameLength": 11, "nicknameLength": 6 }
strLenCP
code points 数量。API 说明
strLenCP的语法如下:
只要表达式可以被解析成字符串,那么它就是有效表达式。db.command.aggregate.strLenCP(<表达式>)
示例代码
students的记录如下:{ "name": "dongyuanxin", "nickname": "心谭" }
strLenCP计算name字段和nickname字段对应值的UTF-8 code points的数量:
返回结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .project({ _id: 0, nameLength: $.strLenCP('$name'), nicknameLength: $.strLenCP('$nickname') }) .end()
{ "nameLength": 11, "nicknameLength": 2 }
strcasecmp
聚合操作符。对两个字符串在不区分大小写的情况下进行大小比较,并返回比较的结果。API 说明
strcasecmp的语法如下:db.command.aggregate.strcasecmp([<表达式1>, <表达式2>])
表达式1和表达式2可以被解析成字符串,那么它们就是有效的。 返回的比较结果有1,0和-1三种:表达式1解析的字符串 >表达式2解析的字符串 - 0:表达式1解析的字符串 =表达式2解析的字符串 - -1:表达式1解析的字符串 <表达式2解析的字符串示例代码
students的记录如下:{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }
strcasecmp比较firstName字段值和lastName字段值的大小:
返回结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .project({ _id: 0, result: $.strcasecmp(['$firstName', '$lastName']), }) .end()
{ "result": 1 }{ "result": 1 }{ "result": -1 }
substr
db.command.aggregate.substrBytes的别名,更推荐使用后者。API 说明
substr的语法如下:db.command.aggregate.substr([<表达式1>, <表达式2>, <表达式3>])
表达式1是任何可以解析为字符串的有效表达式,表达式2和表达式3是任何可以解析为数字的有效表达式。表达式2是负数,返回的结果为""。表达式3是负数,返回的结果为从表达式2指定的开始位置以及之后其余部分的子字符串。示例代码
students的记录如下:{ "birthday": "1999/12/12", "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }{ "birthday": "1998/11/11", "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }{ "birthday": "1997/10/10", "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }
substr可以提取birthday中的年、月、日信息,代码如下:
返回的结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .project({ _id: 0, year: $.substr(['$birthday', 0, 4]), month: $.substr(['$birthday', 5, 2]), day: $.substr(['$birthday', 8, -1]) }) .end()
{ "day": "12", "month": "12", "year": "1999" }{ "day": "11", "month": "11", "year": "1998" }{ "day": "10", "month": "10", "year": "1997" }
substrBytes
UTF-8字节索引的字符开始,长度为指定的字节数。API 说明
substrBytes的语法如下:db.command.aggregate.substrBytes([<表达式1>, <表达式2>, <表达式3>])
表达式1是任何可以解析为字符串的有效表达式,表达式2和表达式3是任何可以解析为数字的有效表达式。表达式2是负数,返回的结果为""。表达式3是负数,返回的结果为从表达式2指定的开始位置以及之后其余部分的子字符串。示例代码
students的记录如下:{ "birthday": "1999/12/12", "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }{ "birthday": "1998/11/11", "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }{ "birthday": "1997/10/10", "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }
substrBytes可以提取birthday中的年、月、日信息,代码如下:
返回的结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .project({ _id: 0, year: $.substrBytes(['$birthday', 0, 4]), month: $.substrBytes(['$birthday', 5, 2]), day: $.substrBytes(['$birthday', 8, -1]) }) .end()
{ "day": "12", "month": "12", "year": "1999" }{ "day": "11", "month": "11", "year": "1998" }{ "day": "10", "month": "10", "year": "1997" }
substrCP
UTF-8字节索引的字符开始,长度为指定的字节数。API 说明
substrCP的语法如下:db.command.aggregate.substrCP([<表达式1>, <表达式2>, <表达式3>])
表达式1是任何可以解析为字符串的有效表达式,表达式2和表达式3是任何可以解析为数字的有效表达式。表达式2是负数,返回的结果为""。表达式3是负数,返回的结果为从表达式2指定的开始位置以及之后其余部分的子字符串。示例代码
students的记录如下:{ "name": "dongyuanxin", "nickname": "心谭" }
substrCP可以提取nickname字段值的第一个汉字:
返回的结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .project({ _id: 0, firstCh: $.substrCP(['$nickname', 0, 1]) }) .end()
{ "firstCh": "心" }
toLower
聚合操作符。将字符串转化为小写并返回。API 说明
toLower的语法如下:db.command.aggregate.toLower(表达式)
$ + 指定字段。示例代码
students的记录如下:{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }
toLower将firstName的字段值转化为小写:
返回的结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .project({ _id: 0, result: $.toLower('$firstName'), }) .end()
{ "result": "yuanxin" }{ "result": "weijia" }{ "result": "chengxi" }
toUpper
聚合操作符。将字符串转化为大写并返回。API 说明
toUpper的语法如下:db.command.aggregate.toUpper(表达式)
$ + 指定字段。示例代码
students的记录如下:{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }
toUpper将lastName的字段值转化为大写:
返回的结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .project({ _id: 0, result: $.toUpper('$lastName'), }) .end()
{ "result": "DONG" }{ "result": "WANG" }{ "result": "LI" }
累计器操作符
addToSet
group stage中使用。API 说明
addToSet语法如下:db.command.aggregate.addToSet(<表达式>)
$ + 指定字段的字符串。如果指定字段的值是数组,那么整个数组会被当作一个元素。示例代码
passages的记录如下:
非数组字段{ "category": "web", "tags": [ "JavaScript", "CSS" ], "title": "title1" }{ "category": "System", "tags": [ "C++", "C" ], "title": "title2" }
category对应值的类型是非数组,利用addToSet统计所有分类:
返回的结果如下:const $ = db.command.aggregatedb .collection('passages') .aggregate() .group({ _id: null, categories: $.addToSet('$category') }) .end()
数组字段{ "_id": null, "categories": [ "System", "web" ] }
tags对应值的类型是数组,数组不会被自动展开:
返回的结果如下:const $ = db.command.aggregatedb .collection('passages') .aggregate() .group({ _id: null, tagsList: $.addToSet('$tags') }) .end()
{ "_id": null, "tagsList": [ [ "C++", "C" ], [ "JavaScript", "CSS" ] ] }
avg
聚合操作符。返回一组集合中,指定字段对应数据的平均值。API 说明
avg的语法如下:db.command.aggregate.avg(<number>)
avg传入的值除了数字常量外,也可以是任何最终解析成一个数字的表达式。它会忽略非数字值。示例代码
students的记录如下:{ "group": "a", "name": "stu1", "score": 84 }{ "group": "a", "name": "stu2", "score": 96 }{ "group": "b", "name": "stu3", "score": 80 }{ "group": "b", "name": "stu4", "score": 100 }
avg可以计算所有记录的score的平均值:
返回的结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .group({ _id: null, average: $.avg('$score') }) .end()
{ "_id": null, "average": 90 }
first
sort)后,此操作才有意义。API 说明
first的语法如下:db.command.aggregate.first(<表达式>)
$ + 指定字段的字符串。first只能在group阶段被使用,并且需要配合sort才有意义。示例代码
students的记录如下:{ "group": "a", "name": "stu1", "score": 84 }{ "group": "a", "name": "stu2", "score": 96 }{ "group": "b", "name": "stu3", "score": 80 }{ "group": "b", "name": "stu4", "score": 100 }
score的最小值,可以先将所有记录按照score排序,然后取出第一条记录的first。
返回的数据结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .sort({ score: 1 }) .group({ _id: null, min: $.first('$score') }) .end()
{ "_id": null, "min": 80 }
last
sort)后,此操作才有意义。API 说明
last的语法如下:db.command.aggregate.last(<表达式>)
$ + 指定字段的字符串。last只能在group阶段被使用,并且需要配合sort才有意义。示例代码
students的记录如下:{ "group": "a", "name": "stu1", "score": 84 }{ "group": "a", "name": "stu2", "score": 96 }{ "group": "b", "name": "stu3", "score": 80 }{ "group": "b", "name": "stu4", "score": 100 }
score的最大值,可以先将所有记录按照score排序,然后取出最后一条记录的last。
返回的数据结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .sort({ score: 1 }) .group({ _id: null, max: $.last('$score') }) .end()
{ "_id": null, "max": 100 }
max
聚合操作符。返回一组数值的最大值。API 说明
max的语法如下:db.command.aggregate.max(<表达式>)
$ + 指定字段的字符串。示例代码
students的记录如下:{ "group": "a", "name": "stu1", "score": 84 }{ "group": "a", "name": "stu2", "score": 96 }{ "group": "b", "name": "stu3", "score": 80 }{ "group": "b", "name": "stu4", "score": 100 }
max可以统计不同组(group)中成绩的最高值,代码如下:
返回的数据结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .group({ _id: '$group', maxScore: $.max('$score') }) .end()
{ "_id": "b", "maxScore": 100 }{ "_id": "a", "maxScore": 96 }```.
mergeObjects
mergeObjectsmin
聚合操作符。返回一组数值的最小值。API 说明
min的语法如下:db.command.aggregate.min(<表达式>)
$ + 指定字段的字符串。示例代码
students的记录如下:{ "group": "a", "name": "stu1", "score": 84 }{ "group": "a", "name": "stu2", "score": 96 }{ "group": "b", "name": "stu3", "score": 80 }{ "group": "b", "name": "stu4", "score": 100 }
min可以统计不同组(group)中成绩的最低值,代码如下:
返回的数据结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .group({ _id: '$group', minScore: $.min('$score') }) .end()
{ "_id": "b", "minScore": 80 }{ "_id": "a", "minScore": 84 }
push
group阶段,返回一组中表达式指定列与对应的值,一起组成的数组。API 说明
push语法如下:db.command.aggregate.push({ <字段名1>: <指定字段1>, <字段名2>: <指定字段2>, ...})
示例代码
students的记录如下:{ "group": "a", "name": "stu1", "score": 84 }{ "group": "a", "name": "stu2", "score": 96 }{ "group": "b", "name": "stu3", "score": 80 }{ "group": "b", "name": "stu4", "score": 100 }
push操作,对不同分组(group)的所有记录,聚合所有数据并且将其放入一个新的字段中,进一步结构化和语义化数据。
输出结果如下:const $ = db.command.aggregatedb .collection('students') .aggregate() .group({ _id: '$group', students: $.push({ name: '$name', score: '$score' }) }) .end()
{ "_id": "b", "students": [{ "name": "stu3", "score": 80 }, { "name": "stu4", "score": 100 }] }{ "_id": "a", "students": [{ "name": "stu1", "score": 84 }, { "name": "stu2", "score": 96 }] }
stdDevPop
聚合操作符。返回一组字段对应值的标准差。API 说明
stdDevPop的使用形式如下:db.command.aggregate.stdDevPop(<表达式>)
number,否则结果会返回null。示例代码
students的记录如下:a组同学的成绩分别是84和96,b组同学的成绩分别是80和100。{ "group":"a", "score":84 }{ "group":"a", "score":96 }{ "group":"b", "score":80 }{ "group":"b", "score":100 }
stdDevPop来分别计算a和b两组同学成绩的标准差,以此来比较哪一组同学的成绩更稳定。代码如下:
返回的数据结果如下:const $ = db.command.aggregatedb.collection('students').aggregate() .group({ _id: '$group', stdDev: $.stdDevPop('$score') }) .end()
{ "_id": "b", "stdDev": 10 }{ "_id": "a", "stdDev": 6 }
stdDevSamp
db.command.aggregate.stdDevPop。API 说明
stdDevSamp的使用形式如下:db.command.aggregate.stdDevSamp(<表达式>)
stdDevSamp会自动忽略非数字值。如果指定字段所有的值均是非数字,那么结果返回null。示例代码
students的记录如下:{ "score": 80 }{ "score": 100 }
stdDevSamp来计算成绩的标准样本偏差。代码如下:
返回的数据结果如下:const $ = db.command.aggregatedb.collection('students').aggregate() .group({ _id: null, ageStdDev: $.stdDevSamp('$score') }) .end()
{ "_id": null, "ageStdDev": 14.142135623730951 }
students添加一条新记录,它的score字段类型是string:{ "score": "aa" }
stdDevSamp会自动忽略类型不为number的记录,返回结果保持不变。sum
聚合操作符。计算并且返回一组字段所有数值的总和。API 说明
sum的使用形式如下:db.command.aggregate.sum(<表达式>)
sum会自动忽略非数字值。如果字段下的所有值均是非数字,那么结果返回 0。若传入数字常量,则当做所有记录该字段的值都给给定常量,在聚合时相加,最终值为输入记录数乘以常量。示例代码
goods的记录如下:price代表商品销售额,cost代表商品成本
单独字段{ "cost": -10, "price": 100 }{ "cost": -15, "price": 1 }{ "cost": -10, "price": 10 }
sum可以计算所有商品的销售总和,代码如下:
返回的数据结果如下:销售额是 111const $ = db.command.aggregatedb .collection('goods') .aggregate() .group({ _id: null, totalPrice: $.sum('$price') }) .end()
字段列表{ "_id": null, "totalPrice": 111 }
cost和price相加得到此记录对应商品的利润。最后再计算所有商品的利润总额。sum,代码如下:
返回的数据结果如下:利润总额为 76const $ = db.command.aggregatedb .collection('goods') .aggregate() .group({ _id: null, totalProfit: $.sum( $.sum(['$price', '$cost']) ) }) .end()
{ "_id": null, "totalProfit": 76 }
变量操作符
let
聚合操作符。自定义变量,并且在指定表达式中使用,返回的结果是表达式的结果。API 说明
let的语法如下:db.command.aggregate.let({ vars: { <变量1>: <变量表达式>, <变量2>: <变量表达式>, ... }, in: <结果表达式>})
vars中可以定义多个变量,变量的值由变量表达式计算而来,并且被定义的变量只有在in中的结果表达式才可以访问。in的结果表达式中访问自定义变量时候,请在变量名前加上双美元符号($$)并用引号括起来。示例代码
goods的记录如下:price代表商品价格,discount代表商品折扣率,cost代表商品成本{ "cost": -10, "discount": 0.95, "price": 100 }{ "cost": -15, "discount": 0.98, "price": 1 }{ "cost": -10, "discount": 1, "price": 10 }
let可以定义并计算每件商品实际的销售价格,并将其赋值给自定义变量priceTotal。最后再将priceTotal与cost进行取和(sum)运算,得到每件商品的利润。 代码如下:
返回的数据结果如下:const $ = db.command.aggregatedb .collection('goods') .aggregate() .project({ profit: $.let({ vars: { priceTotal: $.multiply(['$price', '$discount']) }, in: $.sum(['$$priceTotal', '$cost']) }) }) .end()
{ "profit": 85 }{ "profit": -14.02 }{ "profit": 0 }
在 GitHub 上编辑此页面!
