English
equivalent to mongoDB aggregate operator concept
Returns the absolute value of a number.
The syntax is as follows:
db.command.aggregate.abs(<number>)
In addition to numeric constants, the value passed in by abs
can also be any expression that eventually resolves to a number.
If the expression resolves to null
or points to a field that does not exist, the result of abs
is null
. If the value resolves to NaN
, the result is NaN
.
Suppose the collection ratings
has the following records:
{ _id: 1, start: 5, end: 8 }
{ _id: 2, start: 4, end: 4 }
{ _id: 3, start: 9, end: 7 }
{ _id: 4, start: 6, end: 7 }
···
The absolute difference between start
and end
for each record can be found as follows:
const $ = db.command.aggregate
let res = await db.collection('ratings').aggregate()
.project({
delta: $.abs($.subtract(['$start', '$end']))
})
.end()
The returned results are as follows:
{ "_id" : 1, "delta" : 3 }
{ "_id" : 2, "delta" : 0 }
{ "_id" : 3, "delta" : 2 }
{ "_id" : 4, "delta" : 1 }
Add numbers or add numbers to dates. If one of the values in the array is a date, the other values are treated as milliseconds added to that date.
The syntax is as follows:
db.command.aggregate.add([<表达式1>, <表达式2>, ...])
The expression can be in the form of $ + specified field
, or it can be a normal string. As long as it can be parsed into a string.
Suppose the collection staff
has the following records:
{ _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") }
SUM OF NUMBERS
The total number of people in each record can be obtained as follows:
const $ = db.command.aggregate
let res = await db.collection('staff').aggregate()
.project({
department: 1,
total: $.add(['$sales', '$engineer'])
})
.end()
The returned results are as follows:
{ _id: 1, department: "x", total: 15 }
{ _id: 2, department: "y", total: 30 }
{ _id: 3, department: "z", total: 25 }
Increase date value
The following operation can obtain the value of lastUpdate
plus one hour later for each record:
const $ = db.command.aggregate
let res = await db.collection('staff').aggregate()
.project({
department: 1,
lastUpdate: $.add(['$lastUpdate', 60*60*1000])
})
.end()
The returned results are as follows:
{ _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") }
Round up, returns the smallest integer greater than or equal to the given number.
The syntax is as follows:
db.command.aggregate.ceil(<number>)
<number>
can be any expression that resolves to a number. Returns null
if the expression resolves to null
or points to a field that does not exist, or NaN
if it resolves to NaN
.
Suppose the collection sales
has the following records:
{ _id: 1, sales: 5.2 }
{ _id: 2, sales: 1.32 }
{ _id: 3, sales: -3.2 }
Each number can be rounded up as follows:
const $ = db.command.aggregate
let res = await db.collection('sales').aggregate()
.project({
sales: $.ceil('$sales')
})
.end()
The returned results are as follows:
{ _id: 1, sales: 6 }
{ _id: 2, sales: 2 }
{ _id: 3, sales: -3 }
Pass in the dividend and the divisor, and find the quotient.
The syntax is as follows:
db.command.aggregate.divide([<被除数表达式>, <除数表达式>])
An expression can be any expression that resolves to a number.
Suppose the collection railroads
has the following records:
{ _id: 1, meters: 5300 }
{ _id: 2, meters: 64000 }
{ _id: 3, meters: 130 }
You can take the values after converting each number to kilometers as follows:
const $ = db.command.aggregate
let res = await db.collection('railroads').aggregate()
.project({
km: $.divide(['$meters', 1000])
})
.end()
The returned results are as follows:
{ _id: 1, km: 5.3 }
{ _id: 2, km: 64 }
{ _id: 3, km: 0.13 }
Take e (the base of the natural logarithm, Euler's number) to the nth power.
The syntax is as follows:
db.command.aggregate.exp(<exponent>)
<exponent>
can be any expression that resolves to a number. Returns null
if the expression resolves to null
or points to a field that does not exist, or NaN
if it resolves to NaN
.
Suppose the set math
has the following records:
{ _id: 1, exp: 0 }
{ _id: 2, exp: 1 }
{ _id: 3, exp: 2 }
const $ = db.command.aggregate
let res = await db.collection('math').aggregate()
.project({
result: $.exp('$exp')
})
.end()
The returned results are as follows:
{ _id: 1, result: 1 }
{ _id: 2, result: 2.71828182845905 }
{ _id: 3, result: 7.38905609893065 }
Round down, returns the smallest integer greater than or equal to the given number.
The syntax is as follows:
db.command.aggregate.floor(<number>)
<number>
can be any expression that resolves to a number. Returns null
if the expression resolves to null
or points to a field that does not exist, or NaN
if it resolves to NaN
.
Suppose the collection sales
has the following records:
{ _id: 1, sales: 5.2 }
{ _id: 2, sales: 1.32 }
{ _id: 3, sales: -3.2 }
Each number can be rounded down as follows:
const $ = db.command.aggregate
let res = await db.collection('sales').aggregate()
.project({
sales: $.floor('$sales')
})
.end()
The returned results are as follows:
{ _id: 1, sales: 5 }
{ _id: 2, sales: 1 }
{ _id: 3, sales: -4 }
Calculates the natural logarithm of the given number.
The syntax is as follows:
db.command.aggregate.ln(<number>)
<number>
can be any expression that resolves to a non-negative number.
ln
is equivalent to log([<number>, Math.E])
, where Math.E
is the JavaScript
method for getting the value of e
.
Suppose the collection curve has the following records:
{ _id: 1, x: 1 }
{ _id: 2, x: 2 }
{ _id: 3, x: 3 }
Compute the value of ln(x):
const $ = db.command.aggregate
let res = await db.collection('curve').aggregate()
.project({
log: $.ln('$x')
})
.end()
The returned results are as follows:
{ _id: 1, ln: 0 }
{ _id: 2, ln: 0.6931471805599453 }
{ _id: 3, ln: 1.0986122886681098 }
Calculates the log value of the given number under the given logarithm.
The syntax is as follows:
db.command.aggregate.log([<number>, <base>])
<number>
can be any expression that resolves to a non-negative number. <base>
can be any expression that resolves to a number greater than 1.
log
returns null
if either argument resolves to null
or points to any non-existent field. If either argument resolves to NaN
, log
returns NaN
.
Suppose the collection curve
has the following records:
{ _id: 1, x: 1 }
{ _id: 2, x: 2 }
{ _id: 3, x: 3 }
Compute the value of log2(x)
:
const $ = db.command.aggregate
let res = await db.collection('curve').aggregate()
.project({
log: $.log(['$x', 2])
})
.end()
The returned results are as follows:
{ _id: 1, log: 0 }
{ _id: 2, log: 1 }
{ _id: 3, log: 1.58496250072 }
Calculates the log value of the given number in log base 10.
The syntax is as follows:
db.command.aggregate.log(<number>)
<number>
can be any expression that resolves to a non-negative number.
log10
is equivalent to the log
method where the second parameter is fixed to 10.
Calculates the log value of the given number at log base 10.
The syntax is as follows:
db.command.aggregate.log(<number>)
<number>
can be any expression that resolves to a non-negative number.
log10
is equivalent to the log
method where the second parameter is fixed to 10.
The modulo operation takes the modulo value of the number.
The syntax is as follows:
db.command.aggregate.mod([<dividend>, <divisor>])
The first number is the dividend and the second number is the divisor. The argument can be any expression that resolves to a number.
Suppose the collection shopping
has the following records:
{ _id: 1, bags: 3, items: 5 }
{ _id: 2, bags: 2, items: 8 }
{ _id: 3, bags: 5, items: 16 }
Each record takes the remainder of dividing items
by bags
(items % bags
):
const $ = db.command.aggregate
let res = await db.collection('shopping').aggregate()
.project({
overflow: $.mod(['$items', '$bags'])
})
.end()
The returned results are as follows:
{ _id: 1, overflow: 2 }
{ _id: 2, overflow: 0 }
{ _id: 3, overflow: 1 }
Takes the result of multiplying the passed numeric arguments.
The syntax is as follows:
db.command.aggregate.multiply([<expression1>, <expression2>, ...])
The argument can be any expression that resolves to a number.
Suppose the collection fruits
has the following records:
{ "_id": 1, "name": "apple", "price": 10, "quantity": 100 }
{ "_id": 2, "name": "orange", "price": 15, "quantity": 50 }
{ "_id": 3, "name": "lemon", "price": 5, "quantity": 20 }
Find the total value of each fruit:
const $ = db.command.aggregate
let res = await db.collection('fruits').aggregate()
.project({
name: 1,
total: $.multiply(['$price', '$quantity']),
})
.end()
The returned results are as follows:
{ "_id": 1, "name": "apple", "total": 1000 }
{ "_id": 2, "name": "orange", "total": 750 }
{ "_id": 3, "name": "lemo", "total": 100 }
Raises the exponential power of a given base.
The syntax is as follows:
db.command.aggregate.pow([<base>, <exponent>])
The argument can be any expression that resolves to a number.
Suppose the collection stats
has the following records:
{ "_id": 1, "x": 2, "y": 3 }
{ "_id": 2, "x": 5, "y": 7 }
{ "_id": 3, "x": 10, "y": 20 }
Find the sum of the squares of x
and y
:
const $ = db.command.aggregate
let res = await db.collection('stats').aggregate()
.project({
sumOfSquares: $.add([$.pow(['$x', 2]), $.pow(['$y', 2])]),
})
.end()
The returned results are as follows:
{ "_id": 1, "sumOfSquares": 13 }
{ "_id": 2, "sumOfSquares": 74 }
{ "_id": 3, "sumOfSquares": 500 }
Find the square root.
The syntax is as follows:
db.command.aggregate.sqrt([<number>])
The argument can be any expression that resolves to a non-negative number.
Suppose the collection of right triangles triangle
has the following records:
{ "_id": 1, "x": 2, "y": 3 }
{ "_id": 2, "x": 5, "y": 7 }
{ "_id": 3, "x": 10, "y": 20 }
Assuming x
and y
are two right-angled sides, find the length of the hypotenuse:
const $ = db.command.aggregate
let res = await db.collection('triangle').aggregate()
.project({
len: $.sqrt([$.add([$.pow(['$x', 2]), $.pow(['$y', 2])])]),
})
.end()
The returned results are as follows:
{ "_id": 1, "len": 3.605551275463989 }
{ "_id": 2, "len": 8.602325267042627 }
{ "_id": 3, "len": 22.360679774997898 }
Subtracts two numbers and returns the difference, or subtracts two dates and returns the milliseconds difference, or subtracts a number from a date and returns the date of the result.
The syntax is as follows:
db.command.aggregate.subtract([<expression1>, <expression2>])
The argument can be any expression that resolves to a number or date.
Suppose the collection scores
has the following records:
{ "_id": 1, "max": 10, "min": 1 }
{ "_id": 2, "max": 7, "min": 5 }
{ "_id": 3, "max": 6, "min": 6 }
Find the difference between max
and min
for each record. :
const $ = db.command.aggregate
let res = await db.collection('scores').aggregate()
.project({
diff: $.subtract(['$max', '$min'])
})
.end()
The returned results are as follows:
{ "_id": 1, "diff": 9 }
{ "_id": 2, "diff": 2 }
{ "_id": 3, "diff": 0 }
Truncate numbers to integers.
The syntax is as follows:
db.command.aggregate.trunc(<number>)
The argument can be any expression that resolves to a number.
Suppose the collection scores
has the following records:
{ "_id": 1, "value": 1.21 }
{ "_id": 2, "value": 3.83 }
{ "_id": 3, "value": -4.94 }
const $ = db.command.aggregate
let res = await db.collection('scores').aggregate()
.project({
int: $.trunc('$value')
})
.end()
The returned results are as follows:
{ "_id": 1, "value": 1 }
{ "_id": 2, "value": 3 }
{ "_id": 3, "value": -4 }
Returns the element at the index of the specified array.
The syntax is as follows:
db.command.aggregate.arrayElemAt([<array>, <index>])
<array>
can be any expression that resolves to an array.
<index>
can be any expression that resolves to an integer. If positive, arrayElemAt
returns the element at index
position, if negative, arrayElemAt
returns the element at index
position from the end of the array.
Suppose the collection exams
has the following records:
{ "_id": 1, "scores": [80, 60, 65, 90] }
{ "_id": 2, "scores": [78] }
{ "_id": 3, "scores": [95, 88, 92] }
Find the sum of the scores for each first test and the final score:
const $ = db.command.aggregate
let res = await db.collection('exams').aggregate()
.project({
first: $.arrayElemAt(['$scores', 0]),
last: $.arrayElemAt(['$scores', -1]),
})
.end()
The returned results are as follows:
{ "_id": 1, "first": 80, "last": 90 }
{ "_id": 2, "first": 78, "last": 78 }
{ "_id": 3, "first": 95, "last": 92 }
Convert an array to an object.
There are two syntaxes:
The first type: pass in a two-dimensional array, the length of the second dimension must be 2, the first value is the field name, and the second value is the field value
db.command.aggregate.arrayToObject([
[<key1>, <value1>],
[<key2>, <value2>],
...
])
The second: pass in an array of objects, each object must contain the fields k
and v
, specifying the field name and field value respectively
db.command.aggregate.arrayToObject([
{ "k": <key1>, "v": <value1> },
{ "k": <key2>, "v": <value2> },
...
])
Arguments passed to arrayToObject
can be resolved to one of the above two notations.
Suppose the collection shops
has the following records:
{ "_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 } ] }
Convert an array to an object:
const $ = db.command.aggregate
let res = await db.collection('shops').aggregate()
.project({
sales: $.arrayToObject('$sales'),
})
.end()
The returned results are as follows:
{ "_id": 1, "sales": { "max": 100, "min": 50 } }
{ "_id": 2, "sales": { "max": 70, "min": 60 } }
{ "_id": 3, "sales": { "max": 50, "min": 30 } }
Concatenates multiple arrays into one array.
The syntax is as follows:
db.command.aggregate.concatArrays([ <array1>, <array2>, ... ])
The argument can be any expression that resolves to an array.
Suppose the collection items
has the following records:
{ "_id": 1, "fruits": [ "apple" ], "vegetables": [ "carrot" ] }
{ "_id": 2, "fruits": [ "orange", "lemon" ], "vegetables": [ "cabbage" ] }
{ "_id": 3, "fruits": [ "strawberry" ], "vegetables": [ "spinach" ] }
const $ = db.command.aggregate
let res = await db.collection('items').aggregate()
.project({
list: $.concatArrays(['$fruits', '$vegetables']),
})
.end()
The returned results are as follows:
{ "_id": 1, "list": [ "apple", "carrot" ] }
{ "_id": 2, "list": [ "orange", "lemon", "cabbage" ] }
{ "_id": 3, "list": [ "strawberry", "spinach" ] }
Returns a subset of an array that satisfies the condition based on the given condition.
The syntax is as follows:
db.command.aggregate.filter({
input: <array>,
as: <string>,
cond: <expression>
})
Fields | Description |
---|---|
input | An expression that can be parsed as an array |
as | optional, a variable used to represent each element of the array, the default is thYes |
cond | An expression that can be parsed as a boolean value to determine whether each element satisfies the condition, the name of each element is determined by the as parameter (the parameter name needs to be prefixed with $$, such as $$this) |
The argument can be any expression that resolves to an array.
Suppose the collection fruits
has the following records:
{
"_id": 1,
"stock": [
{ "name": "apple", "price": 10 },
{ "name": "orange", "price": 20 }
],
}
{
"_id": 2,
"stock": [
{ "name": "lemon", "price": 15 },
],
}
const _ = db.command
const $ = db.command.aggregate
let res = await db.collection('fruits').aggregate()
.project({
stock: $.filter({
input: '$stock',
as: 'item',
cond: $.gte(['$$item.price', 15])
})
})
.end()
The returned results are as follows:
{ "_id": 1, "stock": [ { "name": "orange", "price": 20} ] }
{ "_id": 2, "stock": [ { "name": "lemon", "price": 15 } ] }
Given a value and an array, return true
if the value is in the array, false
otherwise.
The syntax is as follows:
db.command.aggregate.in([<value>, <array>])
<value>
can be any expression.
<array>
can be any expression that resolves to an array.
Suppose the collection shops
has the following records:
{ "_id": 1, "topsellers": ["bread", "ice cream", "butter"] }
{ "_id": 2, "topsellers": ["ice cream", "cheese", "yagurt"] }
{ "_id": 3, "topsellers": ["croissant", "cucumber", "coconut"] }
Mark the record for the highest-selling item containing ice cream
.
const $ = db.command.aggregate
let res = await db.collection('price').aggregate()
.project({
included: $.in(['ice cream', '$topsellers'])
})
.end()
The returned results are as follows:
{ "_id": 1, "included": true }
{ "_id": 2, "included": true }
{ "_id": 3, "included": false }
Finds the index of the first element in the array that is equal to the given value, or returns -1 if not found.
The syntax is as follows:
db.command.aggregate.indexOfArray([ <array expression>, <search expression>, <start>, <end> ])
Field | Type | Description |
---|---|---|
- | string | An expression that resolves to an array, if it resolves to null, indexOfArray returns null |
- | string | Conditional match expression applied to each element of the data |
- | integer | optional, used to specify the starting index of the search, must be a non-negative integer |
- | integer | is optional, it is used to specify the end index of the search, it must be a non-negative integer, and should also be specified when is specified, otherwise the default is used as |
The argument can be any expression that resolves to an array.
Suppose the collection stats
has the following records:
{
"_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.aggregate
let res = await db.collection('stats').aggregate()
.project({
index: $.indexOfArray(['$sales', 2, 2])
})
.end()
The returned results are as follows:
{ "_id": 1, "index": 2 }
{ "_id": 2, "index": 4 }
{ "_id": 3, "index": -1 }
Checks whether the given expression is an array, returning a boolean value.
The syntax is as follows:
db.command.aggregate.isArray(<expression>)
Arguments can be arbitrary expressions.
Suppose the collection stats
has the following records:
{
"_id": 1,
"base": 10,
"sales": [ 1, 6, 2, 2, 5 ]
}
{
"_id": 2,
"base": 1,
"sales": 100
}
Calculates the total sales, taking sales * base
if sales
is a number, or the product of the sum of the elements of the array and base
if sales
is an array.
const $ = db.command.aggregate
let res = await db.collection('stats').aggregate()
.project({
sum: $.cond({
if: $.isArray('$sales'),
then: $.multiply([$.sum(['$sales']), '$base']),
else: $.multiply(['$sales', '$base']),
})
})
.end()
The returned results are as follows:
{ "_id": 1, "sum": 160 }
{ "_id": 2, "sum": 100 }
Similar to the map
method on JavaScript Array, converts each element of the given array according to the given conversion method to obtain a new array.
The syntax is as follows:
db.command.aggregate.map({
input: <expression>,
as: <string>,
in: <expression>
})
Fields | Description |
---|---|
input | An expression that can be parsed as an array |
as | optional, a variable used to represent each element of the array, the default is thYes |
in | an expression that can be applied to each element of a given array, the name of each element is determined by the as parameter (the parameter name needs to be prefixed with $$, such as $$this) |
Suppose the collection stats
has the following records:
{
"_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 ]
}
truncate individual numbers to integers, then sum
const $ = db.command.aggregate
let res = await db.collection('stats').aggregate()
.project({
truncated: $.map({
input: '$sales',
as: 'num',
in: $.trunc('$$num'),
})
})
.project({
total: $.sum('$truncated')
})
.end()
The returned results are as follows:
{ "_id": 1, "total": 16 }
{ "_id": 2, "total": 19 }
Convert an object to an array. The method turns each key-value pair of the object into an element of the output array, with elements of the form { k: <key>, v: <value> }
.
The syntax is as follows:
db.command.aggregate.objectToArray(<object>)
Suppose the collection items
has the following records:
{ "_id": 1, "attributes": { "color": "red", "price": 150 } }
{ "_id": 2, "attributes": { "color": "blue", "price": 50 } }
{ "_id": 3, "attributes": { "color": "yellow", "price": 10 } }
const $ = db.command.aggregate
let res = await db.collection('items').aggregate()
.project({
array: $.objectToArray('$attributes')
})
.end()
The returned results are as follows:
{ "_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 }] }
Returns a set of generated sequence numbers. Given a start value, an end value, and a non-zero step size, range
returns a sequence that starts at the start value and gradually increases with the given step size, but not the end value.
The syntax is as follows:
db.command.aggregate.range([<start>, <end>, <non-zero step>])
Fields | Description |
---|---|
start | start value, an expression that resolves to an integer |
end | The end value, an expression that resolves to an integer |
non-zero step | optional, step size, an expression that resolves to a non-zero integer, defaults to 1 |
Suppose the collection stats
has the following records:
{ "_id": 1, "max": 52 }
{ "_id": 2, "max": 38 }
const $ = db.command.aggregate
db.collection('stats').aggregate()
.project({
points: $.range([0, '$max', 10])
})
.end()
The returned results are as follows:
{ "_id": 1, "points": [0, 10, 20, 30, 40, 50] }
{ "_id": 2, "points": [0, 10, 20, 30] }
Similar to JavaScript's reduce
method, which applies an expression to each element of an array and then normalizes it to a single element.
The syntax is as follows:
db.command.aggregate.reduce({
input: <array>
initialValue: <expression>,
in: <expression>
})
Fields | Description |
---|---|
input | input array, which can be any expression that resolves to an array |
initialValue | Initial Value |
in | The expression used to act on each element, there are two variables available in in, value is the variable representing the accumulated value, this is the variable representing the current array element |
Simple String Concatenation
Suppose the collection player
has the following records:
{ "_id": 1, "fullname": [ "Stephen", "Curry" ] }
{ "_id": 2, "fullname": [ "Klay", "Thompsom" ] }
Get the full name of each player, prefixed with Player:
:
const $ = db.command.aggregate
let res = await db.collection('player').aggregate()
.project({
info: $.reduce({
input: '$fullname',
initialValue: 'Player:',
in: $.concat(['$$value', ' ', '$$this']),
})
})
.end()
The returned results are as follows:
{ "_id": 1, "info": "Player: Stephen Curry" }
{ "_id": 2, "info": "Player: Klay Thompson" }
Get the full name of each player, unprefixed:
const $ = db.command.aggregate
let res = await db.collection('player').aggregate()
.project({
name: $.reduce({
input: '$fullname',
initialValue: '',
in: $.concat([
'$$value',
$.cond({
if: $.eq(['$$value', '']),
then: '',
else: ' ',
}),
'$$this',
]),
})
})
.end()
The returned results are as follows:
{ "_id": 1, "name": "Stephen Curry" }
{ "_id": 2, "name": "Klay Thompson" }
Returns the reversed form of the given array.
The syntax is as follows:
db.command.aggregate.reverseArray(<array>)
Arguments can be arbitrarily parsed as array expressions.
Suppose the collection stats
has the following records:
{
"_id": 1,
"sales": [ 1, 2, 3, 4, 5 ]
}
Take sales
in reverse order:
const $ = db.command.aggregate
let res = await db.collection('stats').aggregate()
.project({
reversed: $.reverseArray('$sales'),
})
.end()
The returned results are as follows:
{ "_id": 1, "reversed": [5, 4, 3, 2, 1] }
Returns the length of the array.
The syntax is as follows:
db.command.aggregate.size(<array>)
<array>
can be any expression that resolves to an array.
Suppose the collection shops
has the following records:
{ "_id": 1, "staff": [ "John", "Middleton", "George" ] }
{ "_id": 2, "staff": [ "Steph", "Jack" ] }
Count the number of employees in each store:
const $ = db.command.aggregate
let res = await db.collection('shops').aggregate()
.project({
totalStaff: $.size('$staff')
})
.end()
The returned results are as follows:
{ "_id": 1, "totalStaff": 3 }
{ "_id": 2, "totalStaff": 2 }
Similar to JavaScript's slice
method. Returns the specified subset of the given array.
There are two syntaxes:
Return n
elements from the beginning or end:
db.command.aggregate.slice([<array>, <n>])
Returns n
elements from the specified position counted as the beginning of the array, backwards or forwards:
db.command.aggregate.slice([<array>, <position>, <n>])
<array>
can be any expression that resolves to an array.
<position>
can be any expression that resolves to an integer. If positive, start the array with the <position>
-th element of the array; if <position>
is longer than the array length, slice
returns an empty array. If it is a negative number, the last <position>
element of the array is used as the start of the array; if the absolute value of <position>
is greater than the length of the array, the start position is the start position of the array.
<n>
can be any expression that resolves to an integer. If <position>
is provided, <n>
must be a positive integer. If positive, slice
returns the first n
elements. If negative, slice
returns the last n
elements.
Suppose the collection people
has the following records:
{ "_id": 1, "hobbies": [ "basketball", "football", "tennis", "badminton" ] }
{ "_id": 2, "hobbies": [ "golf", "handball" ] }
{ "_id": 3, "hobbies": [ "table tennis", "swimming", "rowing" ] }
Unity returns the first two hobbies:
const $ = db.command.aggregate
let res = await db.collection('fruits').aggregate()
.project({
hobbies: $.slice(['$hobbies', 2]),
})
.end()
The returned results are as follows:
{ "_id": 1, "hobbies": [ "basketball", "football" ] }
{ "_id": 2, "hobbies": [ "golf", "handball" ] }
{ "_id": 3, "hobbies": [ "table tennis", "swimming" ] }
The elements of the same serial number in the second-dimensional array of the two-dimensional array are assembled into a new array and then assembled into a new two-dimensional array. For example, [ [ 1, 2, 3 ], [ "a", "b", "c" ] ]
can be converted to [ [ 1, "a" ], [ 2, "b" ], [ 3 , "c" ] ]
.
The syntax is as follows:
db.command.aggregate.zip({
inputs: [<array1>, <array2>, ...],
useLongestLength: <boolean>,
defaults: <array>
})
inputs
is a two-dimensional array (inputs
cannot be a field reference), where the expression for each element (this can be a field reference) can be resolved as an array. If either of these expressions returns null
, <inputs>
also returns null
. An error is returned if either of the expressions does not point to a valid field / resolves to an array / resolves to null
.
useLongestLength
determines whether the length of the output array takes the length of the longest array in the input array. The default is false
, that is, the length of the shortest array in the input array is the length of each element of the output array.
defaults
is an array that specifies the default values for each element of the array to use if the input arrays are of different lengths. If this field is specified, useLongestLength
must be specified, otherwise an error will be returned. If useLongestLength
is true
but defaults
is empty or not specified, zip
uses null
as the default default value for array elements. When specifying default values for each element, the length of the defaults
array must be the maximum length of the input array.
Suppose the collection stats
has the following records:
{ "_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] ] }
Only transmit inputs
const $ = db.command.aggregate
let res = await db.collection('items').aggregate()
.project({
zip: $.zip({
inputs: [
'$zip1', // 字段引用
'$zip2',
'$zip3',
],
})
})
.end()
The returned results are as follows:
{ "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] }
{ "_id": 2, "zip": [ [1, 3, 4] ] }
{ "_id": 3, "zip": null }
set useLongestLength
If useLongestLength
is set to true
:
const $ = db.command.aggregate
let res = await db.collection('items').aggregate()
.project({
zip: $.zip({
inputs: [
'$zip1', // 字段引用
'$zip2',
'$zip3',
],
useLongestLength: true,
})
})
.end()
The returned results are as follows:
{ "_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 }
set defaults
const $ = db.command.aggregate
let res = await db.collection('items').aggregate()
.project({
zip: $.zip({
inputs: [
'$zip1', // 字段引用
'$zip2',
'$zip3',
],
useLongestLength: true,
defaults: [-300, -200, -100],
})
})
.end()
The returned results are as follows:
{ "_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 }
Given multiple expressions, and
returns true
only if all expressions return true
, and false
otherwise.
The syntax is as follows:
db.command.aggregate.and([<expression1>, <expression2>, ...])
If the expression returns false
, null
, 0
, or undefined
, the expression resolves to false
, otherwise it is considered true
for other return values.
Suppose the collection price
has the following records:
{ "_id": 1, "min": 10, "max": 100 }
{ "_id": 2, "min": 60, "max": 80 }
{ "_id": 3, "min": 30, "max": 50 }
Find records where min
is greater than or equal to 30 and max
is less than or equal to 80.
const $ = db.command.aggregate
let res = await db.collection('price').aggregate()
.project({
fullfilled: $.and([$.gte(['$min', 30]), $.lte(['$max', 80])])
})
.end()
The returned results are as follows:
{ "_id": 1, "fullfilled": false }
{ "_id": 2, "fullfilled": true }
{ "_id": 3, "fullfilled": true }
Given an expression, not
returns false
if the expression returns true
, and true
otherwise. Note that expressions cannot be logical expressions (and
, or
, nor
, not
).
The syntax is as follows:
db.command.aggregate.not(<expression>)
If the expression returns false
, null
, 0
, or undefined
, the expression resolves to false
, otherwise it is considered true
for other return values.
Suppose the collection price
has the following records:
{ "_id": 1, "min": 10, "max": 100 }
{ "_id": 2, "min": 60, "max": 80 }
{ "_id": 3, "min": 30, "max": 50 }
Find records whose min
is not greater than 40.
const $ = db.command.aggregate
let res = await db.collection('price').aggregate()
.project({
fullfilled: $.not($.gt(['$min', 40]))
})
.end()
The returned results are as follows:
{ "_id": 1, "fullfilled": true }
{ "_id": 2, "fullfilled": false }
{ "_id": 3, "fullfilled": true }
Given multiple expressions, or
returns true
if any of the expressions returns true
, otherwise it returns false
.
The syntax is as follows:
db.command.aggregate.or([<expression1>, <expression2>, ...])
If the expression returns false
, null
, 0
, or undefined
, the expression resolves to false
, otherwise it is considered true
for other return values.
Suppose the collection price
has the following records:
{ "_id": 1, "min": 10, "max": 100 }
{ "_id": 2, "min": 50, "max": 60 }
{ "_id": 3, "min": 30, "max": 50 }
Find records where min
is less than 40 or max
is greater than 60.
const $ = db.command.aggregate
let res = await db.collection('price').aggregate()
.project({
fullfilled: $.or([$.lt(['$min', 40]), $.gt(['$max', 60])])
})
.end()
The returned results are as follows:
{ "_id": 1, "fullfilled": true }
{ "_id": 2, "fullfilled": false }
{ "_id": 3, "fullfilled": true }
Given two values, return their comparison value:
If the first value is less than the second value, return -1 Returns 1 if the first value is greater than the second value Returns 0 if the two values are equal
The syntax is as follows:
db.command.aggregate.cmp([<expression1>, <expression2>])
Suppose the collection price
has the following records:
{ "_id": 1, "shop1": 10, "shop2": 100 }
{ "_id": 2, "shop1": 80, "shop2": 20 }
{ "_id": 3, "shop1": 50, "shop2": 50 }
Find the price comparison of each item in shop1
and shop2
.
const $ = db.command.aggregate
let res = await db.collection('price').aggregate()
.project({
compare: $.cmp(['$shop1', '$shop2']))
})
.end()
The returned results are as follows:
{ "_id": 1, "compare": -1 }
{ "_id": 2, "compare": 1 }
{ "_id": 3, "compare": 0 }
Matches two values and returns true
if they are equal, false
otherwise.
The syntax is as follows:
db.command.aggregate.eq([<value1>, <value2>])
Suppose the collection price
has the following records:
{ "_id": 1, "value": 10 }
{ "_id": 2, "value": 80 }
{ "_id": 3, "value": 50 }
Find records with value
equal to 50.
const $ = db.command.aggregate
let res = await db.collection('price').aggregate()
.project({
matched: $.eq(['$value', 50])
})
.end()
The returned results are as follows:
{ "_id": 1, "matched": false }
{ "_id": 2, "matched": false }
{ "_id": 3, "matched": true }
Matches two values and returns true
if the former is greater than the latter, false
otherwise.
The syntax is as follows:
db.command.aggregate.gt([<value1>, <value2>])
Suppose the collection price
has the following records:
{ "_id": 1, "value": 10 }
{ "_id": 2, "value": 80 }
{ "_id": 3, "value": 50 }
Check if value
is greater than 50.
const $ = db.command.aggregate
db.collection('price').aggregate()
.project({
matched: $.gt(['$value', 50])
})
.end()
The returned results are as follows:
{ "_id": 1, "matched": false }
{ "_id": 2, "matched": true }
{ "_id": 3, "matched": false }
Matches two values and returns true
if the former is greater than or equal to the latter, false
otherwise.
The syntax is as follows:
db.command.aggregate.gte([<value1>, <value2>])
Suppose the collection price
has the following records:
{ "_id": 1, "value": 10 }
{ "_id": 2, "value": 80 }
{ "_id": 3, "value": 50 }
Check if value
is greater than or equal to 50.
const $ = db.command.aggregate
let res = await b.collection('price').aggregate()
.project({
matched: $.gte(['$value', 50])
})
.end()
The returned results are as follows:
{ "_id": 1, "matched": false }
{ "_id": 2, "matched": true }
{ "_id": 3, "matched": true }
Matches two values and returns true
if the former is less than the latter, false
otherwise.
The syntax is as follows:
db.command.aggregate.lt([<value1>, <value2>])
Suppose the collection price
has the following records:
{ "_id": 1, "value": 10 }
{ "_id": 2, "value": 80 }
{ "_id": 3, "value": 50 }
Check if value
is less than 50.
const $ = db.command.aggregate
let res = await db.collection('price').aggregate()
.project({
matched: $.lt(['$value', 50])
})
.end()
The returned results are as follows:
{ "_id": 1, "matched": true }
{ "_id": 2, "matched": false }
{ "_id": 3, "matched": false }
Matches two values and returns true
if the former is less than or equal to the latter, false
otherwise.
The syntax is as follows:
db.command.aggregate.lte([<value1>, <value2>])
Suppose the collection price
has the following records:
{ "_id": 1, "value": 10 }
{ "_id": 2, "value": 80 }
{ "_id": 3, "value": 50 }
Check if value
is less than 50.
const $ = db.command.aggregate
let res = await db.collection('price').aggregate()
.project({
matched: $.lte(['$value', 50])
})
.end()
The returned results are as follows:
{ "_id": 1, "matched": true }
{ "_id": 2, "matched": false }
{ "_id": 3, "matched": true }
Matches two values, returning true
if they are not equal, false
otherwise.
The syntax is as follows:
db.command.aggregate.neq([<value1>, <value2>])
Suppose the collection price
has the following records:
{ "_id": 1, "value": 10 }
{ "_id": 2, "value": 80 }
{ "_id": 3, "value": 50 }
Find records where value
is not equal to 50.
const $ = db.command.aggregate
let res = await db.collection('price').aggregate()
.project({
matched: $.neq(['$value', 50])
})
.end()
The returned results are as follows:
{ "_id": 1, "matched": true }
{ "_id": 2, "matched": true }
{ "_id": 3, "matched": false }
Evaluates a Boolean expression, returning one of the two specified values.
cond
is used as follows:
cond({ if: <布尔表达式>, then: <真值>, else: <假值> })
or:
cond([ <布尔表达式>, <真值>, <假值> ])
In both forms, the three arguments (if
, then
, else
) are required.
$cond
will return <true value>
if the boolean expression is true, otherwise it will return <false value>
Suppose the collection items
records as follows:
{ "_id": "0", "name": "item-a", "amount": 100 }
{ "_id": "1", "name": "item-b", "amount": 200 }
{ "_id": "2", "name": "item-c", "amount": 300 }
We can use cond
to generate a new field discount
based on the amount
field:
const $ = db.command.aggregate
let res = await db.collection('items').aggregate()
.project({
name: 1,
discount: $.cond({
if: $.gte(['$amount', 200]),
then: 0.7,
else: 0.9
})
})
.end()
The output is as follows:
{ "_id": "0", "name": "item-a", "discount": 0.9 }
{ "_id": "1", "name": "item-b", "discount": 0.7 }
{ "_id": "2", "name": "item-c", "discount": 0.7 }
Evaluates the given expression and returns an alternate value if the expression result is null, undefined, or does not exist; otherwise, returns the original value.
ifNull
is used as follows:
ifNull([ <表达式>, <替代值> ])
Suppose the collection items
records as follows:
{ "_id": "0", "name": "A", "description": "这是商品A" }
{ "_id": "1", "name": "B", "description": null }
{ "_id": "2", "name": "C" }
We can use ifNull
to add an alternative value for documents where the desc
field does not exist, or for which the desc
field is null
.
const $ = db.command.aggregate
let res = await db.collection('items').aggregate()
.project({
_id: 0,
name: 1,
description: $.ifNull(['$description', '商品描述空缺'])
})
.end()
The output is as follows:
{ "name": "A", "description": "这是商品A" }
{ "name": "B", "description": "商品描述空缺" }
{ "name": "C", "description": "商品描述空缺" }
Calculate the return value according to the given switch-case-default
,
switch
is used as follows:
switch({
branches: [
case: <表达式>, then: <表达式>,
case: <表达式>, then: <表达式>,
...
],
default: <表达式>
})
Suppose the collection items
records as follows:
{ "_id": "0", "name": "item-a", "amount": 100 }
{ "_id": "1", "name": "item-b", "amount": 200 }
{ "_id": "2", "name": "item-c", "amount": 300 }
We can use switch
to generate a new field discount
based on the amount
field:
const $ = db.command.aggregate
let res = await db.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()
The output is as follows:
{ "_id": "0", "name": "item-a", "discount": 1 }
{ "_id": "1", "name": "item-b", "discount": 0.9 }
{ "_id": "2", "name": "item-c", "discount": 0.8 }
Notice
timezone
in the following date operators supports the following formstimezone: "Asia/Shanghai" // Asia/Shanghai时区
timezone: "+08" // utc+8时区
timezone: "+08:30" // 时区偏移8小时30分
timezone: "+0830" // 时区偏移8小时30分,同上
Given information about a date, constructs and returns a date object.
The syntax is as follows:
db.command.aggregate.dateFromParts({
year: <year>,
month: <month>,
day: <day>,
hour: <hour>,
minute: <minute>,
second: <second>,
millisecond: <ms>,
timezone: <tzExpression>
})
You can also use the ISO 8601 standard:
db.command.aggregate.dateFromParts({
isoWeekYear: <year>,
isoWeek: <week>,
isoDayOfWeek: <day>,
hour: <hour>,
minute: <minute>,
second: <second>,
millisecond: <ms>,
timezone: <tzExpression>
})
const $ = db.command.aggregate
let res = await db
.collection('dates')
.aggregate()
.project({
_id: 0,
date: $.dateFromParts({
year: 2017,
month: 2,
day: 8,
hour: 12,
timezone: 'America/New_York'
}),
})
.end()
The output is as follows:
{
"date": ISODate("2017-02-08T17:00:00.000Z")
}
Convert a date/time string to a date object
The syntax is as follows:
db.command.aggregate.dateFromString({
dateString: <dateStringExpression>,
timezone: <tzExpression>
})
const $ = db.command.aggregate
let res = await db
.collection('dates')
.aggregate()
.project({
_id: 0,
date: $.dateFromString({
dateString: "2019-05-14T09:38:51.686Z"
})
})
.end()
The output is as follows:
{
"date": ISODate("2019-05-14T09:38:51.686Z")
}
Formats a date object as a string according to the specified expression.
The call form of dateToString
is as follows:
db.command.aggregate.dateToString({
date: <日期表达式>,
format: <格式化表达式>,
timezone: <时区表达式>,
onNull: <空值表达式>
})
The following is a detailed description of the four expressions:
Name | Description |
---|---|
Date Expression | Required. Specifies that the field value should be a date that can be converted to a string. |
Formatting Expression | Optional. It can be any valid string containing a "format specifier". |
Timezone expression | Optional. Specifies the time zone for the result of the operation. It can parse strings in the format UTC Offset or Olson Timezone Identifier. |
null expression | optional. When <date_expression> returns null or does not exist, the value specified by this expression will be returned. |
The following is a detailed description of the format specifiers:
specifier | description | legal values |
---|---|---|
%d | Day of the month (2 digits, 0-padded) | 01 - 31 |
%G | Year in ISO 8601 format | 0000 - 9999 |
%H | hour (2 digits, 0-padded, 24-hour clock) | 00 - 23 |
%j | Day of the year (3 digits, 0-padded) | 001 - 366 |
%L | milliseconds (3 digits, 0-padded) | 000 - 999 |
%m | month (2 digits, 0-padded) | 01 - 12 |
%M | minutes (2 digits, 0-padded) | 00 - 59 |
%S | Seconds (2 digits, padded with 0s) | 00 - 60 |
%w | Day of the week | 1 - 7 |
%u | Day of the week in ISO 8601 format | 1 - 7 |
%U | week of year (2 digits, 0-padded) | 00 - 53 |
%V | week of year in ISO 8601 format | 1 - 53 |
%Y | Year (4 digits, 0-padded) | 0000 - 9999 |
%z | Timezone offset from UTC | +/-[hh][mm] |
%Z | timezone offset from UTC in minutes | +/-mmm |
%% | Percent sign as character | % |
Suppose the collection students
has the following records:
{ "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" }
Format Date
The following is the value of the date
field, formatted as a string like year-month-date
:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.project({
_id: 0,
formatDate: $.dateToString({
date: '$date',
format: '%Y-%m-%d'
})
})
.end()
The results returned are as follows:
{ "formatDate": "1999-12-11" }
{ "formatDate": "1998-11-10" }
{ "formatDate": "1997-10-09" }
Time zone time
The following is an example of formatting a date
field value to Shanghai time zone time:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.project({
_id: 0,
formatDate: $.dateToString({
date: '$date',
format: '%H:%M:%S',
timezone: 'Asia/Shanghai'
})
})
.end()
The results returned are as follows:
{ "formatDate": "00:00:00" }
{ "formatDate": "00:00:00" }
{ "formatDate": "00:00:00" }
Default value for missing cases
When the specified <date_expression>
returns empty or does not exist, you can set the default value in the absence of:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.project({
_id: 0,
formatDate: $.dateToString({
date: '$empty',
onNull: 'null'
})
})
.end()
The results returned are as follows:
{ "formatDate": "null" }
{ "formatDate": "null" }
{ "formatDate": "null" }
Returns the number of days (day of the month) corresponding to the date field, as a number between 1 and 31.
The interface has the following two usages, the syntax is as follows:
db.command.aggregate.dayOfMonth(<日期字段>)
db.command.aggregate.dayOfMonth({date:<日期字段>,timezone:<时区>})
Suppose the collection dates
has the following documents:
{
"_id": 1,
"date": ISODate("2019-05-14T09:38:51.686Z")
}
We use dayOfMonth()
to project the date
field to get the corresponding date:
const $ = db.command.aggregate
let res = await db
.collection('dates')
.aggregate()
.project({
_id: 0,
dayOfMonth: $.dayOfMonth('$date')
})
.end()
The output is as follows:
{
"dayOfMonth": 14
}
Returns the number of days (day of the week) corresponding to the date field, as an integer between 1 (Sunday) and 7 (Saturday).
NOTE: Sunday is the 1st day of the week
The interface has the following two usages, the syntax is as follows:
db.command.aggregate.dayOfWeek(<日期字段>)
db.command.aggregate.dayOfWeek({date:<日期字段>,timezone:<时区>})
Suppose the collection dates
has the following documents:
{
"_id": 1,
"date": ISODate("2019-05-14T09:38:51.686Z")
}
We use dayOfWeek()
to project the date
field to get the corresponding day (day of the week):
const $ = db.command.aggregate
let res = await db
.collection('dates')
.aggregate()
.project({
_id: 0,
dayOfWeek: $.dayOfWeek('$date')
})
.end()
The output is as follows:
{
"dayOfWeek": 3
}
Returns the number of days (day of the year) corresponding to the date field, as an integer between 1 and 366.
The interface has the following two usages, the syntax is as follows:
db.command.aggregate.dayOfYear(<日期字段>)
db.command.aggregate.dayOfYear({date:<日期字段>,timezone:<时区>})
Suppose the collection dates
has the following documents:
{
"_id": 1,
"date": ISODate("2019-05-14T09:38:51.686Z")
}
We use dayOfYear()
to project the date
field to get the corresponding number of days (day of the year):
const $ = db.command.aggregate
let res = await db
.collection('dates')
.aggregate()
.project({
_id: 0,
dayOfYear: $.dayOfYear('$date')
})
.end()
The output is as follows:
{
"dayOfYear": 134
}
Returns the hour corresponding to the date field, as an integer between 0 and 23.
The interface has the following two usages, the syntax is as follows:
db.command.aggregate.hour(<日期字段>)
db.command.aggregate.hour({date:<日期字段>,timezone:<时区>})
Suppose the collection dates
has the following documents:
{
"_id": 1,
"date": ISODate("2019-05-14T09:38:51.686Z")
}
We use hour()
to project the date
field to get the corresponding hour:
const $ = db.command.aggregate
let res = await db
.collection('dates')
.aggregate()
.project({
_id: 0,
hour: $.hour('$date')
})
.end()
The output is as follows:
{
"hour": 9
}
Returns the ISO 8601 standard day number (day of the week) for the date field, as an integer between 1 (Monday) and 7 (Sunday).
The interface has the following two usages, the syntax is as follows:
db.command.aggregate.isoDayOfWeek(<日期字段>)
db.command.aggregate.isoDayOfWeek({date:<日期字段>,timezone:<时区>})
Suppose the collection dates
has the following documents:
{
"_id": 1,
"date": ISODate("2019-05-14T09:38:51.686Z")
}
We use isoDayOfWeek()
to project the date
field to get the corresponding ISO 8601 standard number of days (day of the week):
const $ = db.command.aggregate
let res = await db
.collection('dates')
.aggregate()
.project({
_id: 0,
isoDayOfWeek: $.isoDayOfWeek('$date')
})
.end()
The output is as follows:
{
"isoDayOfWeek": 2
}
Returns the ISO 8601 standard week number (week of the year) for the date field, as an integer between 1 and 53.
According to the ISO 8601 standard, Monday to Sunday are regarded as a week, and the week on which the first Thursday of the current year is located is regarded as the first week of the current year.
For example: January 7, 2016 is the first Thursday of that year, then 2016.01.04 (Monday) to 2016.01.10 (Sunday) is week 1. Similarly, the week number for January 1, 2016 is 53.
The interface has the following two usages, the syntax is as follows:
db.command.aggregate.isoWeek(<日期字段>)
db.command.aggregate.isoWeek({date:<日期字段>,timezone:<时区>})
Suppose the collection dates
has the following documents:
{
"_id": 1,
"date": ISODate("2019-05-14T09:38:51.686Z")
}
We use isoWeek()
to project the date
field to get the corresponding ISO 8601 week number (week of the year):
const $ = db.command.aggregate
let res = await db
.collection('dates')
.aggregate()
.project({
_id: 0,
isoWeek: $.isoWeek('$date')
})
.end()
The output is as follows:
{
"isoWeek": 20
}
Returns the ISO 8601 standard number of days (day of the year) for a date field.
The "year" here starts on the Monday of the first week and ends on the Sunday of the last week.
The interface has the following two usages, the syntax is as follows:
db.command.aggregate.isoWeekYear(<日期字段>)
db.command.aggregate.isoWeekYear({date:<日期字段>,timezone:<时区>})
Suppose the collection dates
has the following documents:
{
"_id": 1,
"date": ISODate("2019-05-14T09:38:51.686Z")
}
We use isoWeekYear()
to project the date
field to get the corresponding ISO 8601 standard number of days (day of the year):
const $ = db.command.aggregate
let res = await db
.collection('dates')
.aggregate()
.project({
_id: 0,
isoWeekYear: $.isoWeekYear('$date')
})
.end()
The output is as follows:
{
"isoWeekYear": 2019
}
Returns the number of milliseconds corresponding to the date field, as an integer between 0 and 999.
The interface has the following two usages, the syntax is as follows:
db.command.aggregate.millisecond(<日期字段>)
db.command.aggregate.millisecond({date:<日期字段>,timezone:<时区>})
Suppose the collection dates
has the following documents:
{
"_id": 1,
"date": ISODate("2019-05-14T09:38:51.686Z")
}
We use millisecond()
to project the date
field to get the corresponding milliseconds:
const $ = db.command.aggregate
let res = await db
.collection('dates')
.aggregate()
.project({
_id: 0,
millisecond: $.millisecond('$date'),
})
.end()
The output is as follows:
{
"millisecond": 686
}
Returns the number of minutes corresponding to the date field, as an integer between 0 and 59.
The interface has the following two usages, the syntax is as follows:
db.command.aggregate.minute(<日期字段>)
db.command.aggregate.minute({date:<日期字段>,timezone:<时区>})
Suppose the collection dates
has the following documents:
{
"_id": 1,
"date": ISODate("2019-05-14T09:38:51.686Z")
}
We use minute()
to project the date
field to get the corresponding minutes:
const $ = db.command.aggregate
let res = await db
.collection('dates')
.aggregate()
.project({
_id: 0,
minute: $.minute('$date')
})
.end()
The output is as follows:
{
"minute": 38
}
Returns the month corresponding to the date field as an integer between 1 and 12.
The interface has the following two usages, the syntax is as follows:
db.command.aggregate.month(<日期字段>)
db.command.aggregate.month({date:<日期字段>,timezone:<时区>})
Suppose the collection dates
has the following documents:
{
"_id": 1,
"date": ISODate("2019-05-14T09:38:51.686Z")
}
We use month()
to project the date
field to get the corresponding month:
const $ = db.command.aggregate
let res = await db
.collection('dates')
.aggregate()
.project({
_id: 0,
month: $.month('$date')
})
.end()
The output is as follows:
{
"month": 5
}
Returns the number of seconds corresponding to the date field, as an integer between 0 and 59, and may be equal to 60 in special cases (leap seconds).
The interface has the following two usages, the syntax is as follows:
db.command.aggregate.second(<日期字段>)
db.command.aggregate.second({date:<日期字段>,timezone:<时区>})
Suppose the collection dates
has the following documents:
{
"_id": 1,
"date": ISODate("2019-05-14T09:38:51.686Z")
}
We use second()
to project the date
field to get the corresponding seconds:
const $ = db.command.aggregate
let res = await db
.collection('dates')
.aggregate()
.project({
_id: 0,
second: $.second('$date')
})
.end()
The output is as follows:
{
"second": 51
}
Returns the week number (week of the year) corresponding to the date field, as an integer between 0 and 53.
Week starts with Sunday, the first Sunday of every year is the start of week 1
, before this day is week 0
.
The interface has the following two usages, the syntax is as follows:
db.command.aggregate.week(<日期字段>)
db.command.aggregate.week({date:<日期字段>,timezone:<时区>})
Suppose the collection dates
has the following documents:
{
"_id": 1,
"date": ISODate("2019-05-14T09:38:51.686Z")
}
We use week()
to project the date
field to get the corresponding week number (week of the year):
const $ = db.command.aggregate
let res = await db
.collection('dates')
.aggregate()
.project({
_id: 0,
week: $.week('$date')
})
.end()
The output is as follows:
{
"week": 19
}
Returns the year corresponding to the date field.
The interface has the following two usages, the syntax is as follows:
db.command.aggregate.year(<日期字段>)
db.command.aggregate.year({date:<日期字段>,timezone:<时区>})
Suppose the collection dates
has the following documents:
{
"_id": 1,
"date": ISODate("2019-05-14T09:38:51.686Z")
}
We use year()
to project the date
field to get the corresponding year:
const $ = db.command.aggregate
let res = await db
.collection('dates')
.aggregate()
.project({
_id: 0,
year: $.year('$date')
})
.end()
The output is as follows:
{
"year": 2019
}
see subtract
Returns the literal of a value directly, without any parsing and processing.
literal
is used as follows:
literal(<值>)
If <value>
is an expression, then literal
will not parse or evaluate the expression, but return the expression directly.
For example, we have an items
collection with the following data:
{ "_id": "0", "price": "$1" }
{ "_id": "1", "price": "$5.60" }
{ "_id": "2", "price": "$8.90" }
Use $ in literal form
The following code uses literal
to generate a new field isOneDollar
that indicates whether the price
field is strictly equal to "$1"
.
Note: We cannot use eq(['$price', '$1'])
here, because "$1"
is an expression that represents the value of the "1"
field, not a string literal "$1"
.
const $ = db.command.aggregate
let res = await db.collection('items').aggregate()
.project({
isOneDollar: $.eq(['$price', $.literal('$1')])
})
.end()
The output is as follows:
{ "_id": "0", "isOneDollar": true }
{ "_id": "1", "isOneDollar": false }
{ "_id": "2", "isOneDollar": false }
Project a field, the corresponding value is 1
The following code uses literal
, projecting a new field amount
with a value of 1
.
const $ = db.command.aggregate
db.collection('items').aggregate()
.project({
price: 1,
amount: $.literal(1)
})
.end()
The output is as follows:
{ "_id": "0", "price": "$1", "amount": 1 }
{ "_id": "1", "price": "$5.60", "amount": 1 }
{ "_id": "2", "price": "$8.90", "amount": 1 }
Merge multiple documents into a single document.
The form of use is as follows:
When used in group()
:
mergeObjects(<document>)
When used in other expressions:
mergeObjects([<document1>, <document2>, ...])
Use with group()
Suppose the following documents exist in the collection 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 } }
The following code uses mergeObjects()
to merge documents with the same name
:
const $ = db.command.aggregate
let res = await db.collection('sales').aggregate()
.group({
_id: '$name',
mergedVolume: $.mergeObjects('$volume')
})
.end()
The output is as follows:
{ "_id": "A", "mergedVolume": { "2017Q1": 400, "2017Q2": 300, "2017Q3": 0, "2017Q4": 0, "2018Q1": 500, "2018Q2": 500 } }
{ "_id": "B", "mergedVolume": { "2017Q3": 100, "2017Q4": 250, "2018Q1": 100 } }
General usage
Suppose the following documents exist in the collection 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 } }
The following code uses mergeObjects()
to merge the foo
and bar
fields in the document into foobar
:
const $ = db.command.aggregate
let res = await db.collection('sales').aggregate()
.project({
foobar: $.mergeObjects(['$foo', '$bar'])
})
.end()
The output is as follows:
{ "_id": 1, "foobar": { "a": 1, "b": 2 } }
{ "_id": 2, "foobar": { "c": 1, "d": 2 } }
{ "_id": 3, "foobar": { "e": 1, "f": 2 } }
Enter an array, or an expression for an array field. Returns true
if all elements in the array are true, otherwise returns false
. Empty arrays always return true
.
The syntax is as follows:
allElementsTrue([<expression>])
Suppose the collection test
has the following records:
{ "_id": 1, "array": [ true ] }
{ "_id": 2, "array": [ ] }
{ "_id": 3, "array": [ false ] }
{ "_id": 4, "array": [ true, false ] }
{ "_id": 5, "array": [ 0 ] }
{ "_id": 6, "array": [ "stark" ] }
The following code uses allElementsTrue()
to determine whether all of the array
fields are true:
const $ = db.command.aggregate
let res = await db.collection('price')
.aggregate()
.project({
isAllTrue: $.allElementsTrue(['$array'])
})
.end()
The returned results are as follows:
{ "_id": 1, "isAllTrue": true }
{ "_id": 2, "isAllTrue": true }
{ "_id": 3, "isAllTrue": false }
{ "_id": 4, "isAllTrue": false }
{ "_id": 5, "isAllTrue": false }
{ "_id": 6, "isAllTrue": true }
Enter an array, or an expression for an array field. Returns true
if any element in the array is true, otherwise returns false
. Empty arrays always return false
.
The syntax is as follows:
anyElementTrue([<expression>])
Suppose the collection test
has the following records:
{ "_id": 1, "array": [ true ] }
{ "_id": 2, "array": [ ] }
{ "_id": 3, "array": [ false ] }
{ "_id": 4, "array": [ true, false ] }
{ "_id": 5, "array": [ 0 ] }
{ "_id": 6, "array": [ "stark" ] }
The following code uses anyElementTrue()
to determine whether the array
field contains a true value:
const $ = db.command.aggregate
let res = await db.collection('price')
.aggregate()
.project({
isAnyTrue: $.anyElementTrue(['$array'])
})
.end()
The returned results are as follows:
{ "_id": 1, "isAnyTrue": true }
{ "_id": 2, "isAnyTrue": false }
{ "_id": 3, "isAnyTrue": false }
{ "_id": 4, "isAnyTrue": true }
{ "_id": 5, "isAnyTrue": false }
{ "_id": 6, "isAnyTrue": true }
Takes two sets as input, and outputs elements that exist only in the first set.
The form of use is as follows:
setDifference([<expression1>, <expression2>])
Suppose the following data exists in the collection 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 ] }
The following code uses setDifference
to find numbers that only exist in B
:
let res = await db.collection('test')
.aggregate()
.project({
isBOnly: $.setDifference(['$B', '$A'])
})
.end()
{ "_id": 1, "isBOnly": [] }
{ "_id": 2, "isBOnly": [] }
{ "_id": 3, "isBOnly": [3] }
{ "_id": 4, "isBOnly": [3] }
{ "_id": 5, "isBOnly": [] }
{ "_id": 6, "isBOnly": [{}, []] }
{ "_id": 7, "isBOnly": [] }
{ "_id": 8, "isBOnly": [1] }
Input two sets and determine whether the elements contained in the two sets are the same (regardless of order, deduplication).
The form of use is as follows:
setEquals([<expression1>, <expression2>])
Suppose the following data exists in the collection 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 ] }
The following code uses setEquals
to determine whether two sets contain the same elements:
let res = await 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 }
Input two sets, output the intersection of the two sets.
The form of use is as follows:
setIntersection([<expression1>, <expression2>])
Suppose the following data exists in the collection 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 ] }
The following code uses setIntersection
to output the intersection of two sets:
let res = await db.collection('test')
.aggregate()
.project({
commonToBoth: $.setIntersection(['$A', '$B'])
})
.end()
The output is as follows:
{ "_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": [ ] }
Given two sets, determine whether the first set is a subset of the second set.
The form of use is as follows:
setIsSubset([<expression1>, <expression2>])
Suppose the following data exists in the collection 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 ] }
The following code uses setIsSubset
to determine whether the first set is a subset of the second set:
let res = await 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 }
Input two sets, output the union of the two sets.
The form of use is as follows:
setUnion([<expression1>, <expression2>])
Suppose the following data exists in the collection 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 ] }
The following code uses setUnion
to output the union of two sets:
let res = await db.collection('test')
.aggregate()
.project({
AB: $.setUnion(['$A', '$B'])
})
.end()
The output is as follows:
{ "_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 ] }
Concatenate strings and return the concatenated string.
The syntax of concat
is as follows:
db.command.aggregate.concat([<表达式1>, <表达式2>, ...])
The expression can be in the form of $ + specified field
, or it can be a normal string. As long as it can be parsed into a string.
Suppose the collection students
has the following records:
{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }
{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }
{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }
With concat
you can concatenate the lastName
and firstName
fields to get the full name of each student:
const $ = db.command.aggregate
db
.collection('students')
.aggregate()
.project({
_id: 0,
fullName: $.concat(['$firstName', ' ', '$lastName'])
})
.end()
The results returned are as follows:
{ "fullName": "Yuanxin Dong" }
{ "fullName": "Weijia Wang" }
{ "fullName": "Chengxi Li" }
see dateFromString
see dateToString
Finds a substring in the target string and returns the byte index (0-based) of the first occurrence of UTF-8
. Returns -1 if no substring exists.
The syntax of indexOfBytes
is as follows:
db.command.aggregate.indexOfBytes([<目标字符串表达式>, <子字符串表达式>, <开始位置表达式>, <结束位置表达式>])
The following is a detailed description of the four expressions:
expression | description |
---|---|
target string expression | any expression that can be parsed as a string |
Substring expression | Any expression that can be parsed as a string |
Start position expression | Any expression that can be parsed as a non-negative integer |
End position expression | Any expression that can be parsed as a non-negative integer |
Suppose the collection students
has the following records:
{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }
{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }
{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }
Use indexOfBytes
to find the position of the character "a"
in the field firstName
:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.project({
_id: 0,
aStrIndex: $.indexOfBytes(['$firstName', 'a'])
})
.end()
The results returned are as follows:
{ "aStrIndex": 2 }
{ "aStrIndex": 5 }
{ "aStrIndex": -1 }
Finds a substring in the target string and returns the code point
index (0-based) of the first occurrence of UTF-8
. Returns -1 if no substring exists.
code point
is a "code point", aka "code position". This refers specifically to the code points in the Unicode
package, ranging from 0 (hexadecimal) to 10FFFF (hexadecimal).
The syntax of indexOfCP
is as follows:
db.command.aggregate.indexOfCP([<目标字符串表达式>, <子字符串表达式>, <开始位置表达式>, <结束位置表达式>])
The following is a detailed description of the four expressions:
expression | description |
---|---|
target string expression | any expression that can be parsed as a string |
Substring expression | Any expression that can be parsed as a string |
Start position expression | Any expression that can be parsed as a non-negative integer |
End position expression | Any expression that can be parsed as a non-negative integer |
Suppose the collection students
has the following records:
{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }
{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }
{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }
Use indexOfCP
to find the position of the character "a"
in the field firstName
:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.project({
_id: 0,
aStrIndex: $.indexOfCP(['$firstName', 'a'])
})
.end()
The results returned are as follows:
{ "aStrIndex": 2 }
{ "aStrIndex": 5 }
{ "aStrIndex": -1 }
Delimits the array by the delimiter and removes the delimiter to return an array of substrings. If the string cannot be separated by a delimiter, returns the original string as the only element of the array.
The syntax of split
is as follows:
db.command.aggregate.split([<字符串表达式>, <分隔符表达式>])
String expressions and delimiter expressions can be any expression as long as it can be parsed as a string.
Suppose the collection students
has the following records:
{ "birthday": "1999/12/12" }
{ "birthday": "1998/11/11" }
{ "birthday": "1997/10/10" }
Use split
to separate the corresponding values of the birthday
field in each record into arrays, each consisting of 3 elements representing the year, month, and day:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.project({
_id: 0,
birthday: $.split(['$birthday', '/'])
})
.end()
The results returned are as follows:
{ "birthday": [ "1999", "12", "12" ] }
{ "birthday": [ "1998", "11", "11" ] }
{ "birthday": [ "1997", "10", "10" ] }
Calculates and returns the number of utf-8
encoded bytes in the specified string.
The syntax of strLenBytes
is as follows:
db.command.aggregate.strLenBytes(<表达式>)
An expression is a valid expression as long as it can be parsed into a string.
Suppose the collection students
has the following records:
{ "name": "dongyuanxin", "nickname": "心谭" }
Calculate the length in bytes of the corresponding values of the name
field and nickname
field with the help of strLenBytes
:
const $ = db.command.aggregate
db
.collection('students')
.aggregate()
.project({
_id: 0,
nameLength: $.strLenBytes('$name'),
nicknameLength: $.strLenBytes('$nickname')
})
.end()
The returned results are as follows:
{ "nameLength": 11, "nicknameLength": 6 }
Calculates and returns the UTF-8 code points of the specified string number.
The syntax of strLenCP
is as follows:
db.command.aggregate.strLenCP(<表达式>)
An expression is a valid expression as long as it can be parsed into a string.
Suppose the collection students
has the following records:
{ "name": "dongyuanxin", "nickname": "心谭" }
Calculate UTF-8 code points number:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.project({
_id: 0,
nameLength: $.strLenCP('$name'),
nicknameLength: $.strLenCP('$nickname')
})
.end()
The returned results are as follows:
{ "nameLength": 11, "nicknameLength": 2 }
Compares two strings case-insensitively and returns the result of the comparison.
The syntax of strcasecmp
is as follows:
db.command.aggregate.strcasecmp([<表达式1>, <表达式2>])
expression1
and expression2
are valid as long as they can be parsed as strings.
The comparison results returned are 1, 0 and -1:
expression1
parsed string > expression2
parsed string - 0: expression1
parsed string = expression2
parsed string - -1: expression2
expression1parsed string <
expression2` parsed stringSuppose the collection students
has the following records:
{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }
{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }
{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }
Use strcasecmp
to compare the size of the firstName
field value and the lastName
field value:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.project({
_id: 0,
result: $.strcasecmp(['$firstName', '$lastName']),
})
.end()
The returned results are as follows:
{ "result": 1 }
{ "result": 1 }
{ "result": -1 }
Returns a substring of the specified length of the string starting at the specified position. It is an alias for db.command.aggregate.substrBytes
, the latter is preferred.
The syntax of substr
is as follows:
db.command.aggregate.substr([<表达式1>, <表达式2>, <表达式3>])
expression1
is any valid expression that can be parsed as a string, expression2
and expression3
are any valid expression that can be parsed as a number.
If expression2
is negative, the result returned is ""
.
If expression3
is negative, the result returned is the substring starting at the position specified by expression2
and the rest after that.
Suppose the collection students
has the following records:
{ "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 }
With the help of substr
, you can extract the year, month, and day information in birthday
, the code is as follows:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.project({
_id: 0,
year: $.substr(['$birthday', 0, 4]),
month: $.substr(['$birthday', 5, 2]),
day: $.substr(['$birthday', 8, -1])
})
.end()
The results returned are as follows:
{ "day": "12", "month": "12", "year": "1999" }
{ "day": "11", "month": "11", "year": "1998" }
{ "day": "10", "month": "10", "year": "1997" }
Returns a substring of the specified length of the string starting at the specified position. The substring starts at the character at the specified UTF-8
byte index in the string and is the specified number of bytes long.
The syntax of substrBytes
is as follows:
db.command.aggregate.substrBytes([<表达式1>, <表达式2>, <表达式3>])
expression1
is any valid expression that can be parsed as a string, expression2
and expression3
are any valid expression that can be parsed as a number.
If expression2
is negative, the result returned is ""
.
If expression3
is negative, the result returned is the substring starting at the position specified by expression2
and the rest after that.
Suppose the collection students
has the following records:
{ "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 }
With the help of substrBytes
, you can extract the year, month, and day information in birthday
, the code is as follows:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.project({
_id: 0,
year: $.substrBytes(['$birthday', 0, 4]),
month: $.substrBytes(['$birthday', 5, 2]),
day: $.substrBytes(['$birthday', 8, -1])
})
.end()
The results returned are as follows:
{ "day": "12", "month": "12", "year": "1999" }
{ "day": "11", "month": "11", "year": "1998" }
{ "day": "10", "month": "10", "year": "1997" }
Returns a substring of the specified length of the string starting at the specified position. The substring starts at the character at the specified UTF-8
byte index in the string and is the specified number of bytes long.
The syntax of substrCP
is as follows:
db.command.aggregate.substrCP([<表达式1>, <表达式2>, <表达式3>])
expression1
is any valid expression that can be parsed as a string, expression2
and expression3
are any valid expression that can be parsed as a number.
If expression2
is negative, the result returned is ""
.
If expression3
is negative, the result returned is the substring starting at the position specified by expression2
and the rest after that.
Suppose the collection students
has the following records:
{ "name": "dongyuanxin", "nickname": "心谭" }
With the help of substrCP
, the first Chinese character of the nickname
field value can be extracted:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.project({
_id: 0,
firstCh: $.substrCP(['$nickname', 0, 1])
})
.end()
The results returned are as follows:
{ "firstCh": "心" }
Convert the string to lowercase and return.
The syntax of toLower
is as follows:
db.command.aggregate.toLower(表达式)
An expression is a valid expression as long as it can be parsed into a string. For example: $ + specify field
.
Suppose the collection students
has the following records:
{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }
{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }
{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }
Convert the field value of firstName
to lowercase with the help of toLower
:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.project({
_id: 0,
result: $.toLower('$firstName'),
})
.end()
The results returned are as follows:
{ "result": "yuanxin" }
{ "result": "weijia" }
{ "result": "chengxi" }
Convert the string to uppercase and return.
The syntax of toUpper
is as follows:
db.command.aggregate.toUpper(表达式)
An expression is a valid expression as long as it can be parsed into a string. For example: $ + specify field
.
Suppose the collection students
has the following records:
{ "firstName": "Yuanxin", "group": "a", "lastName": "Dong", "score": 84 }
{ "firstName": "Weijia", "group": "a", "lastName": "Wang", "score": 96 }
{ "firstName": "Chengxi", "group": "b", "lastName": "Li", "score": 80 }
Use toUpper
to convert the field value of lastName
to uppercase:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.project({
_id: 0,
result: $.toUpper('$lastName'),
})
.end()
The results returned are as follows:
{ "result": "DONG" }
{ "result": "WANG" }
{ "result": "LI" }
Aggregation operator. Adds a value to the array, and does nothing if the value already exists in the array. It can only be used in group stage
.
The addToSet
syntax is as follows:
db.command.aggregate.addToSet(<表达式>)
An expression is a string of the form $ + specified field
. If the value of the specified field is an array, the entire array is treated as one element.
Suppose the collection passages
has the following records:
{ "category": "web", "tags": [ "JavaScript", "CSS" ], "title": "title1" }
{ "category": "System", "tags": [ "C++", "C" ], "title": "title2" }
non-array field
The type of the corresponding value of category
for each record is non-array, use addToSet
to count all categories:
const $ = db.command.aggregate
let res = await db
.collection('passages')
.aggregate()
.group({
_id: null,
categories: $.addToSet('$category')
})
.end()
The results returned are as follows:
{ "_id": null, "categories": [ "System", "web" ] }
Array field
The type of the corresponding value of tags
for each record is an array, and the array will not be automatically expanded:
const $ = db.command.aggregate
let res = await db
.collection('passages')
.aggregate()
.group({
_id: null,
tagsList: $.addToSet('$tags')
})
.end()
The results returned are as follows:
{ "_id": null, "tagsList": [ [ "C++", "C" ], [ "JavaScript", "CSS" ] ] }
Returns the average value of the data corresponding to the specified field in a set of collections.
The syntax of avg
is as follows:
db.command.aggregate.avg(<number>)
In addition to numeric constants, the value passed to avg
can also be any expression that eventually resolves to a number. It ignores non-numeric values.
Suppose the collection students
has the following records:
{ "group": "a", "name": "stu1", "score": 84 }
{ "group": "a", "name": "stu2", "score": 96 }
{ "group": "b", "name": "stu3", "score": 80 }
{ "group": "b", "name": "stu4", "score": 100 }
With avg
it is possible to calculate the average of the score
of all records:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.group({
_id: null,
average: $.avg('$score')
})
.end()
The results returned are as follows:
{ "_id": null, "average": 90 }
Returns the value corresponding to the specified field in the first record of a set. This operation only makes sense if the set of collections is sorted by some definition ( sort
).
The syntax of first
is as follows:
db.command.aggregate.first(<表达式>)
An expression is a string of the form $ + specified field
.
first
can only be used in the group
phase, and only makes sense in conjunction with sort
.
Suppose the collection students
has the following records:
{ "group": "a", "name": "stu1", "score": 84 }
{ "group": "a", "name": "stu2", "score": 96 }
{ "group": "b", "name": "stu3", "score": 80 }
{ "group": "b", "name": "stu4", "score": 100 }
If you need to get the minimum value of score
in all records, you can first sort all records according to score
, and then take the first
of the first record.
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.sort({
score: 1
})
.group({
_id: null,
min: $.first('$score')
})
.end()
The returned data results are as follows:
{ "_id": null, "min": 80 }
Returns the value corresponding to the specified field in the last record of a set. This operation only makes sense if the set of collections is sorted by some definition ( sort
).
The syntax of last
is as follows:
db.command.aggregate.last(<表达式>)
An expression is a string of the form $ + specified field
.
last
can only be used in the group
phase, and only makes sense with sort
.
Suppose the collection students
has the following records:
{ "group": "a", "name": "stu1", "score": 84 }
{ "group": "a", "name": "stu2", "score": 96 }
{ "group": "b", "name": "stu3", "score": 80 }
{ "group": "b", "name": "stu4", "score": 100 }
If you need to get the maximum value of score
in all records, you can first sort all records according to score
, and then take the last
of the last record.
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.sort({
score: 1
})
.group({
_id: null,
max: $.last('$score')
})
.end()
The returned data results are as follows:
{ "_id": null, "max": 100 }
Returns the maximum value of a set of values.
The syntax of max
is as follows:
db.command.aggregate.max(<表达式>)
An expression is a string of the form $ + specified field
.
Suppose the collection students
has the following records:
{ "group": "a", "name": "stu1", "score": 84 }
{ "group": "a", "name": "stu2", "score": 96 }
{ "group": "b", "name": "stu3", "score": 80 }
{ "group": "b", "name": "stu4", "score": 100 }
With the help of max
, you can count the highest value of grades in different groups ( group
), the code is as follows:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.group({
_id: '$group',
maxScore: $.max('$score')
})
.end()
The returned data results are as follows:
{ "_id": "b", "maxScore": 100 }
{ "_id": "a", "maxScore": 96 }
...
see mergeObjects
Returns the minimum value of a set of values.
The syntax for min
is as follows:
db.command.aggregate.min(<表达式>)
An expression is a string of the form $ + specified field
.
Suppose the collection students
has the following records:
{ "group": "a", "name": "stu1", "score": 84 }
{ "group": "a", "name": "stu2", "score": 96 }
{ "group": "b", "name": "stu3", "score": 80 }
{ "group": "b", "name": "stu4", "score": 100 }
With the help of min
, you can count the lowest value of grades in different groups ( group
), the code is as follows:
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.group({
_id: '$group',
minScore: $.min('$score')
})
.end()
The returned data results are as follows:
{ "_id": "b", "minScore": 80 }
{ "_id": "a", "minScore": 84 }
In the group
stage, returns a group of arrays consisting of the columns specified by the expression and the corresponding values.
The push
syntax is as follows:
db.command.aggregate.push({
<字段名1>: <指定字段1>,
<字段名2>: <指定字段2>,
...
})
Suppose the collection students
has the following records:
{ "group": "a", "name": "stu1", "score": 84 }
{ "group": "a", "name": "stu2", "score": 96 }
{ "group": "b", "name": "stu3", "score": 80 }
{ "group": "b", "name": "stu4", "score": 100 }
With the push
operation, for all records in different groups ( group
), aggregate all the data and put it into a new field, further structuring and semantic data.
const $ = db.command.aggregate
let res = await db
.collection('students')
.aggregate()
.group({
_id: '$group',
students: $.push({
name: '$name',
score: '$score'
})
})
.end()
The output is as follows:
{ "_id": "b", "students": [{ "name": "stu3", "score": 80 }, { "name": "stu4", "score": 100 }] }
{ "_id": "a", "students": [{ "name": "stu1", "score": 84 }, { "name": "stu2", "score": 96 }] }
Returns the standard deviation of the corresponding values for a set of fields.
stdDevPop
is used as follows:
db.command.aggregate.stdDevPop(<表达式>)
The expression passes in the specified field, and the data type of the value corresponding to the specified field must be number
, otherwise the result will return null
.
Suppose the records of the set students
are as follows: The grades of the students in the a
group are 84 and 96, respectively, and the grades of the students in the b
group are 80 and 100, respectively.
{ "group":"a", "score":84 }
{ "group":"a", "score":96 }
{ "group":"b", "score":80 }
{ "group":"b", "score":100 }
You can use stdDevPop
to calculate the standard deviation of the scores of the two groups of students a
and b
respectively, in order to compare which group of students has more stable scores. code show as below:
const $ = db.command.aggregate
let res = await db.collection('students').aggregate()
.group({
_id: '$group',
stdDev: $.stdDevPop('$score')
})
.end()
The returned data results are as follows:
{ "_id": "b", "stdDev": 10 }
{ "_id": "a", "stdDev": 6 }
Calculates the sample standard deviation of the input values. Use db.command.aggregate.stdDevPop
instead if the input value represents the population of data, or does not generalize more data.
stdDevSamp
is used as follows:
db.command.aggregate.stdDevSamp(<表达式>)
The expression passed in is the specified field, and stdDevSamp
will automatically ignore non-numeric values. If all values of the specified field are non-numeric, the result returns null
.
Suppose the collection students
has the following records:
{ "score": 80 }
{ "score": 100 }
The standard sample deviation of grades can be calculated using stdDevSamp
. code show as below:
const $ = db.command.aggregate
let res = await db.collection('students').aggregate()
.group({
_id: null,
ageStdDev: $.stdDevSamp('$score')
})
.end()
The returned data results are as follows:
{ "_id": null, "ageStdDev": 14.142135623730951 }
If you add a new record to the collection students
, its score
field type is string
:
{ "score": "aa" }
When using the above code to calculate standard sample deviation, stdDevSamp
will automatically ignore records whose type is not number
, and the returned result will remain unchanged.
Calculates and returns the sum of all values in a set of fields.
sum
is used in the following form:
db.command.aggregate.sum(<表达式>)
The expression can be passed in a specified field, or a list of specified fields can be passed in. sum
automatically ignores non-numeric values. If all values under the field are non-numeric, the result returns 0. If a numeric constant is passed in, the value of this field in all records will be given the given constant, added during aggregation, and the final value will be the number of input records multiplied by the constant.
Suppose the records representing the collection of goods goods
are as follows: price
represents the sales of the goods, cost
represents the cost of the goods
{ "cost": -10, "price": 100 }
{ "cost": -15, "price": 1 }
{ "cost": -10, "price": 10 }
Separate field
With the help of sum
you can calculate the total sales of all products, the code is as follows:
const $ = db.command.aggregate
let res = await db
.collection('goods')
.aggregate()
.group({
_id: null,
totalPrice: $.sum('$price')
})
.end()
The result of the returned data is as follows: Sales is 111
{ "_id": null, "totalPrice": 111 }
Field List
If you need to calculate the total profit of all items, you need to add the cost
and price
of each record to get the profit of the item corresponding to this record. Finally, calculate the total profit of all commodities.
With sum
, the code is as follows:
const $ = db.command.aggregate
let res = await db
.collection('goods')
.aggregate()
.group({
_id: null,
totalProfit: $.sum(
$.sum(['$price', '$cost'])
)
})
.end()
The result of the returned data is as follows: The total profit is 76
{ "_id": null, "totalProfit": 76 }
Custom variables, and used in the specified expression, the returned result is the result of the expression.
The syntax of let
is as follows:
db.command.aggregate.let({
vars: {
<变量1>: <变量表达式>,
<变量2>: <变量表达式>,
...
},
in: <结果表达式>
})
Multiple variables can be defined in vars
, the value of the variable is calculated from the variable expression
, and the defined variable can only be accessed by the result expression
in in
.
When accessing custom variables in the result expression of in
, precede the variable name with a double dollar sign ( $$
) and enclose it in quotes.
Suppose the records representing the collection of goods goods
are as follows: price
represents the price of the goods, discount
represents the discount rate of the goods, and cost
represents the cost of the goods
{ "cost": -10, "discount": 0.95, "price": 100 }
{ "cost": -15, "discount": 0.98, "price": 1 }
{ "cost": -10, "discount": 1, "price": 10 }
With let
, you can define and calculate the actual selling price of each item, and assign it to the custom variable priceTotal
. Finally, priceTotal
and cost
are summed ( sum
) to get the profit of each item.
code show as below:
const $ = db.command.aggregate
let res = await db
.collection('goods')
.aggregate()
.project({
profit: $.let({
vars: {
priceTotal: $.multiply(['$price', '$discount'])
},
in: $.sum(['$$priceTotal', '$cost'])
})
})
.end()
The returned data results are as follows:
{ "profit": 85 }
{ "profit": -14.02 }
{ "profit": 0 }