English
uniCloud's cloud database provides a batch of powerful computing methods. These methods are executed by the database, not by the cloud function.
These calculation methods are used in conjunction with data query, and they can perform calculations on field values or part of field values, and return the calculated results to the query request.
The database operation method provides more powerful and flexible queries than traditional SQL. More functions can be realized, and the expected results can be queried at one time. It is not necessary to check the database multiple times for multiple calculations, which will not only complicate the code, but also cause performance degradation for multiple database queries; if you use billing cloud space, using these methods can also reduce the number of database queries.
For example, the sum() method can sum the values of a certain field in multiple rows of records, and can sum the values of several fields in a single row of records. If the field is an array, it can also sum the items of the array.
For the convenience of writing, the usage of the database operation method is simplified in JQL (compared to the original database operation method writing method), mainly the parameters are flattened, and the method is a string Express. The following are the database operation methods that can be used in JQL
Computation method | Application | Simplified usage of JQL | Description |
---|---|---|---|
abs | Returns the absolute value of a number | abs(expression) | - |
add | Add numbers or add numbers to dates. If one of the values in the argument is a date, the other values will be treated as milliseconds added to that date | add(expression1,expression2) | - |
ceil | round up | ceil(expression) | - |
divide | Input dividend and divisor, find quotient | divide(expression1,expression2) | - |
exp | Take e (the base of natural logarithm, Euler's number) to the power n | exp(expression) | - |
floor | round down | floor(expression) | - |
ln | Calculates the natural logarithm value of the given number | ln(expression) | - |
log | Calculates the log value of a given number under a given logarithm | log(expression1,expression2) | - |
log10 | Calculates the log value of a given number with logarithm base 10 | log10(expression) | - |
mod | Modulo operation, the first number is the dividend, the second number is the divisor | mod(expression1,expression2) | - |
multiply | The result of multiplying the incoming number parameters | multiply(expression1,expression2) | - |
pow | Find the power of the exponent in the given base | pow(expression1,expression2) | - |
sqrt | square root | sqrt(expression1,expression2) | - |
subtract | Subtracts two numbers and returns the difference, or subtracts two dates and returns the difference in milliseconds, or subtracts a date and returns the date of the result. | subtract(expression1,expression2) | - |
trunc | Truncates a number to an integer | trunc(expression) | - |
arrayElemAt | returns the element at the specified array index | arrayElemAt(expression1,expression2) | - |
arrayToObject | converts an array to an object | arrayToObject(expression) | - |
concatArrays | Concatenate multiple arrays into one array | concatArrays(expression1,expression2) | - |
filter | Returns a subset of the array that satisfies the condition based on the given condition | filter(input,as,cond) | - |
in | Given a value and an array, return true if the value is in the array, otherwise return false | in(expression1,expression2) | - |
indexOfArray | Find the subscript of the first element in the array equal to the given value, if not found, return -1 | indexOfArray(expression1,expression2) | - |
isArray | Determine whether the given expression is an array, return a Boolean value | isArray(expression) | - |
map | Similar to the map method on JavaScript Array, convert each element of the given array according to the given conversion method to get a new array | map(input,as,in) | - |
objectToArray | Converts an object to an array. The method turns each key-value pair of the object into an element of the output array, and the element is in the form of { k: <key>, v: <value> } | objectToArray(expression) | - |
range | Returns a range of generated sequence numbers. Given a start value, an end value, and a non-zero step size, range returns a sequence growing from the start value in steps of the given step size, excluding the end value. | range(expression1,expression2) | - |
reduce | Similar to JavaScript's reduce method, apply an expression to each element of the array and then normalize it into one element | reduce(input,initialValue,in) | - |
reverseArray | Returns the reversed form of the given array | reverseArray(expression) | - |
size | returns the length of the array | size(expression) | - |
slice | Similar to JavaScript's slice method. returns the specified subset of the given array | slice(expression1,expression2) | - |
zip | Assemble the elements with the same serial number in the second dimension of the two-dimensional array into a new array and then assemble a new two-dimensional array. | zip(inputs, useLongestLength, defaults) | - |
and | Given multiple expressions, and returns true only if all expressions return true, otherwise returns false | and(expression1,expression2) | - |
not | Given an expression, not returns false if the expression returns true, and true otherwise. Note that the expression cannot be a logical expression (and, or, nor, not) | not(expression) | - |
or | Given multiple expressions, if any expression returns true, then or returns true, otherwise returns false | or(expression1,expression2) | - |
cmp | Given two values, return their comparison value. If the first value is less than the second value, return -1 If the first value is greater than the second value, return 1 If the two values are equal, return 0 | cmp(expression1,expression2) | - |
eq | Matches two values, returns true if equal, false otherwise | eq(expression1,expression2) | - |
gt | matches two values, returns true if former is greater than latter, false otherwise | gt(expression1,expression2) | - |
gte | matches two values, returns true if former is greater than or equal to latter, false otherwise | gte(expression1,expression2) | - |
lt | Matches two values, returns true if former is less than latter, false otherwise | lt(expression1,expression2) | - |
lte | matches two values, returns true if former is less than or equal to latter, false otherwise | lte(expression1,expression2) | - |
neq | matches two values, returns true if not equal, false otherwise | neq(expression1,expression2) | - |
cond | Calculate Boolean expression 1, return expression 2 if true, otherwise return expression 3 | cond(expression 1, expression 2, expression 3) | - |
ifNull | Evaluates the given expression and returns a replacement value if the expression evaluates to null, undefined or does not exist; otherwise returns the original value. | ifNull(expression1,expression2) | - |
switch | Calculate the return value according to the given switch-case-default | switch(branches,default) | - |
dateFromParts | Given information about a date, construct and return a date object | dateFromParts(year,month,day,hour,minute,second,millisecond,timezone) | - |
isoDateFromParts | Given information about a date, construct and return a date object | isoDateFromParts(isoWeekYear,isoWeek,isoDayOfWeek,hour,minute,second,millisecond,timezone) | - |
dateFromString | Convert a date/time string to a date object | dateFromString(dateString, format, timezone, onError, onNull) | - |
dateToString | Format the date object into a string that meets the requirements according to the specified expression | dateToString(date,format,timezone,onNull) | - |
dayOfMonth | Returns the day (the day of the month) corresponding to the date field, which is a number between 1 and 31 | dayOfMonth(date,timezone) | - |
dayOfWeek | Returns the day number (the day of the week) corresponding to the date field, which is an integer between 1 (Sunday) and 7 (Saturday) | dayOfWeek(date,timezone) | - |
dayOfYear | Returns the day number (the day of the year) corresponding to the date field, which is an integer between 1 and 366 | dayOfYear(date,timezone) | - |
hour | Returns the hour corresponding to the date field, which is an integer between 0 and 23. | hour(date,timezone) | - |
isoDayOfWeek | Returns the ISO 8601 day number (day of the week) corresponding to the date field, as an integer between 1 (Monday) and 7 (Sunday). | isoDayOfWeek(date, timezone) | - |
isoWeek | Returns the ISO 8601 week number (week of the year) corresponding to the date field, which is an integer between 1 and 53. | isoWeek(date, timezone) | - |
isoWeekYear | Returns the ISO 8601 day number (day of the year) corresponding to the date field | isoWeekYear(date,timezone) | - |
millisecond | returns the milliseconds corresponding to the date field, which is an integer between 0 and 999 | millisecond(date,timezone) | - |
minute | Returns the minute corresponding to the date field, which is an integer between 0 and 59 | minute(date,timezone) | - |
month | Returns the month corresponding to the date field, which is an integer between 1 and 12 | month(date,timezone) | - |
second | Returns the second corresponding to the date field, an integer between 0 and 59, which may be equal to 60 in special cases (leap seconds) | second(date,timezone) | - |
week | Returns the week number (week of the year) corresponding to the date field, which is an integer between 0 and 53 | week(date,timezone) | - |
year | returns the year corresponding to the date field | year(date,timezone) | - |
timestampToDate | Pass in a timestamp and return the corresponding date object | timestampToDate(timestamp) | Only supported in JQL strings, supported since HBuilderX 3.1.0 |
literal | directly returns a literal value without any parsing and processing | literal(expression) | - |
mergeObjects | Merge multiple objects into a single object | mergeObjects(expression1,expression2) | - |
allElementsTrue | Enter an array, or an expression for an array field. Returns true if all elements in the array are true, otherwise returns false. An empty array always returns true | allElementsTrue(expression1,expression2) | - |
anyElementTrue | Enter an array, or an expression for an array field. Returns true if any element in the array is true, otherwise returns false. An empty array always returns false | anyElementTrue(expression1,expression2) | - |
setDifference | Input two collections, output elements that only exist in the first collection | setDifference(expression1,expression2) | - |
setEquals | Input two collections, judge whether the elements contained in the two collections are the same (regardless of order, deduplication) | setEquals(expression 1, expression 2) | - |
setIntersection | Input two sets, output the intersection of the two sets | setIntersection(expression1,expression2) | - |
setIsSubset | Input two sets, judge whether the first set is a subset of the second set | setIsSubset(expression1,expression2) | - |
setUnion | Input two sets, output the union of two sets | setUnion(expression1,expression2) | - |
concat | Concatenate strings and return the concatenated string | concat(expression1,expression2) | - |
indexOfBytes | Finds a substring in the target string and returns the UTF-8 byte index (starting from 0) of the first occurrence. If there is no substring, return -1 | indexOfBytes(expression1,expression2) | - |
indexOfCP | Finds a substring in the target string and returns the UTF-8 code point index (starting from 0) of the first occurrence. If there is no substring, return -1 | indexOfCP(expression1,expression2) | - |
split | Splits an array by a delimiter and removes the delimiter, returning an array of substrings. If the string cannot be separated by a delimiter, return the original string as the only element of the array | split(expression1,expression2) | - |
strLenBytes | Calculate and return the number of utf-8 encoded bytes in the specified string | strLenBytes(expression) | - |
strLenCP | Calculate and return the number of UTF-8 code points of the specified string | strLenCP(expression) | - |
strcasecmp | Compare two character strings without case sensitivity, and return the comparison result | strcasecmp(expression1,expression2) | - |
substr | Returns a substring of the specified length starting at the specified position | substr(expression1,expression2) | - |
substrBytes | Returns a substring of the specified length of the string starting at the specified position. The substring starts with the character at the specified UTF-8 byte index in the string and has a length of the specified number of bytes | substrBytes(expression1,expression2) | - |
substrCP | Returns a substring of a specified length of a string starting at a specified position. The substring starts with the character at the specified UTF-8 byte index in the string and has a length of the specified number of bytes | substrCP(expression1,expression2) | - |
toLower | Convert the string to lowercase and return | toLower(expression) | - |
toUpper | convert string to uppercase and return | toUpper(expression) | - |
addToSet | Aggregation operator. Adds a value to the array, or does nothing if the value already exists in the array. It can only be used in group stage | addToSet(expression) | - |
avg | returns the average value of the data corresponding to the specified expression | avg(expression) | - |
first | Returns the value corresponding to the first record of the specified field in a set. This operation only makes sense if the set of collections is sorted by some definition ( sort ) | first(expression) | - |
last | Returns the value corresponding to the last record of the specified field in a set. This operation only makes sense if the set of collections is sorted ( sort ) by some definition. | last(expression) | - |
max | Returns the maximum value of a set of values | max(expression) | - |
min | Returns the minimum value of a set of values | min(expression) | - |
push | Returns an array of columns specified by expressions and corresponding values in a group | push(expression) | - |
stdDevPop | Returns the standard deviation of values corresponding to a set of fields | stdDevPop(expression) | - |
stdDevSamp | Computes the sample standard deviation of input values | stdDevSamp(expression) | - |
sum | Returns the sum of all values of a group of fields in groupField, and returns the sum of all elements of an array in non-groupField | sum(expression) | - |
let | Customize variables and use them in the specified expression, the returned result is the result of the expression | let(vars,in) | - |
The above operators can also be used in combination
Example: The data table article has the following data
{
"_id": "1",
"publish_date": 1611141512751,
"content": "hello uniCloud content 01",
"content": "hello uniCloud title 01",
}
{
"_id": "2",
"publish_date": 1611141512752,
"content": "hello uniCloud content 02",
"content": "hello uniCloud title 02",
}
{
"_id": "3",
"publish_date": 1611141512753,
"content": "hello uniCloud content 03",
"content": "hello uniCloud title 03",
}
You can use the following query to convert the publish_date field from timestamp to 2021-01-20
, and then perform statistics by day
const res = await db.collection('article')
.groupBy('dateToString(add(new Date(0),publish_date),"%Y-%m-%d","+0800") as publish_date_str')
.groupField('count(*) as total')
.get()
The above code uses the add method to convert the publish_date timestamp into a date type, and then uses dateToString to format the date in the previous step in the format of 4-digit year-2-digit month-2-digit day
according to the time zone '+0800' (Beijing time) , please refer to dateToString for complete format parameters.
The above code execution result is
res = {
result: {
data: [{
publish_date_str: '2021-01-20',
total: 3
}]
}
}
Notice
In the calculation method, only database fields can be directly written as variables without quotation marks, and other strings must still be written as strings
example:
The database contains the following data:
{
"_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 ]
}
Round the sales field in the following data in the cloud function
const db = uniCloud.database()
const $ = db.command.aggregate
let res = await db.collection('stats').aggregate()
.project({
truncated: $.map({
input: '$sales',
as: 'num',
in: $.trunc('$$num'),
})
})
.end()
Realization of the same function in JQL syntax
const db = uniCloud.database()
const res = await db.collection('stats')
.field('map(sales,"num",trunc("$$num")) as truncated')
.get()
The grouping operation method is a database operation method dedicated to statistical summarization. It's also a database method, not a js method.
Equivalent to mongoDB accumulator operator concept
Only the following calculation methods can be used in groupField.
Operator | Usage | Usage | Description |
---|---|---|---|
addToSet | Adds a value to the array, or does nothing if the value already exists in the array | addToSet(expression) | - |
avg | returns the average value of the data corresponding to the specified expression | avg(expression) | - |
first | Returns the value corresponding to the first record of the specified field in a set. This operation only makes sense if the collection is sorted by some definition ( sort ) | first(expression) | - |
last | Returns the value corresponding to the last record of the specified field in a set. This operation only makes sense if the set of collections is sorted ( sort ) by some definition. | last(expression) | - |
max | Returns the maximum value of a set of values | max(expression) | - |
min | Returns the minimum value of a set of values | min(expression) | - |
push | Returns an array of columns specified by expressions and corresponding values in a group | push(expression) | - |
stdDevPop | Returns the standard deviation of values corresponding to a set of fields | stdDevPop(expression) | - |
stdDevSamp | Computes the sample standard deviation of the input values | stdDevSamp(expression) | - |
sum | Returns the sum of all values in a set of fields | sum(expression) | - |
mergeObjects | Merges a group of objects into a single object | mergeObjects(expression) | Receives only one argument when used inside a groupField |
The following lists the application of common operation methods in JQL
Arithmetic expressions perform mathematical operations on numbers. Some arithmetic expressions can also support date arithmetic.
Returns the absolute value of a number.
Example collection test
data example:
{ _id: 1, start: 5 }
{ _id: 2, start: -4 }
{ _id: 3, start: -9 }
{ _id: 4, start: 6 }
Compute the absolute value of start
:
db.collection('test').field('abs(satrt) as absStart').get()
Results of the:
{ _id: 1, absStart: 5 }
{ _id: 2, absStart: 4 }
{ _id: 3, absStart: 9 }
{ _id: 4, absStart: 6 }
Add numbers or add numbers to dates. If one of the values in the parameter is a date, the other values are treated as milliseconds added to that date.
Example collection test
data example:
{ _id: 1, price: 5, fee: 1, date: 1667804052630 }
{ _id: 2, price: 4, fee: 5, date: 1667804052630 }
{ _id: 3, price: 9, fee: 2, date: 1667804052630 }
{ _id: 4, price: 6, fee: 8, date: 1667804052630 }
Example:
add numbers
db.collection('test').field('add(price, fee) as total').get()
Results of the:
{ _id: 1, total: 6 }
{ _id: 2, total: 9 }
{ _id: 3, total: 11 }
{ _id: 4, total: 14 }
Add 1 day to the current date
db.collection('test').field('add(date, 24 * 60 * 60 * 1000) as newDate').get()
Results of the:
{ _id: 1, newDate: 1667890452630 }
{ _id: 2, newDate: 1667890452630 }
{ _id: 3, newDate: 1667890452630 }
{ _id: 4, newDate: 1667890452630 }
Rounded up.
The collection test
data is as follows:
{ _id: 1, value: 9.25 }
{ _id: 2, value: 8.73 }
{ _id: 3, value: 4.32 }
{ _id: 4, value: -5.34 }
Round up the value field:
db.collection('test').field('ceil(value) as ceilingVaule').get()
Results of the:
{ _id: 1, value: 10 }
{ _id: 2, value: 10 }
{ _id: 3, value: 5 }
{ _id: 4, value: -5 }
Pass in the dividend and divisor to find the quotient.
The example collection test
data is as follows:
{ "_id" : 1, "name" : "A", "hours" : 80, "resources" : 7 }
{ "_id" : 2, "name" : "B", "hours" : 40, "resources" : 4 }
Divide the hours
field by 8 to calculate the number of working days:
db.collection('test').field('divide(hours, 8) as workdays').get()
Results of the:
{ "_id" : 1, "workdays" : 10 }
{ "_id" : 2, "workdays" : 8 }
Round down.
The example collection test
data is as follows:
{ _id: 1, value: 9.25 }
{ _id: 2, value: 8.73 }
{ _id: 3, value: 4.32 }
{ _id: 4, value: -5.34 }
Round value down:
db.collection('test').field('floor(value) as floorValue').get()
Results of the:
{ _id: 1, floorValue: 9 }
{ _id: 2, floorValue: 8 }
{ _id: 3, floorValue: 4 }
{ _id: 4, floorValue: -6 }
Calculates the natural logarithm value of the given number.
The example collection test
data is as follows:
{ _id: 1, year: "2000", sales: 8700000 }
{ _id: 2, year: "2005", sales: 5000000 }
{ _id: 3, year: "2010", sales: 6250000 }
An example of converting test data is as follows:
db.collection('test').field('year as x, ln(sales) as y').get()
Results of the:
{ "_id" : 1, "x" : "2000", "y" : 15.978833583624812 }
{ "_id" : 2, "x" : "2005", "y" : 15.424948470398375 }
{ "_id" : 3, "x" : "2010", "y" : 15.648092021712584 }
Computes the log
value of a given number at a given logarithm.
The example collection test
data is as follows:
{ _id: 1, positiveInt: 5 }
{ _id: 2, positiveInt: 2 }
{ _id: 3, positiveInt: 23 }
{ _id: 4, positiveInt: 10 }
Use $log_2$ in the calculation to determine the number of digits required to represent the value of positiveInt:
db.collection('test').field('floor(add(log(positiveInt, 2))) as bitsNeeded')
Results of the:
{ "_id" : 1, "bitsNeeded" : 3 }
{ "_id" : 2, "bitsNeeded" : 2 }
{ "_id" : 3, "bitsNeeded" : 5 }
{ "_id" : 4, "bitsNeeded" : 4 }
Computes the log
value of the given number at log base 10.
The example collection test
data is as follows:
{ _id: 1, H3O: 0.0025 }
{ _id: 2, H3O: 0.001 }
{ _id: 3, H3O: 0.02 }
The following example calculates the pH of a sample:
db.collection('test').field('multiply(1, log10(H3O)) as pH').get()
Results of the:
{ "_id" : 1, "pH" : 2.6020599913279625 }
{ "_id" : 2, "pH" : 3 }
{ "_id" : 3, "pH" : 1.6989700043360187 }
Modulo operation, the first number is the dividend and the second number is the divisor.
The example collection test
data is as follows:
{ "_id" : 1, "project" : "A", "hours" : 80, "tasks" : 7 }
{ "_id" : 2, "project" : "B", "hours" : 40, "tasks" : 4 }
Use the mod
expression to return the remainder of the hours
field divided by the tasks
field:
db.collection('test').field('mod(hours, tasks) as remainder').get()
Results of the:
{ "_id" : 1, "remainder" : 3 }
{ "_id" : 2, "remainder" : 0 }
Gets the result of multiplying the passed in numeric arguments.
The example collection test
data is as follows:
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity": 2 }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity": 1 }
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity": 10 }
Use the multiply
expression to multiply the price
and quantity
fields:
db.collection('test').field('multiply(price, quantity) as total').get()
Results of the:
{ "_id" : 1, "total" : 20 }
{ "_id" : 2, "total" : 20 }
{ "_id" : 3, "total" : 50 }
Raises the given base to the power of the exponent.
The example collection test
data is as follows:
{ "_id" : 1, "item" : "abc", "price" : 10, "quantity": 2 }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity": 1 }
{ "_id" : 3, "item" : "xyz", "price" : 5, "quantity": 10 }
Use the multiply
expression to multiply the price
and quantity
fields:
db.collection('test').field('multiply(price, quantity) as total').get()
Results of the:
{ "_id" : 1, "total" : 20 }
{ "_id" : 2, "total" : 20 }
{ "_id" : 3, "total" : 50 }
Calculates the square root.
The example collection test
data is as follows:
{ _id: 1, p1: { x: 5, y: 8 }, p2: { x: 0, y: 5} }
{ _id: 2, p1: { x: -2, y: 1 }, p2: { x: 1, y: 5} }
{ _id: 3, p1: { x: 4, y: 4 }, p2: { x: 4, y: 0} }
The following example calculates the distance between p1 and p2:
db.collection('test').field('sqrt(add(pow(subtract(p2.y, p1.y), 2), pow(subtract(p2.x, p1.x), 2))) as distance').get()
Results of the:
{ "_id" : 1, "distance" : 5.830951894845301 }
{ "_id" : 2, "distance" : 5 }
{ "_id" : 3, "distance" : 4 }
Subtracts two numbers and returns the difference, or subtracts two dates and returns the difference in milliseconds, or subtracts a number from a date and returns the date of the result.
The example collection test
data is as follows:
{ "_id" : 1, "item" : "abc", "price" : 10, "fee" : 2, "discount" : 5, "date" : 1393660800000 }
{ "_id" : 2, "item" : "jkl", "price" : 20, "fee" : 1, "discount" : 2, "date" : 1393664400000 }
subtract number
db.collection('test').field('subtract(add(price, fee), discount) as total').get()
Results of the:
{ "_id" : 1, "item" : "abc", "total" : 7 }
{ "_id" : 2, "item" : "jkl", "total" : 19 }
Subtract 1 day from current date
db.collection('test').field('subtract(date, 24 * 60 * 60 * 1000) as dateDifference').get()
Results of the:
{ "_id" : 1, "item" : "abc", "dateDifference" : 1393747200000 }
{ "_id" : 2, "item" : "jkl", "dateDifference" : 1393750800000 }
Truncates a number to an integer.
The example collection test
data is as follows:
{ _id: 1, value: 19.25 }
{ _id: 2, value: 28.73 }
{ _id: 3, value: 34.32 }
{ _id: 4, value: -45.34 }
截断 value
为整数的信息:
db.collection('test').field('trunc(value) as truncatedValue').get()
Results of the:
{ "_id" : 1, "truncatedValue" : 19 }
{ "_id" : 2, "truncatedValue" : 28 }
{ "_id" : 3, "truncatedValue" : 34 }
{ "_id" : 4, "truncatedValue" : -45 }
Returns the element at the specified array index.
The example collection users
contains the following documents:
{"_id":1,"name":"dave123",favorites:["chocolate","cake","butter","apples"]}
{"_id":2,"name":"li",favorites:["apples","pudding","pie"]}
{"_id":3,"name":"ahn",favorites:["pears","pecans","chocolate","cherries"]}
{"_id":4,"name":"ty",favorites:["ice cream"]}
Return the first and last elements in the favorites
array:
db.collection('users').field('arrayElemAt(favorites, 0) as first, arrayElemAt(favorites, -1) as last').get()
Results of the:
{"_id":1,"first":"chocolate","last":"apples"}
{"_id":2,"first":"apples","last":"pie"}
{"_id":3,"first":"pears","last":"cherries"}
{"_id":4,"first":"ice cream","last":"ice cream"}
Convert an array to an object.
The example collection inventory
contains a collection of the following documents:
{"_id":1,"item":"ABC1",dimensions:[{"k":"l","v":25},{"k":"w","v":10},{"k":"uom","v":"cm"}]}
{"_id":2,"item":"ABC2",dimensions:[["l",50],["w",25],["uom","cm"]]}
{"_id":3,"item":"ABC3",dimensions:[["l",25],["l","cm"],["l",50]]}
The following returns the dimensions
field as an object:
db.collection('inventory').field('item, arrayToObject(dimensions) as dimensionsObject').get()
Results of the:
{"_id":1,"item":"ABC1","dimensionsObject":{"l":25,"w":10,"uom":"cm"}}
{"_id":2,"item":"ABC2","dimensionsObject":{"l":50,"w":25,"uom":"cm"}}
{"_id":3,"item":"ABC3","dimensionsObject":{"l":50}}
Concatenate multiple arrays into one array.
The example collection warehouses
contains the following documents:
{"_id":1,instock:["chocolate"],ordered:["butter","apples"]}
{"_id":2,instock:["apples","pudding","pie"]}
{"_id":3,instock:["pears","pecans"],ordered:["cherries"]}
{"_id":4,instock:["ice cream"],ordered:[]}
The following example concatenates the instock
and ordered
arrays:
db.collection('warehouses').field('concatArrays(instock, ordered) as items').get()
Results of the:
{"_id":1,"items":["chocolate","butter","apples"]}
{"_id":2,"items":null}
{"_id":3,"items":["pears","pecans","cherries"]}
{"_id":4,"items":["ice cream"]}
Returns the subset of the array that satisfies the condition based on the given condition.
The example collection sales
contains the following documents:
{_id:0,items:[{item_id:43,quantity:2,price:10},{item_id:2,quantity:1,price:240}]}
{_id:1,items:[{item_id:23,quantity:3,price:110},{item_id:103,quantity:4,price:5},{item_id:38,quantity:1,price:300}]}
{_id:2,items:[{item_id:4,quantity:1,price:23}]}
Filter the items
array to only contain documents with price
greater than or equal to 100
:
db.collection('sales').field('filter(items, "item", gte("$$item.price", 100)) as filterItems').get()
Results of the:
{"_id":0,"filterItems":[{"item_id":2,"quantity":1,"price":240}]}
{"_id":1,"filterItems":[{"item_id":23,"quantity":3,"price":110},{"item_id":38,"quantity":1,"price":300}]}
{"_id":2,"filterItems":[]}
Given a value and an array, return true if the value is in the array, false otherwise.
The example collection fruit
has the following documents:
{"_id":1,"location":"24th Street","in_stock":["apples","oranges","bananas"]}
{"_id":2,"location":"36th Street","in_stock":["bananas","pears","grapes"]}
{"_id":3,"location":"82nd Street","in_stock":["cantaloupes","watermelons","apples"]}
Determine whether the bananas
string exists in the in_stock
array:
db.collection('fruit').field('location as storeLocation, in("bananas", in_stock) as hasHananas').get()
Results of the:
{"_id":1,"storeLocation":"24th Street","hasBananas":true}
{"_id":2,"storeLocation":"36th Street","hasBananas":true}
{"_id":3,"storeLocation":"82nd Street","hasBananas":false}
Finds the index of the first element in the array equal to the given value, or returns -1 if not found.
The example collection inventory
contains the following documents:
{"_id":1,"items":["one","two","three"]}
{"_id":2,"items":[1,2,3]}
{"_id":3,"items":[null,null,2]}
{"_id":4,"items":null}
{"_id":5,"amount":3}
Query the array index where the number 2
is located in each items
array:
db.collection('inventory').field('indexOfArray(items, 2) as index').get()
Results of the:
{"_id":1,"index":"-1"}
{"_id":2,"index":"1"}
{"_id":3,"index":"2"}
{"_id":4,"index":null}
{"_id":5,"index":null}
Determines whether the given expression is an array, returns a Boolean value.
The example collection warehouses
contains the following documents:
{"_id":1,instock:["chocolate"],ordered:["butter","apples"]}
{"_id":2,instock:["apples","pudding","pie"]}
{"_id":3,instock:["pears","pecans"],ordered:["cherries"]}
{"_id":4,instock:["ice cream"],ordered:[]}
Check that the instock
and ordered
fields are arrays before concatenating the two fields together:
db.collection('warehouses').field('cond(and(isArray(instock), isArray(ordered)), concatArrays(instock, ordered), "有字段不是数组类型") as items').get()
Results of the:
{"_id":1,"items":["chocolate","butter","apples"]}
{"_id":2,"items":"有字段不是数组类型"}
{"_id":3,"items":["pears","pecans","cherries"]}
{"_id":4,"items":["ice cream"]}
Similar to the map method on JavaScript Array, each element of the given array is converted by the given conversion method to obtain a new array.
An example collection grades
is the following documents:
{_id:1,quizzes:[5,6,7]}
{_id:2,quizzes:[]}
{_id:3,quizzes:[3,8,9]}
Increment each element in the quizzes
array by 1
db.collection('grades').field('map(quizzes, "grade", add("$$grade", 2)) as adjustedGrades').get()
Results of the:
{"_id":1,"adjustedGrades":[7,8,9]}
{"_id":2,"adjustedGrades":[]}
{"_id":3,"adjustedGrades":[5,10,11]}
Convert an object to an array. The method turns each key-value pair of the object into an element of the output array, and the element is in the form of { k: <key>, v: <value> }
The example collection inventory
contains the following documents:
{"_id":1,"item":"ABC1",dimensions:{l:25,w:10,uom:"cm"}}
{"_id":2,"item":"ABC2",dimensions:{l:50,w:25,uom:"cm"}}
{"_id":3,"item":"XYZ1",dimensions:{l:70,w:75,uom:"cm"}}
Return the dimensions
field as an array:
db.collection('inventory').field('item, objectToArray(dimensions) as dimensionsArray').get()
Results of the:
{"_id":1,"item":"ABC1","dimensionsArray":[{"k":"l","v":25},{"k":"w","v":10},{"k":"uom","v":"cm"}]}
{"_id":2,"item":"ABC2","dimensionsArray":[{"k":"l","v":50},{"k":"w","v":25},{"k":"uom","v":"cm"}]}
{"_id":3,"item":"XYZ1","dimensionsArray":[{"k":"l","v":70},{"k":"w","v":75},{"k":"uom","v":"cm"}]}
Returns an array of generated sequence numbers. Given a start value, an end value, and a non-zero step size, range
returns a sequence that increases incrementally from the start value by the given step size, excluding the end value.
The example collection distances
contains the following documents:
{_id:0,city:"San Jose",distance:42}
{_id:1,city:"Sacramento",distance:88}
{_id:2,city:"Reno",distance:218}
{_id:3,city:"Los Angeles",distance:383}
A cyclist is planning to cycle from San Francisco to every city listed in the set and wants to stop every 25 miles to take a break.
The following operations are performed to determine the stopping points for each trip.
db.collection('distances').field('city, range(0, distance, 25) as restStops').get()
The operation returns the following:
{"city":"San Jose","restStops":[0,25]}
{"city":"Sacramento","restStops":[0,25,50,75]}
{"city":"Reno","restStops":[0,25,50,75,100,125,150,175,200]}
{"city":"Los Angeles","restStops":[0,25,50,75,100,125,150,175,200,225,250,275,300,325,350,375]}
Similar to JavaScript's reduce method, it applies an expression to each element of an array and reduces it to a single element.
The example collection clothes
contains the following documents:
{"_id":1,"productId":"ts1","description":"T-Shirt","color":"black","size":"M","price":20,"discounts":[0.5,0.1]}
{"_id":2,"productId":"j1","description":"Jeans","color":"blue","size":"36","price":40,"discounts":[0.25,0.15,0.05]}
{"_id":3,"productId":"s1","description":"Shorts","color":"beige","size":"32","price":30,"discounts":[0.15,0.05]}
{"_id":4,"productId":"ts2","description":"Cool T-Shirt","color":"White","size":"L","price":25,"discounts":[0.3]}
{"_id":5,"productId":"j2","description":"Designer Jeans","color":"blue","size":"30","price":80,"discounts":[0.1,0.25]}
Each document contains a discounts
array containing currently available coupons for each item.
If each discount can be applied to the product at one time, the minimum price can be calculated by applying the following formula to each element in the discounts
array via reduce
(1-discount)*price.
db.collection('clothes').field('reduce(discounts, price, multiply("$$vaule", subtract(1, "$$this")) as discountedPrice').get()
The operation returns the following:
{"_id":ObjectId("57c893067054e6e47674ce01"),"discountedPrice":9}
{"_id":ObjectId("57c9932b7054e6e47674ce12"),"discountedPrice":24.224999999999998}
{"_id":ObjectId("57c993457054e6e47674ce13"),"discountedPrice":24.224999999999998}
{"_id":ObjectId("57c993687054e6e47674ce14"),"discountedPrice":17.5}
{"_id":ObjectId("57c993837054e6e47674ce15"),"discountedPrice":54}
Returns the reversed form of the given array.
The example collection users
contains the following documents:
{"_id":1,"name":"dave123","favorites":["chocolate","cake","butter","apples"]}
{"_id":2,"name":"li","favorites":["apples","pudding","pie"]}
{"_id":3,"name":"ahn","favorites":[]}{"_id":4,"name":"ty"}
The following example favorites
returns an array containing the elements of the array in reverse order:
db.collection('users').field('name, reverseArray(favorites) as reverseFavorites').get()
Results of the:
{"_id":1,"name":"dave123","reverseFavorites":["apples","butter","cake","chocolate"]}
{"_id":2,"name":"li","reverseFavorites":["pie","pudding","apples"]}
{"_id":3,"name":"ahn","reverseFavorites":[]}{"_id":4,"name":"ty","reverseFavorites":null}
Returns the length of the array.
The example collection inventory
contains the following documents:
{"_id":1,"item":"ABC1","description":"product 1",colors:["blue","black","red"]}
{"_id":2,"item":"ABC2","description":"product 2",colors:["purple"]}
{"_id":3,"item":"XYZ1","description":"product 3",colors:[]}
{"_id":4,"item":"ZZZ1","description":"product 4 - missing colors"}
{"_id":5,"item":"ZZZ2","description":"product 5 - colors is string",colors:"blue,red"}
Returns the number of elements in the colors
array:
db.collection('inventory').field('item, cond(isArray(colors), size(colors), "None") as numberOfColors').get()
The operation returns the following:
{"_id":1,"item":"ABC1","numberOfColors":3}
{"_id":2,"item":"ABC2","numberOfColors":1}
{"_id":3,"item":"XYZ1","numberOfColors":0}
{"_id":4,"item":"ZZZ1","numberOfColors":"None"}
{"_id":5,"item":"ZZZ2","numberOfColors":"None"}
Similar to JavaScript's slice method. Returns the specified subset of the given array.
The example collection users
contains the following documents:
{"_id":1,"name":"dave123",favorites:["chocolate","cake","butter","apples"]}
{"_id":2,"name":"li",favorites:["apples","pudding","pie"]}
{"_id":3,"name":"ahn",favorites:["pears","pecans","chocolate","cherries"]}
{"_id":4,"name":"ty",favorites:["ice cream"]}
Return at most the first three elements in the favorites
array for each user:
db.collection('users').field('name, slice(favorites, 3) as threeFavorites').get()
Results of the:
{"_id":1,"name":"dave123","threeFavorites":["chocolate","cake","butter"]}
{"_id":2,"name":"li","threeFavorites":["apples","pudding","pie"]}
{"_id":3,"name":"ahn","threeFavorites":["pears","pecans","chocolate"]}
{"_id":4,"name":"ty","threeFavorites":["ice cream"]}
The elements of the same serial number in the second dimension array of the two-dimensional array are respectively assembled into a new array and then assembled into a new two-dimensional array.
The example collection matrices
contains the following documents:
{matrix:[[1,2],[2,3],[3,4]]}
{matrix:[[8,7],[7,6],[5,4]]}
Compute the transpose of each 3x2 matrix in this set:
db.collection('matrices').field('zip(arrayElemAt(matrix, 0), arrayElemAt(matrix, 1), arrayElemAt(matrix, 2))').get()
Execution returns:
{"transposed":[[1,2,3],[2,3,4]]}
{"transposed":[[8,7,5],[7,6,4]]}
A Boolean expression evaluates its argument expressions to Boolean values and returns a Boolean value as the result.
Given multiple expressions, and returns true only if all of them return true, and returns false otherwise.
Accepts any number of argument expressions.
The example collection inventory
contains the following documents:
{"_id":1,"item":"abc1",description:"product 1",qty:300}
{"_id":2,"item":"abc2",description:"product 2",qty:200}
{"_id":3,"item":"xyz1",description:"product 3",qty:250}
{"_id":4,"item":"VWZ1",description:"product 4",qty:300}
{"_id":5,"item":"VWZ2",description:"product 5",qty:180}
Determine whether the qty
field is greater than 100
and less than 250
:
db.collection('inventory').field('item, qty, and(gt(qty, 100), lt(qty, 250)) as result').get()
Results of the:
{"_id":1,"item":"abc1","qty":300,"result":false}
{"_id":2,"item":"abc2","qty":200,"result":true}
{"_id":3,"item":"xyz1","qty":250,"result":false}
{"_id":4,"item":"VWZ1","qty":300,"result":false}
{"_id":5,"item":"VWZ2","qty":180,"result":true}
Given an expression, not returns false if the expression returns true, and true otherwise. Note that the expression cannot be a logical expression (and, or, nor, not).
The example collection inventory
contains the following documents:
{"_id":1,"item":"abc1",description:"product 1",qty:300}
{"_id":2,"item":"abc2",description:"product 2",qty:200}
{"_id":3,"item":"xyz1",description:"product 3",qty:250}
{"_id":4,"item":"VWZ1",description:"product 4",qty:300}
{"_id":5,"item":"VWZ2",description:"product 5",qty:180}
Determine whether the qty
field is not greater than 250
:
db.collection('inventory').field('item, not(gt(qty, 250)) as result').get()
Results of the:
{"_id":1,"item":"abc1","result":false}
{"_id":2,"item":"abc2","result":true}
{"_id":3,"item":"xyz1","result":true}
{"_id":4,"item":"VWZ1","result":false}
{"_id":5,"item":"VWZ2","result":true}
Given multiple expressions, or returns true if any one of them returns true, otherwise it returns false.
Accepts any number of argument expressions.
The example collection inventory
contains the following documents:
{"_id":1,"item":"abc1",description:"product 1",qty:300}
{"_id":2,"item":"abc2",description:"product 2",qty:200}
{"_id":3,"item":"xyz1",description:"product 3",qty:250}
{"_id":4,"item":"VWZ1",description:"product 4",qty:300}
{"_id":5,"item":"VWZ2",description:"product 5",qty:180}
Determine whether the qty
field is greater than 250
or smaller than 200
:
db.collection('inventory').field('item, or(gt(qty, 250), lt(qty, 200)) as result').get()
Results of the:
{"_id":1,"item":"abc1","result":true}
{"_id":2,"item":"abc2","result":false}
{"_id":3,"item":"xyz1","result":false}
{"_id":4,"item":"VWZ1","result":true}
{"_id":5,"item":"VWZ2","result":true}
Comparison expressions return a boolean value, except cmp
, which returns a number.
Given two values, return their comparison value. Returns -1 if the first value is less than the second value 1 if the first value is greater than the second value 0 if the two values are equal.
The example collection inventory
contains the following documents:
{"_id":1,"item":"abc1",description:"product 1",qty:300}
{"_id":2,"item":"abc2",description:"product 2",qty:200}
{"_id":3,"item":"xyz1",description:"product 3",qty:250}
{"_id":4,"item":"VWZ1",description:"product 4",qty:300}
{"_id":5,"item":"VWZ2",description:"product 5",qty:180}
The qty
value is compared to 250
:
db.collection('inventory').field('item, qty, cmp(qty, 250) as cmpTo250').get()
Results of the:
{"_id": 1,"item":"abc1","qty":300,"cmpTo250":1}
{"_id": 2,"item":"abc2","qty":200,"cmpTo250":-1}
{"_id": 3,"item":"xyz1","qty":250,"cmpTo250":0}
{"_id": 4,"item":"VWZ1","qty":300,"cmpTo250":1}
{"_id": 5,"item":"VWZ2","qty":180,"cmpTo250":-1}
Matches two values, returning true if they are equal, otherwise false.
The example collection inventory
contains the following documents:
{"_id":1,"item":"abc1",description:"product 1",qty:300}
{"_id":2,"item":"abc2",description:"product 2",qty:200}
{"_id":3,"item":"xyz1",description:"product 3",qty:250}
{"_id":4,"item":"VWZ1",description:"product 4",qty:300}
{"_id":5,"item":"VWZ2",description:"product 5",qty:180}
Determine whether qty
is equal to 250
:
db.collection('inventory').field('item, qty, eq(qty, 250) as qtyEq250').get()
Results of the:
{"id": 1,"item":"abc1","qty":300,"qtyEq250":false}
{"id": 2,"item":"abc2","qty":200,"qtyEq250":false}
{"id": 3,"item":"xyz1","qty":250,"qtyEq250":true}
{"id": 4,"item":"VWZ1","qty":300,"qtyEq250":false}
{"id": 5,"item":"VWZ2","qty":180,"qtyEq250":false}
Matches two values, returning true if the former is greater than the latter, false otherwise.
The example collection inventory
contains the following documents:
{"_id":1,"item":"abc1",description:"product 1",qty:300}
{"_id":2,"item":"abc2",description:"product 2",qty:200}
{"_id":3,"item":"xyz1",description:"product 3",qty:250}
{"_id":4,"item":"VWZ1",description:"product 4",qty:300}
{"_id":5,"item":"VWZ2",description:"product 5",qty:180}
Determine whether qty
is greater than 250
:
db.collection('inventory').field('item, qty, gt(qty, 250) as qtyGt250').get()
Results of the:
{"item":"abc1","qty":300,"qtyGt250":true}
{"item":"abc2","qty":200,"qtyGt250":false}
{"item":"xyz1","qty":250,"qtyGt250":false}
{"item":"VWZ1","qty":300,"qtyGt250":true}
{"item":"VWZ2","qty":180,"qtyGt250":false}
Matches two values, returning true if the former is greater than or equal to the latter, false otherwise.
The example collection inventory
contains the following documents:
{"_id":1,"item":"abc1",description:"product 1",qty:300}
{"_id":2,"item":"abc2",description:"product 2",qty:200}
{"_id":3,"item":"xyz1",description:"product 3",qty:250}
{"_id":4,"item":"VWZ1",description:"product 4",qty:300}
{"_id":5,"item":"VWZ2",description:"product 5",qty:180}
Determine whether qty
is greater than or equal to 250
:
db.collection('inventory').field('item, qty, gte(qty, 250) as qtyGte250').get()
Results of the:
{"item":"abc1","qty":300,"qtyGte250":true}
{"item":"abc2","qty":200,"qtyGte250":false}
{"item":"xyz1","qty":250,"qtyGte250":true}
{"item":"VWZ1","qty":300,"qtyGte250":true}
{"item":"VWZ2","qty":180,"qtyGte250":false}
Matches two values, returning true if the former is less than the latter, false otherwise.
The example collection inventory
contains the following documents:
{"_id":1,"item":"abc1",description:"product 1",qty:300}
{"_id":2,"item":"abc2",description:"product 2",qty:200}
{"_id":3,"item":"xyz1",description:"product 3",qty:250}
{"_id":4,"item":"VWZ1",description:"product 4",qty:300}
{"_id":5,"item":"VWZ2",description:"product 5",qty:180}
Determine whether qty
is less than 250
:
db.collection('inventory').field('item, qty, lt(qty, 250) as qtyLt250').get()
Results of the:
{"_id": 1,"item":"abc1","qty":300,"qtyLt250":false}
{"_id": 2,"item":"abc2","qty":200,"qtyLt250":true}
{"_id": 3,"item":"xyz1","qty":250,"qtyLt250":false}
{"_id": 4,"item":"VWZ1","qty":300,"qtyLt250":false}
{"_id": 5,"item":"VWZ2","qty":180,"qtyLt250":true}
Matches two values, returning true if the former is less than or equal to the latter, false otherwise.
The example collection inventory
contains the following documents:
{"_id":1,"item":"abc1",description:"product 1",qty:300}
{"_id":2,"item":"abc2",description:"product 2",qty:200}
{"_id":3,"item":"xyz1",description:"product 3",qty:250}
{"_id":4,"item":"VWZ1",description:"product 4",qty:300}
{"_id":5,"item":"VWZ2",description:"product 5",qty:180}
Determine whether qty
is less than or equal to 250
:
db.collection('inventory').field('item, qty, lte(qty, 250) as qtyLte250').get()
Results of the:
{"_id": 1,"item":"abc1","qty":300,"qtyLte250":false}
{"_id": 2,"item":"abc2","qty":200,"qtyLte250":true}
{"_id": 3,"item":"xyz1","qty":250,"qtyLte250":true}
{"_id": 4,"item":"VWZ1","qty":300,"qtyLte250":false}
{"_id": 5,"item":"VWZ2","qty":180,"qtyLte250":true}
Matches two values, returning true if they are not equal, false otherwise.
The example collection inventory
contains the following documents:
{"_id":1,"item":"abc1",description:"product 1",qty:300}
{"_id":2,"item":"abc2",description:"product 2",qty:200}
{"_id":3,"item":"xyz1",description:"product 3",qty:250}
{"_id":4,"item":"VWZ1",description:"product 4",qty:300}
{"_id":5,"item":"VWZ2",description:"product 5",qty:180}
Determine whether qty
is not equal to 250
:
db.collection('inventory').field('item, qty, neq(qty, 250) as qtyNe250').get()
Results of the:
{"_id": 1,"item":"abc1","qty":300,"qtyNe250":true}
{"_id": 2,"item":"abc2","qty":200,"qtyNe250":true}
{"_id": 3,"item":"xyz1","qty":250,"qtyNe250":false}
{"_id": 4,"item":"VWZ1","qty":300,"qtyNe250":true}
{"_id": 5,"item":"VWZ2","qty":180,"qtyNe250":true}
Evaluates Boolean expression 1, returns expression 2 if true, otherwise returns expression 3.
The example collection inventory
contains the following documents:
{"_id":1,"item":"abc1",qty:300}
{"_id":2,"item":"abc2",qty:200}
{"_id":3,"item":"xyz1",qty:250}
If qty
value is greater than or equal to 250, set discount
to 30, otherwise set to 20:
db.collection('inventory').field('item, cond(gte(qty, 250), 30, 20) as discount').get()
Results of the:
{"_id":1,"item":"abc1","discount":30}
{"_id":2,"item":"abc2","discount":20}
{"_id":3,"item":"xyz1","discount":30}
Evaluates the given expression and returns a replacement value if the expression evaluates to null, undefined, or does not exist; otherwise returns the original value.
The example collection inventory
contains the following documents:
{"_id":1,"item":"abc1",description:"product 1",qty:300}
{"_id":2,"item":"abc2",description:null,qty:200}
{"_id":3,"item":"xyz1",qty:250}
If the description
field is empty or does not exist, return the string "Unspecified"
, otherwise return the value of the description
field:
db.collection('inventory').field('item, ifNull(description, "Unspecified") as description').get()
Results of the:
{"_id":1,"item":"abc1","description":"product 1"}
{"_id":2,"item":"abc2","description":"Unspecified"}
{"_id":3,"item":"xyz1","description":"Unspecified"}
Computes the return value according to the given switch-case-default.
The example collection grades
contains the following documents:
{"_id":1,"name":"Susan Wilkes","scores":[87,86,78]}
{"_id":2,"name":"Bob Hanna","scores":[71,64,81]}
{"_id":3,"name":"James Torrelio","scores":[91,84,97]}
Display specific messages based on each student's average score.
db.collection('grades').field('name, switch([{case: gte(avg(scores), 90), then: "Doing great!"}, {case: and(gte(avg(scores), 80), lt(avg(scores), 90)), then: "Doing pretty well."}, {case: lt(avg(scores), 80), then: "Needs improvement."}], "No scores found.")').get()
The operation returns the following:
{"_id":1,"name":"Susan Wilkes","summary":"Doing pretty well."}
{"_id":2,"name":"Bob Hanna","summary":"Needs improvement."}
{"_id":3,"name":"James Torrelio","summary":"Doing great!"}
Given information about a date, construct and return a date object.
Constructs three date objects from the provided input fields:
db.collection('sales').field('dateFromParts(2017, 2, 8, 12) as date, isoDateFromParts(2017, 6, 3, 12) as date_iso, dateFromParts(2016, 12, 31, 23, 46, 12, "America/New_York") as date_timezone').get()
Results of the:
{"_id":1,"date":"2017-02-08T12:00:00Z","date_iso":"2017-02-08T12:00:00Z","date_timezone":"2017-01-01T04:46:12Z"}
Convert a date/time string to a date object.
The example collection logmessages
contains the following collections.
{_id:1,date:"2017-02-08T12:10:40.787",timezone:"America/New_York",message:"Step 1: Started"}
{_id:2,date:"2017-02-08",timezone:"-05:00",message:"Step 1: Ended"}
{_id:3,message:" Step 1: Ended "}
{_id:4,date:"2017-02-09",timezone:"Europe/London",message:"Step 2: Started"}
{_id:5,date:"2017-02-09T03:35:02.055",timezone:"+0530",message:"Step 2: In Progress"}
** Convert a date
value to a date object:**
db.collection('logmessages').field('dateFromString(date, "%Y-%m-%dT%H:%M:%S.%LZ", "America/New_York") as date').get()
Results of the:
{"_id":1,"date": "2017-02-08T17:10:40.787Z"}
{"_id":2,"date": "2017-02-08T05:00:00Z"}
{"_id":3,"date":null}
{"_id":4,"date": "2017-02-09T05:00:00Z"}
{"_id":5,"date": "2017-02-09T08:35:02.055Z"}
** The timezone
parameter can also be provided via a document field instead of a hardcoded parameter. For example:**
db.collection('logmessages').field('dateFromString(date, "%Y-%m-%dT%H:%M:%S.%LZ", timezone) as date').get()
Results of the:
{"_id":1,"date":"2017-02-08T17:10:40.787Z"}
{"_id":2,"date":"2017-02-08T05:00:00Z"}
{"_id":3,"date":null}
{"_id":4,"date":"2017-02-09T00:00:00Z"}
{"_id":5,"date":"2017-02-08T22:05:02.055Z"}
If the collection has an unparseable date string, an error onError
will be raised, and the onError
parameter can be used to return an invalid date in its raw string form:
An example collection dates
is as follows:
{"_id":1,"date":"2017-02-08T12:10:40.787",timezone:"America/New_York"}
{"_id":2,"date":"20177-02-09T03:35:02.055",timezone:"America/New_York"}
db.collection('dates').field('dateFromString(date, "%Y-%m-%dT%H:%M:%S.%L", timezone, date)')
Results of the:
{"_id":1,"date": "2017-02-08T17:10:40.787Z"}
{"_id":2,"date": "20177-02-09T03:35:02.055"}
If there is a null
date string in the collection, you can use the onNull
parameter to return a date:
An example collection dates
is as follows:
{"_id":1,"date":"2017-02-08T12:10:40.787",timezone:"America/New_York"}
{"_id":2,"date":null,timezone:"America/New_York"}
db.collection('dates').field('dateFromString(date, "%Y-%m-%dT%H:%M:%S.%L", timezone, date, new Date(0))')
Results of the:
{"_id":1,"date": "2017-02-08T17:10:40.787Z"}
{"_id":2,"date": "1970-01-01T00:00:00Z"}
Formats a date object as a string according to the specified expression.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:15:39.736Z"}
Format the date
field and return:
db.collection('sales').field('dateToString(date, "%Y-%m-%d") as yearMonthDayUTC, dateToString(date, "%H:%M:%S:%L%z", "America/New_York") as timewithOffsetNY, dateToString(date, "%H:%M:%S:%L%z", "+04:30") as timewithOffset430, dateToString(date, "%Z", "America/New_York") as minutesOffsetNY, dateToString(date, "%Z", "+04:30") as minutesOffset430').get()
Results of the:
{"_id":1,"yearMonthDayUTC":"2014-01-01","timewithOffsetNY":"03:15:39:736-0500","timewithOffset430":"12:45:39:736+0430","minutesOffsetNY":"-300","minutesOffset430":"270"}
Returns the day (the day of the month) corresponding to the date field, which is a number between 1 and 31.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:15:39.736Z"}
Parsing the date
field:
db.collection('sales').field('year(date) as year, month(date) as month, dayOfMonth(date) as day, hour(date) as hour, minutes(date) as minutes, second(date) as seconds, millisecond(date) as milliseconds, dayOfYear(date) as dayOfYear, dayOfWeek(date) as dayOfWeek, week(date) as week').get()
Results of the:
{"_id":1,"year":2014,"month":1,"day":1,"hour":8,"minutes":15,"seconds":39,"milliseconds":736,"dayOfYear":1,"dayOfWeek":4,"week":0}
Returns the day (day of the week) corresponding to the date field, which is an integer between 1 (Sunday) and 7 (Saturday).
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:15:39.736Z"}
Parsing the date
field:
db.collection('sales').field('year(date) as year, month(date) as month, dayOfMonth(date) as day, hour(date) as hour, minutes(date) as minutes, second(date) as seconds, millisecond(date) as milliseconds, dayOfYear(date) as dayOfYear, dayOfWeek(date) as dayOfWeek, week(date) as week').get()
Results of the:
{"_id":1,"year":2014,"month":1,"day":1,"hour":8,"minutes":15,"seconds":39,"milliseconds":736,"dayOfYear":1,"dayOfWeek":4,"week":0}
Returns the day number (the day of the year) corresponding to the date field, which is an integer between 1 and 366.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:15:39.736Z"}
Parsing the date
field:
db.collection('sales').field('year(date) as year, month(date) as month, dayOfMonth(date) as day, hour(date) as hour, minutes(date) as minutes, second(date) as seconds, millisecond(date) as milliseconds, dayOfYear(date) as dayOfYear, dayOfWeek(date) as dayOfWeek, week(date) as week').get()
Results of the:
{"_id":1,"year":2014,"month":1,"day":1,"hour":8,"minutes":15,"seconds":39,"milliseconds":736,"dayOfYear":1,"dayOfWeek":4,"week":0}
Returns the hour corresponding to the date field, an integer between 0 and 23.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:15:39.736Z"}
Parsing the date
field:
db.collection('sales').field('year(date) as year, month(date) as month, dayOfMonth(date) as day, hour(date) as hour, minutes(date) as minutes, second(date) as seconds, millisecond(date) as milliseconds, dayOfYear(date) as dayOfYear, dayOfWeek(date) as dayOfWeek, week(date) as week').get()
Results of the:
{"_id":1,"year":2014,"month":1,"day":1,"hour":8,"minutes":15,"seconds":39,"milliseconds":736,"dayOfYear":1,"dayOfWeek":4,"week":0}
Returns the ISO 8601 day number (day of the week) corresponding to the date field, which is an integer between 1 (Monday) and 7 (Sunday).
The example collection birthdays
contains the following documents:
{"_id":1,"name":"Betty","birthday":"1993-09-21T00:00:00Z"}
{"_id":2,"name":"Veronica","birthday":"1981-11-07T00:00:00Z"}
Return the day of the week from the birthday
field:
db.collection('dates').field('name, isoDayOfWeek(birthday) as dayOfWeek').get()
Results of the:
{"name":"Betty","dayOfWeek":2}{"name":"Veronica","dayOfWeek":6}
Returns the ISO 8601 week number (week of the year) corresponding to the date field, an integer between 1 and 53.
The example collection deliveries
contains the following documents:
{"_id":1,"date":"2006-10-24T00:00:00Z","city":"Boston"}
{"_id":2,"date":"2011-08-18T00:00:00Z","city":"Detroit"}
Returns the week number for each date
field.
db.collection('deliveries').field('city, isoWeek(date) as weekNumber').get()
Results of the:
{"city":"Boston","weekNumber":43}{"city":"Detroit","weekNumber":33}
Returns the ISO 8601 day number (day of the year) for a date field.
The example collection anniversaries
contains the following documents:
{"_id":1,"date":"2016-01-01T00:00:00Z"}
{"_id":2,"date":"2016-01-04T00:00:00Z"}
{"_id":3,"date":"2015-01-01T00:00:00Z"}
{"_id":4,"date":"2014-04-21T00:00:00Z"}
Returns the year in ISO 8601 format for the date
field.
db.collection('anniversaries').field('isoWeekYear(date) as yearNumber').get()
Results of the:
{"_id":1,"yearNumber":2015}
{"_id":2,"yearNumber":2016}
{"_id":3,"yearNumber":2015}
{"_id":4,"yearNumber":2014}
Returns the milliseconds corresponding to the date field, which is an integer between 0 and 999.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:15:39.736Z"}
Parsing the date
field:
db.collection('sales').field('year(date) as year, month(date) as month, dayOfMonth(date) as day, hour(date) as hour, minutes(date) as minutes, second(date) as seconds, millisecond(date) as milliseconds, dayOfYear(date) as dayOfYear, dayOfWeek(date) as dayOfWeek, week(date) as week').get()
Returns the minute corresponding to the date field, an integer between 0 and 59.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:15:39.736Z"}
Parsing the date
field:
db.collection('sales').field('year(date) as year, month(date) as month, dayOfMonth(date) as day, hour(date) as hour, minutes(date) as minutes, second(date) as seconds, millisecond(date) as milliseconds, dayOfYear(date) as dayOfYear, dayOfWeek(date) as dayOfWeek, week(date) as week').get()
Returns the month corresponding to the date field, which is an integer between 1 and 12.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:15:39.736Z"}
Parsing the date
field:
db.collection('sales').field('year(date) as year, month(date) as month, dayOfMonth(date) as day, hour(date) as hour, minutes(date) as minutes, second(date) as seconds, millisecond(date) as milliseconds, dayOfYear(date) as dayOfYear, dayOfWeek(date) as dayOfWeek, week(date) as week').get()
Returns the number of seconds corresponding to the date field, an integer between 0 and 59, which may be equal to 60 in special cases (leap seconds).
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:15:39.736Z"}
Parsing the date
field:
db.collection('sales').field('year(date) as year, month(date) as month, dayOfMonth(date) as day, hour(date) as hour, minutes(date) as minutes, second(date) as seconds, millisecond(date) as milliseconds, dayOfYear(date) as dayOfYear, dayOfWeek(date) as dayOfWeek, week(date) as week').get()
Returns the week number (week of the year) corresponding to the date field, which is an integer between 0 and 53.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:15:39.736Z"}
Parsing the date
field:
db.collection('sales').field('year(date) as year, month(date) as month, dayOfMonth(date) as day, hour(date) as hour, minutes(date) as minutes, second(date) as seconds, millisecond(date) as milliseconds, dayOfYear(date) as dayOfYear, dayOfWeek(date) as dayOfWeek, week(date) as week').get()
Returns the year corresponding to the date field.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:15:39.736Z"}
Parsing the date
field:
db.collection('sales').field('year(date) as year, month(date) as month, dayOfMonth(date) as day, hour(date) as hour, minutes(date) as minutes, second(date) as seconds, millisecond(date) as milliseconds, dayOfYear(date) as dayOfYear, dayOfWeek(date) as dayOfWeek, week(date) as week').get()
Pass in a timestamp and return the corresponding date object.
Only supported in JQL strings, supported since HBuilderX 3.1.0
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","date": 1664697600000}
Return a date object for the date
field:
db.collection('sales').field('item, timestampToDate(date) as date').get()
Results of the:
{"_id":1,"item":"abc","date": "2022-10-02T08:00:00.000Z"}
Directly returns a value literal without any parsing and processing.
Treat $
as a literal value
The example collection records
contains the following documents:
{"_id":1,"item":"abc123",price:"$2.50"}
{"_id":2,"item":"xyz123",price:"1"}
{"_id":3,"item":"ijk123",price:"$1"}
Check whether price
is equal to the string $1
:
db.collection('records').field('eq(price, literal($1)) as costsOneDollar').get()
Results of the:
{"_id":1,"costsOneDollar":false}
{"_id":2,"costsOneDollar":false}
{"_id":3,"costsOneDollar":true}
Merge multiple objects into a single object.
Note: If the documents to be merged contain the same field names, the fields in the resulting document will override the values in the last merged document.
The example collection orders
contains the following documents:
{"_id":1,"item":"abc","price":12,"ordered":2}
{"_id":2,"item":"jkl","price":20,"ordered":1}
Another example collection items
contains the following documents:
{"_id":1,"item":"abc",description:"product 1","instock":120}
{"_id":2,"item":"def",description:"product 2","instock":80}
{"_id":3,"item":"jkl",description:"product 3","instock":60}
Merge items
and orders
First associate the two tables through lookup
, and then use the mergeObjects
expression to merge the two tables in the replaceRoot
stage.
db.collection('orders').aggregate().lookup({
from: "items",
let: {
item: "$item"
},
pipeline: $.pipeline().match(db.command.expr($.and([
$.eq(['$item', '$$item'])
]))).done(),
as: 'fromItems'
}).replaceRoot({
newRoot: $.mergeObjects([ $.arrayElemAt(['$fromItems', 0]), '$$ROOT' ])
}).project({
fromItems: 0
}).end()
Execution returns:
{"_id":1,"item":"abc","description":"product 1","instock":120,"price":12,"ordered":2}
{"_id":2,"item":"jkl","description":"product 3","instock":60,"price":20,"ordered":1}
used in groupBy
The example collection sales
contains the following documents:
{_id:1,year:2017,item:"A",quantity:{"2017Q1":500,"2017Q2":500}}
{_id:2,year:2016,item:"A",quantity:{"2016Q1":400,"2016Q2":300,"2016Q3":0,"2016Q4":0}}
{_id:3,year:2017,item:"B",quantity:{"2017Q1":300}}
{_id:4,year:2016,item:"B",quantity:{"2016Q3":100,"2016Q4":250}}
Group by item
, mergeObjects
only accepts single object operations.
db.collection('sales').groupBy('item').groupField('mergeObjects(quantity) as mergedSales').get()
Results of the:
{"_id":"B","mergedSales":{"2017Q1":300,"2016Q3":100,"2016Q4":250}}
{"_id":"A","mergedSales":{"2017Q1":500,"2017Q2":500,"2016Q1":400,"2016Q2":300,"2016Q3":0,"2016Q4":0}}
Convert a document to an array of documents representing key-value pairs.
The example collection inventory
contains the following documents:
{"_id":1,"item":"ABC1",dimensions:{l:25,w:10,uom:"cm"}}
{"_id":2,"item":"ABC2",dimensions:{l:50,w:25,uom:"cm"}}
{"_id":3,"item":"XYZ1",dimensions:{l:70,w:75,uom:"cm"}}
Return the dimensions
field as an array:
db.collection('inventory').field('item, objectToArray(dimensions) as dimensionsArray').get()
Results of the:
{"_id":1,"item":"ABC1","dimensions":[{"k":"l","v":25},{"k":"w","v":10},{"k":"uom","v":"cm"}]}
{"_id":2,"item":"ABC2","dimensions":[{"k":"l","v":50},{"k":"w","v":25},{"k":"uom","v":"cm"}]}
{"_id":3,"item":"XYZ1","dimensions":[{"k":"l","v":70},{"k":"w","v":75},{"k":"uom","v":"cm"}]}
Set expressions perform set operations on arrays, treating arrays as sets. Set expressions ignore duplicate entries and the order of elements in each input array.
If a set operation returns a set, the operation filters out duplicates in the result to output an array containing only unique entries. The order of elements in the output array is unspecified.
If the set contains nested array elements, the set expression does not descend into the nested array, but evaluates the array at the top level.
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 example collection survey
uses the following documents:
{"_id":1,"responses":[true]}
{"_id":2,"responses":[true,false]}
{"_id":3,"responses":[]}
{"_id":4,"responses":[1,true,"seven"]}
{"_id":5,"responses":[0]}
{"_id":6,"responses":[[]]}
{"_id":7,"responses":[[0]]}
{"_id":8,"responses":[[false]]}
{"_id":9,"responses":[null]}
{"_id":10,"responses":[undefined]}
Check if the responses
array contains only values that evaluate to true
:
db.collection('survey').field('responses, allElementsTrue(responses) as isAllTrue').get()
Results of the:
{"responses":[true],"isAllTrue":true}
{"responses":[true,false],"isAllTrue":false}
{"responses":[],"isAllTrue":true}
{"responses":[1,true,"seven"],"isAllTrue":true}
{"responses":[0],"isAllTrue":false}
{"responses":[[]],"isAllTrue":true}
{"responses":[[0]],"isAllTrue":true}
{"responses":[[false]],"isAllTrue":true}
{"responses":[null],"isAllTrue":false}
{"responses":[undefined],"isAllTrue":false}
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 example collection survey
contains the following documents:
{"_id":1,"responses":[true]}
{"_id":2,"responses":[true,false]}
{"_id":3,"responses":[]}
{"_id":4,"responses":[1,true,"seven"]}
{"_id":5,"responses":[0]}
{"_id":6,"responses":[[]]}
{"_id":7,"responses":[[0]]}
{"_id":8,"responses":[[false]]}
{"_id":9,"responses":[null]}
{"_id":10,"responses":[undefined]}
Determine if the responses
array contains any that evaluate to true
:
db.collection('survey').field('responses, anyElementTrue(responses) as isAnyTrue').get()
Results of the:
{"responses":[true],"isAnyTrue":true}
{"responses":[true,false],"isAnyTrue":true}
{"responses":[],"isAnyTrue":false}
{"responses":[1,true,"seven"],"isAnyTrue":true}
{"responses":[0],"isAnyTrue":false}
{"responses":[[]],"isAnyTrue":true}
{"responses":[[0]],"isAnyTrue":true}
{"responses":[[false]],"isAnyTrue":true}
{"responses":[null],"isAnyTrue":false}
{"responses":[undefined],"isAnyTrue":false}
Input two collections, output elements that only exist in the first collection
The example collection experiments
contains the following documents:
{"_id":1,"A":["red","blue"],"B":["red","blue"]}
{"_id":2,"A":["red","blue"],"B":["blue","red","blue"]}
{"_id":3,"A":["red","blue"],"B":["red","blue","green"]}
{"_id":4,"A":["red","blue"],"B":["green","red"]}
{"_id":5,"A":["red","blue"],"B":[]}
{"_id":6,"A":["red","blue"],"B":[["red"],["blue"]]}
{"_id":7,"A":["red","blue"],"B":[["red","blue"]]}
{"_id":8,"A":[],"B":[]}
{"_id":9,"A":[],"B":["red"]}
Compare A and B arrays and return only the values in array B:
db.collection('experiments').field('A, B, setDifference(B, A) as inBOnly').get()
Results of the:
{"A":["red","blue"],"B":["red","blue"],"inBOnly":[]}
{"A":["red","blue"],"B":["blue","red","blue"],"inBOnly":[]}
{"A":["red","blue"],"B":["red","blue","green"],"inBOnly":["green"]}
{"A":["red","blue"],"B":["green","red"],"inBOnly":["green"]}
{"A":["red","blue"],"B":[],"inBOnly":[]}
{"A":["red","blue"],"B":[["red"],["blue"]],"inBOnly":[["red"],["blue"]]}
{"A":["red","blue"],"B":[["red","blue"]],"inBOnly":[["red","blue"]]}
{"A":[],"B":[],"inBOnly":[]}
{"A":[],"B":["red"],"inBOnly":["red"]}
Enter two collections, and judge whether the elements contained in the two collections are the same (regardless of order, deduplication)
The example collection experiments
contains the following documents:
{"_id":1,"A":["red","blue"],"B":["red","blue"]}
{"_id":2,"A":["red","blue"],"B":["blue","red","blue"]}
{"_id":3,"A":["red","blue"],"B":["red","blue","green"]}
{"_id":4,"A":["red","blue"],"B":["green","red"]}
{"_id":5,"A":["red","blue"],"B":[]}
{"_id":6,"A":["red","blue"],"B":[["red"],["blue"]]}
{"_id":7,"A":["red","blue"],"B":[["red","blue"]]}
{"_id":8,"A":[],"B":[]}{"_id":9,"A":[],"B":["red"]}
Determine whether A
array and B
array contain the same elements:
db.collection('experiments').field('A, B, setEquals(A, B) as sameElements').get()
Results of the:
{"A":["red","blue"],"B":["red","blue"],"sameElements":true}
{"A":["red","blue"],"B":["blue","red","blue"],"sameElements":true}
{"A":["red","blue"],"B":["red","blue","green"],"sameElements":false}
{"A":["red","blue"],"B":["green","red"],"sameElements":false}
{"A":["red","blue"],"B":[],"sameElements":false}
{"A":["red","blue"],"B":[["red"],["blue"]],"sameElements":false}
{"A":["red","blue"],"B":[["red","blue"]],"sameElements":false}
{"A":[],"B":[],"sameElements":true}{"A":[],"B":["red"],"sameElements":false}
Input two sets, output the intersection of the two sets
The example collection experiments
contains the following documents:
{"_id":1,"A":["red","blue"],"B":["red","blue"]}
{"_id":2,"A":["red","blue"],"B":["blue","red","blue"]}
{"_id":3,"A":["red","blue"],"B":["red","blue","green"]}
{"_id":4,"A":["red","blue"],"B":["green","red"]}
{"_id":5,"A":["red","blue"],"B":[]}
{"_id":6,"A":["red","blue"],"B":[["red"],["blue"]]}
{"_id":7,"A":["red","blue"],"B":[["red","blue"]]}
{"_id":8,"A":[],"B":[]}{"_id":9,"A":[],"B":["red"]}
Returns an array of elements common to arrays A
and B
:
db.collection('experiments').field('A, B, setIntersection(A, B) as commonToBoth').get()
Results of the:
{"A":["red","blue"],"B":["red","blue"],"commonToBoth":["blue","red"]}
{"A":["red","blue"],"B":["blue","red","blue"],"commonToBoth":["blue","red"]}
{"A":["red","blue"],"B":["red","blue","green"],"commonToBoth":["blue","red"]}
{"A":["red","blue"],"B":["green","red"],"commonToBoth":["red"]}
{"A":["red","blue"],"B":[],"commonToBoth":[]}
{"A":["red","blue"],"B":[["red"],["blue"]],"commonToBoth":[]}
{"A":["red","blue"],"B":[["red","blue"]],"commonToBoth":[]}
{"A":[],"B":[],"commonToBoth":[]}{"A":[],"B":["red"],"commonToBoth":[]}
Given two sets, determine whether the first set is a subset of the second set.
The example collection experiments
contains the following documents:
{"_id":1,"A":["red","blue"],"B":["red","blue"]}
{"_id":2,"A":["red","blue"],"B":["blue","red","blue"]}
{"_id":3,"A":["red","blue"],"B":["red","blue","green"]}
{"_id":4,"A":["red","blue"],"B":["green","red"]}
{"_id":5,"A":["red","blue"],"B":[]}
{"_id":6,"A":["red","blue"],"B":[["red"],["blue"]]}
{"_id":7,"A":["red","blue"],"B":[["red","blue"]]}
{"_id":8,"A":[],"B":[]}{"_id":9,"A":[],"B":["red"]}
Determine whether the array A
is a subset of the array B
:
db.collection('experiments').field('A, B, setIsSubset(A, B) as AisSubset').get()
Results of the:
{"A":["red","blue"],"B":["red","blue"],"AisSubset":true}
{"A":["red","blue"],"B":["blue","red","blue"],"AisSubset":true}
{"A":["red","blue"],"B":["red","blue","green"],"AisSubset":true}
{"A":["red","blue"],"B":["green","red"],"AisSubset":false}
{"A":["red","blue"],"B":[],"AisSubset":false}
{"A":["red","blue"],"B":[["red"],["blue"]],"AisSubset":false}
{"A":["red","blue"],"B":[["red","blue"]],"AisSubset":false}
{"A":[],"B":[],"AisSubset":true}{"A":[],"B":["red"],"AisSubset":true}
Input two sets and output the union of the two sets.
The example collection experiments
contains the following documents:
{"_id":1,"A":["red","blue"],"B":["red","blue"]}
{"_id":2,"A":["red","blue"],"B":["blue","red","blue"]}
{"_id":3,"A":["red","blue"],"B":["red","blue","green"]}
{"_id":4,"A":["red","blue"],"B":["green","red"]}
{"_id":5,"A":["red","blue"],"B":[]}
{"_id":6,"A":["red","blue"],"B":[["red"],["blue"]]}
{"_id":7,"A":["red","blue"],"B":[["red","blue"]]}
{"_id":8,"A":[],"B":[]}{"_id":9,"A":[],"B":["red"]}
Return an array of elements found in the A
array or the B
array, or both:
db.collection('experiments').field('A, B, setUnion(A, B) as allValues').get()
Results of the:
{"A":["red","blue"],"B":["red","blue"],"allValues":["blue","red"]}
{"A":["red","blue"],"B":["blue","red","blue"],"allValues":["blue","red"]}
{"A":["red","blue"],"B":["red","blue","green"],"allValues":["blue","red","green"]}
{"A":["red","blue"],"B":["green","red"],"allValues":["blue","red","green"]}
{"A":["red","blue"],"B":[],"allValues":["blue","red"]}
{"A":["red","blue"],"B":[["red"],["blue"]],"allValues":["blue","red",["red"],["blue"]]}
{"A":["red","blue"],"B":[["red","blue"]],"allValues":["blue","red",["red","blue"]]}
{"A":[],"B":[],"allValues":[]}{"A":[],"B":["red"],"allValues":["red"]}
String expressions (except concat
) have well-defined behavior only for strings of ASCII characters.
The behavior of concat
is well-defined independent of the characters used.
Concatenate any number of strings.
The example collection inventory
contains the following documents:
{"_id":1,"item":"ABC1",quarter:"13Q1","description":"product 1"}
{"_id":2,"item":"ABC2",quarter:"13Q4","description":"product 2"}
{"_id":3,"item":"XYZ1",quarter:"14Q2","description":null}
Concatenate the item
field and the description
field with the "-" delimiter:
db.collection('inventory').field('concat(item, "-", "description") as itemDescription').get()
Results of the:
{"_id":1,"itemDescription":"ABC1 - product 1"}
{"_id":2,"itemDescription":"ABC2 - product 2"}
{"_id":3,"itemDescription":null}
Finds a substring in the target string and returns the UTF-8 byte index (starting from 0) of the first occurrence. Returns -1 if no substring exists
The example collection inventory
contains the following documents:
{"_id":1,"item":"foo"}
{"_id":2,"item":"fóofoo"}
{"_id":3,"item":"the foo bar"}
{"_id":4,"item":"hello world fóo"}
{"_id":5,"item":null}{"_id":6,"amount":3}
Retrieve the index where the string foo resides in each item:
db.collection('inventory').field('indexOfBytes(item, "foo") as bytyLocation').get()
Results of the:
{"_id":1,"byteLocation":"0"}
{"_id":2,"byteLocation":"4"}
{"_id":3,"byteLocation":"4"}
{"_id":4,"byteLocation":"-1"}
{"_id":5,"byteLocation":null}
{"_id":6,"byteLocation":null}
Finds a substring in the target string and returns the UTF-8 code point index (starting from 0) of the first occurrence. Returns -1 if no substring exists
The example collection inventory
contains the following documents:
{"_id":1,"item":"foo"}
{"_id":2,"item":"fóofoo"}
{"_id":3,"item":"the foo bar"}
{"_id":4,"item":"hello world fóo"}
{"_id":5,"item":null}
{"_id":6,"amount":3}
Returns the code point index where the string is located in each item
string of foo
:
db.collection('inventory').field('indexOfCP(item, "foo") as cpLocation').get()
Results of the:
{"_id":1,"cpLocation":"0"}
{"_id":2,"cpLocation":"3"}
{"_id":3,"cpLocation":"4"}
{"_id":4,"cpLocation":"-1"}
{"_id":5,"cpLocation":null}
{"_id":6,"cpLocation":null}
Splits the array by delimiter and removes the delimiter, returning an array of substrings. If the string cannot be separated by a delimiter, return the original string as the only element of the array
The example collection deliveries
contains the following documents:
{"_id":1,"city":"Berkeley, CA","qty":648}
{"_id":2,"city":"Bend, OR","qty":491}
{"_id":3,"city":"Kensington, CA","qty":233}
Create string array city
field by splitting, using ,
as delimiter.
db.collection('deliveries').field('split(city, ", ") as city_state').get()
Results of the:
{"_id":1,"city_state":["Berkeley", "CA"]}
{"_id":2,"city_state":["Bend", "OR"]}
{"_id":3,"city_state":["Kensington", "CA"]}
Calculates and returns the number of utf-8 encoded bytes in the specified string.
The example collection food
contains the following documents:
{"_id":1,"name":"apple"}
{"_id":2,"name":"banana"}
{"_id":3,"name":"éclair"}
{"_id":4,"name":"hamburger"}
{"_id":5,"name":"jalapeño"}
{"_id":6,"name":"pizza"}
{"_id":7,"name":"tacos"}
{"_id":8,"name":"寿司"}
Compute the length
for each name
value:
db.collection('food').field('name, strLenBytes(name) as length').get()
Results of the:
{"_id":1,"name":"apple","length":5}
{"_id":2,"name":"banana","length":6}
{"_id":3,"name":"éclair","length":7}
{"_id":4,"name":"hamburger","length":9}
{"_id":5,"name":"jalapeño","length":9}
{"_id":6,"name":"pizza","length":5}
{"_id":7,"name":"tacos","length":5}
{"_id":8,"name":"寿司","length":6}
The documents for _id: 3 and _id: 5 each contain an umlaut (é and ñ, respectively), which requires two bytes to encode.
The document with _id: 8 contains two Japanese characters encoded using three bytes each.
This makes the length greater than the number of characters in the names of documents with _id: 3, _id: 5, and _id: 8.
Calculates and returns the number of UTF-8 code points for the specified string.
The example collection food
contains the following documents:
{"_id":1,"name":"apple"}
{"_id":2,"name":"banana"}
{"_id":3,"name":"éclair"}
{"_id":4,"name":"hamburger"}
{"_id":5,"name":"jalapeño"}
{"_id":6,"name":"pizza"}
{"_id":7,"name":"tacos"}
{"_id":8,"name":"寿司"}
Compute the length
for each name
value:
db.collection('food').field('name, strLenCP(name) as length').get()
Results of the:
{"_id":1,"name":"apple","length":5}
{"_id":2,"name":"banana","length":6}
{"_id":3,"name":"éclair","length":6}
{"_id":4,"name":"hamburger","length":9}
{"_id":5,"name":"jalapeño","length":8}
{"_id":6,"name":"pizza","length":5}
{"_id":7,"name":"tacos","length":5}
{"_id":8,"name":"寿司","length":2}
Compare two strings case-insensitively, and return the result of the comparison
The example collection inventory
contains the following documents:
{"_id":1,"item":"ABC1",quarter:"13Q1","description":"product 1"}
{"_id":2,"item":"ABC2",quarter:"13Q4","description":"product 2"}
{"_id":3,"item":"XYZ1",quarter:"14Q2","description":null}
Perform a case-insensitive comparison of the quarter
field value with the string "13q4":
db.collection('inventory').field('item, strcasecmp(quarter, "13q4") as comparisonResult').get()
Results of the:
{"_id":1,"item":"ABC1","comparisonResult":-1}
{"_id":2,"item":"ABC2","comparisonResult":0}
{"_id":3,"item":"XYZ1","comparisonResult":1}
Returns a substring of the specified length of the string starting at the specified position.
Deprecated, recommend using
substrBytes
orsubstrCP
The example collection inventory
contains the following documents:
{"_id":1,"item":"ABC1",quarter:"13Q1","description":"product 1"}
{"_id":2,"item":"ABC2",quarter:"13Q4","description":"product 2"}
{"_id":3,"item":"XYZ1",quarter:"14Q2","description":null}
Divide quarter
into yearSubstring
and QuarterSubstring
:
db.collection('inventory').field('item, substr(quarter, 0, 2) as yearSubstring, substr(quarter, 2, -1) as quarterSubtring')
Results of the:
{"_id":1,"item":"ABC1","yearSubstring":"13","quarterSubtring":"Q1"}
{"_id":2,"item":"ABC2","yearSubstring":"13","quarterSubtring":"Q4"}
{"_id":3,"item":"XYZ1","yearSubstring":"14","quarterSubtring":"Q2"}
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 example collection inventory
contains the following documents:
{"_id":1,"item":"ABC1",quarter:"13Q1","description":"product 1"}
{"_id":2,"item":"ABC2",quarter:"13Q4","description":"product 2"}
{"_id":3,"item":"XYZ1",quarter:"14Q2","description":null}
Separate quarter
(containing only single-byte US-ASCII characters) into yearSubstring
and QuarterSubstring
.
The QuarterSubstring
field represents the rest of the string from the specified byte index after yearSubstring
.
It is calculated by subtracting the byte index from the length of the string using strLenBytes
.
db.collection('inventory').field('item, substrBytes(quarter, 0, 2) as yearSubstring, substrBytes(quarter, 2, subtract(strLenBytes(quarter), 2)) as quarterSubtring').get()
Results of the:
{"_id":1,"item":"ABC1","yearSubstring":"13","quarterSubtring":"Q1"}
{"_id":2,"item":"ABC2","yearSubstring":"13","quarterSubtring":"Q4"}
{"_id":3,"item":"XYZ1","yearSubstring":"14","quarterSubtring":"Q2"}
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 example collection inventory
contains the following documents:
{"_id":1,"item":"ABC1",quarter:"13Q1","description":"product 1"}
{"_id":2,"item":"ABC2",quarter:"13Q4","description":"product 2"}
{"_id":3,"item":"XYZ1",quarter:"14Q2","description":null}
Split quarter
into yearSubstring
and QuarterSubstring
.
The QuarterSubstring
field represents the rest of the string from the specified byte index after yearSubstring
.
It is calculated by subtracting the byte index from the length of the string using strLenCP
.
db.collection('inventory').field('item, substrCP(quarter, 0, 2) as yearSubstring, substrCP(quarter, 2, subtract(strLenCP(quarter), 2))').get()
Results of the:
{"_id":1,"item":"ABC1","yearSubstring":"13","quarterSubtring":"Q1"}
{"_id":2,"item":"ABC2","yearSubstring":"13","quarterSubtring":"Q4"}
{"_id":3,"item":"XYZ1","yearSubstring":"14","quarterSubtring":"Q2"}
Convert a string to lowercase. Accepts a single argument expression.
The example collection inventory
contains the following documents:
{"_id":1,"item":"ABC1",quarter:"13Q1","description":"PRODUCT 1"}
{"_id":2,"item":"abc2",quarter:"13Q4","description":"Product 2"}
{"_id":3,"item":"xyz1",quarter:"14Q2","description":null}
Return lowercase item
and lowercase description
values:
db.collection('inventory').field('toLower(item) as item, toLower(description) as description').get()
Results of the:
{"_id":1,"item":"abc1","description":"product 1"}
{"_id":2,"item":"abc2","description":"product 2"}
{"_id":3,"item":"xyz1","description":""}
Convert a string to uppercase. Accepts a single argument expression.
The example collection inventory
contains the following documents:
{"_id":1,"item":"ABC1",quarter:"13Q1","description":"PRODUCT 1"}
{"_id":2,"item":"abc2",quarter:"13Q4","description":"Product 2"}
{"_id":3,"item":"xyz1",quarter:"14Q2","description":null}
Return uppercase item
and uppercase description
values:
db.collection('inventory').field('toUpper(item) as item, toUpper(description) as description').get()
Results of the:
{"_id":1,"item":"ABC1","description":"PRODUCT 1"}
{"_id":2,"item":"ABC2","description":"PRODUCT 2"}
{"_id":3,"item":"XYZ1","description":""}
Adds a value to the array, or does nothing if the value already exists in the array.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:00:00Z"}
{"_id":2,"item":"jkl","price":20,"quantity":1,"date":"2014-02-03T09:00:00Z"}
{"_id":3,"item":"xyz","price":5,"quantity":5,"date":"2014-02-03T09:05:00Z"}
{"_id":4,"item":"abc","price":10,"quantity":10,"date":"2014-02-15T08:00:00Z"}
{"_id":5,"item":"xyz","price":5,"quantity":10,"date":"2014-02-15T09:12:00Z"}
Compute the list of unique items sold by each group:
db.collection('sales').groupBy('dayOfYear(date) as day, year(date) as year').groupField('addToSet(item) as itemsSold').get()
Results of the:
{"day":46,"year":2014,"itemsSold":["xyz","abc"]}
{"day":34,"year":2014,"itemsSold":["xyz","jkl"]}
{"day":1,"year":2014,"itemsSold":["abc"]}
Returns the mean of the data corresponding to the specified expression.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:00:00Z"}
{"_id":2,"item":"jkl","price":20,"quantity":1,"date":"2014-02-03T09:00:00Z"}
{"_id":3,"item":"xyz","price":5,"quantity":5,"date":"2014-02-03T09:05:00Z"}
{"_id":4,"item":"abc","price":10,"quantity":10,"date":"2014-02-15T08:00:00Z"}
{"_id":5,"item":"xyz","price":5,"quantity":10,"date":"2014-02-15T09:12:00Z"}
Group documents by the item
field and calculate the average and average count for each group.
db.collection('sales').groupBy('item').groupField('avg(multiply(price, quantity)) as avgAmount, avg(quantity) as avgQuantity').get()
Results of the:
{"_id":"xyz","avgAmount":37.5,"avgQuantity":7.5}
{"_id":"jkl","avgAmount":20,"avgQuantity":1}
{"_id":"abc","avgAmount":60,"avgQuantity":6}
Returns the value corresponding to the first record of the specified field in a collection. This operation only makes sense if the set of collections is sorted ( sort ) by some definition.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:00:00Z"}
{"_id":2,"item":"jkl","price":20,"quantity":1,"date":"2014-02-03T09:00:00Z"}
{"_id":3,"item":"xyz","price":5,"quantity":5,"date":"2014-02-03T09:05:00Z"}
{"_id":4,"item":"abc","price":10,"quantity":10,"date":"2014-02-15T08:00:00Z"}
{"_id":5,"item":"xyz","price":5,"quantity":10,"date":"2014-02-15T09:05:00Z"}
{"_id":6,"item":"xyz","price":5,"quantity":5,"date":"2014-02-15T12:05:10Z"}
{"_id":7,"item":"xyz","price":5,"quantity":10,"date":"2014-02-15T14:12:12Z"}
Group by field item
and calculate the first sale date for each item:
const $ = db.command.aggregate
db.collection('sales').aggregate().sort({item: 1, date: 1}).group({
_id: "$item",
firstSalesDate: $.first('$date')
}).end()
Results of the:
{"_id":"xyz","firstSalesDate":"2014-02-03T09:05:00Z"}
{"_id":"jkl","firstSalesDate":"2014-02-03T09:00:00Z"}
{"_id":"abc","firstSalesDate":"2014-01-01T08:00:00Z"}
Returns the value corresponding to the last record of the specified field in a collection. This operation only makes sense if the set of collections is sorted ( sort ) by some definition.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","date":"2014-01-01T08:00:00Z","price":10,"quantity":2}
{"_id":2,"item":"jkl","date":"2014-02-03T09:00:00Z","price":20,"quantity":1}
{"_id":3,"item":"xyz","date":"2014-02-03T09:05:00Z","price":5,"quantity":5}
{"_id":4,"item":"abc","date":"2014-02-15T08:00:00Z","price":10,"quantity":10}
{"_id":5,"item":"xyz","date":"2014-02-15T09:05:00Z","price":5,"quantity":10}
{"_id":6,"item":"xyz","date":"2014-02-15T12:05:10Z","price":5,"quantity":5}
{"_id":7,"item":"xyz","date":"2014-02-15T14:12:12Z","price":5,"quantity":10}
Sort the documents by item
and date
, then group the now sorted documents by the item
field and calculate the last sale date for each item:
const $ = db.command.aggregate
db.collection('sales').aggregate().sort({item: 1, date: 1}).group({
_id: "$item",
lastSalesDate: $.last('$date')
}).end()
Results of the:
{"_id":"xyz","lastSalesDate":"2014-02-15T14:12:12Z"}
{"_id":"jkl","lastSalesDate":"2014-02-03T09:00:00Z"}
{"_id":"abc","lastSalesDate":"2014-02-15T08:00:00Z"}
Returns the maximum value of a set of numbers.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:00:00Z"}
{"_id":2,"item":"jkl","price":20,"quantity":1,"date":"2014-02-03T09:00:00Z"}
{"_id":3,"item":"xyz","price":5,"quantity":5,"date":"2014-02-03T09:05:00Z"}
{"_id":4,"item":"abc","price":10,"quantity":10,"date":"2014-02-15T08:00:00Z"}
{"_id":5,"item":"xyz","price":5,"quantity":10,"date":"2014-02-15T09:05:00Z"}
Group by field item
, and calculate the maximum total and maximum number of documents for each group.
db.collection('sales').groupBy('item').groupField('max(multiply(price, quantity)) as maxTotalAmount, max(quantity) as maxQuantity').get()
Results of the:
{"_id":"xyz","maxTotalAmount":50,"maxQuantity":10}
{"_id":"jkl","maxTotalAmount":20,"maxQuantity":1}
{"_id":"abc","maxTotalAmount":100,"maxQuantity":10}
Returns the minimum value of a set of numbers.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:00:00Z"}
{"_id":2,"item":"jkl","price":20,"quantity":1,"date":"2014-02-03T09:00:00Z"}
{"_id":3,"item":"xyz","price":5,"quantity":5,"date":"2014-02-03T09:05:00Z"}
{"_id":4,"item":"abc","price":10,"quantity":10,"date":"2014-02-15T08:00:00Z"}
{"_id":5,"item":"xyz","price":5,"quantity":10,"date":"2014-02-15T09:05:00Z"}
Groups documents by the item
field and computes the minimum and minimum counts for each grouping.
db.collection('sales').groupBy('item').groupField('min(quantity) as minQuantity').get()
Results of the:
{"item":"xyz","minQuantity":5}
{"item":"jkl","minQuantity":1}
{"item":"abc","minQuantity":2}
Returns an array composed of the column specified by the expression and the corresponding value in a group.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:00:00Z"}
{"_id":2,"item":"jkl","price":20,"quantity":1,"date":"2014-02-03T09:00:00Z"}
{"_id":3,"item":"xyz","price":5,"quantity":5,"date":"2014-02-03T09:05:00Z"}
{"_id":4,"item":"abc","price":10,"quantity":10,"date":"2014-02-15T08:00:00Z"}
{"_id":5,"item":"xyz","price":5,"quantity":10,"date":"2014-02-15T09:05:00Z"}
{"_id":6,"item":"xyz","price":5,"quantity":5,"date":"2014-02-15T12:05:10Z"}
{"_id":7,"item":"xyz","price":5,"quantity":10,"date":"2014-02-15T14:12:12Z"}
Group by the date and year of the date
field and calculate the BOM and sales quantity for each group:
db.collection('sales').groupBy('dayOfYear(date) as day, year(date) as year').groupField('push({item: item, quantity: quantity}) as itemsSold').get()
Results of the:
{"day":46,"year":2014,"itemsSold":[{"item":"abc","quantity":10},{"item":"xyz","quantity":10},{"item":"xyz","quantity":5},{"item":"xyz","quantity":10}]}
{"day":34,"year":2014,"itemsSold":[{"item":"jkl","quantity":1},{"item":"xyz","quantity":5}]}
{"day":1,"year":2014,"itemsSold":[{"item":"abc","quantity":2}]}
Returns the standard deviation of the corresponding values for a set of fields.
The example collection users
contains the following documents:
{"_id":1,"name":"dave123","quiz":1,"score":85}
{"_id":2,"name":"dave2","quiz":1,"score":90}
{"_id":3,"name":"ahn","quiz":1,"score":71}
{"_id":4,"name":"li","quiz":2,"score":96}
{"_id":5,"name":"annT","quiz":2,"score":77}
{"_id":6,"name":"ty","quiz":2,"score":82}
Compute the standard deviation for each test:
db.collection('users').groupBy('quiz').groupField('stdDevPop(score) as stdDev').get()
Results of the:
{"quiz":2,"stdDev":8.04155872120988}
{"quiz":1,"stdDev":8.04155872120988}
Computes the sample standard deviation of the input values.
The example collection users
contains the following documents:
{_id:0,username:"user0",age:20}
{_id:1,username:"user1",age:42}
{_id:2,username:"user2",age:28}
...
To calculate the standard deviation of a sample of users, first use the sample
pipeline to sample 100 users, then use stdDevSamp
to calculate the standard deviation of the sample users.
db.collection('users').aggregate()
.sample({size: 100})
.group({
_id: null,
ageStdDev:{$stdDevSamp:"$age"}
})
.end()
The operation returns the following results:
{"_id":null,"ageStdDev":7.811258386185771}
Returns the sum of all values for a set of fields.
The example collection sales
contains the following documents:
{"_id":1,"item":"abc","price":10,"quantity":2,"date":"2014-01-01T08:00:00Z"}
{"_id":2,"item":"jkl","price":20,"quantity":1,"date":"2014-02-03T09:00:00Z"}
{"_id":3,"item":"xyz","price":5,"quantity":5,"date":"2014-02-03T09:05:00Z"}
{"_id":4,"item":"abc","price":10,"quantity":10,"date":"2014-02-15T08:00:00Z"}
{"_id":5,"item":"xyz","price":5,"quantity":10,"date":"2014-02-15T09:05:00Z"}
Group documents by the date and year of the date
field and calculate the total and count of each group of documents.
db.collection('sales').groupBy('dayOfYear(date) as day, year(date) as year').groupField('sum(multiply(price, quantity)) as totalAmount, sum(1) as count').get()
Results of the:
{"_id":{"day":46,"year":2014},"totalAmount":150,"count":2}
{"_id":{"day":34,"year":2014},"totalAmount":45,"count":2}
{"_id":{"day":1,"year":2014},"totalAmount":20,"count":1}
Merge multiple documents into one.
Note: If the documents to be merged contain the same field names, the fields in the resulting document will override the values in the last merged document.
The example collection sales
contains the following documents:
{_id:1,year:2017,item:"A",quantity:{"2017Q1":500,"2017Q2":500}}
{_id:2,year:2016,item:"A",quantity:{"2016Q1":400,"2016Q2":300,"2016Q3":0,"2016Q4":0}}
{_id:3,year:2017,item:"B",quantity:{"2017Q1":300}}
{_id:4,year:2016,item:"B",quantity:{"2016Q3":100,"2016Q4":250}}
Group by item
, mergeObjects
only accepts single object operations.
db.collection('sales').groupBy('item').groupField('mergeObjects(quantity) as mergedSales').get()
Results of the:
{"_id":"B","mergedSales":{"2017Q1":300,"2016Q3":100,"2016Q4":250}}
{"_id":"A","mergedSales":{"2017Q1":500,"2017Q2":500,"2016Q1":400,"2016Q2":300,"2016Q3":0,"2016Q4":0}}
// Product table goods
{
"name": {
"bsonType": "string",
"description": "商品名称"
},
"category": {
"bsonType": "string",
"description": "商品分类"
},
"price": {
"bsonType": "number",
"description": "商品价格"
},
"stock": {
"bsonType": "number",
"description": "库存"
}
}
// order table orders
{
"goodsId": {
"bsonType": "string",
"description": "商品ID",
"foreignKey": "goods._id"
},
"buyNum": {
"bsonType": "number",
"description": "购买数量"
},
"userId": {
"bsonType": "string",
"description": "用户ID",
"foreignKey": "users._id"
},
"createDate": {
"bsonType": "timestamp",
"description": "购买时间"
}
}
// user table users
{
"name": {
"bsonType": "string",
"description": "用户名"
}
}
// goods
[
{
"_id": "6363666826e8170001b62baa",
"category": "手机",
"name": "iPhone 14 512G",
"price": 8488,
"stock": 100
},
{
"_id": "6363666f3aeb530001925bb6",
"category": "手机",
"name": "iPhone 13 Pro Max 128G",
"price": 9688,
"stock": 20
},
{
"_id": "63636678a899370001a22627",
"category": "手机",
"name": "华为 Meta P50",
"price": 7699,
"stock": 50
},
{
"_id": "63636681ff2a54000133afd7",
"category": "手机",
"name": "小米 12 Ultra",
"price": 4599,
"stock": 200
},
{
"_id": "6363668cd69bc10001765c5f",
"category": "电脑",
"name": "红米 Redmibook 15寸 256G",
"price": 3999,
"stock": 100
},
{
"_id": "6363669353a7f30001b46c84",
"category": "电脑",
"name": "Macbook Pro 512G",
"price": 10499,
"stock": 100
},
{
"_id": "6363669a26e8170001b63213",
"category": "电脑",
"name": "Macbook Air 128G",
"price": 7699,
"stock": 100
}
]
// orders
[
{
"_id": "6364b2e8b653d6000163c4f3",
"buyNum": 2,
"createDate": 1664769600000,
"goodsId": "6363666826e8170001b62baa",
"userId": "6364cc82b653d6000167f848"
},
{
"_id": "6364b2e8b653d6000163c4f4",
"buyNum": 1,
"createDate": 1664773200000,
"goodsId": "6363668cd69bc10001765c5f",
"userId": "6364cc82b653d6000167f848"
},
{
"_id": "6364b2e8b653d6000163c4f5",
"buyNum": 2,
"createDate": 1664758800000,
"goodsId": "6363669353a7f30001b46c84",
"userId": "6364cc82b653d6000167f849"
},
{
"_id": "6364b2e8b653d6000163c4f6",
"buyNum": 1,
"createDate": 1664769600000,
"goodsId": "63636678a899370001a22627",
"userId": "6364cc82b653d6000167f848"
},
{
"_id": "6364b2e8b653d6000163c4f7",
"buyNum": 3,
"createDate": 1664769600000,
"goodsId": "63636681ff2a54000133afd7",
"userId": "6364cc82b653d6000167f848"
},
{
"_id": "6364b2e8b653d6000163c4f8",
"buyNum": 1,
"createDate": 1664769600000,
"goodsId": "6363668cd69bc10001765c5f",
"userId": "6364cc82b653d6000167f849"
},
{
"_id": "6364b2e8b653d6000163c4f9",
"buyNum": 3,
"createDate": 1664683200000,
"goodsId": "6363669353a7f30001b46c84",
"userId": "6364cc82b653d6000167f848"
},
{
"_id": "6364b2e8b653d6000163c4fa",
"buyNum": 2,
"createDate": 1664679600000,
"goodsId": "6363666f3aeb530001925bb6",
"userId": "6364cc82b653d6000167f848"
},
{
"_id": "6364b2e8b653d6000163c4fb",
"buyNum": 1,
"createDate": 1664697600000,
"goodsId": "63636678a899370001a22627",
"userId": "6364cc82b653d6000167f849"
}
]
// users
[
{
"_id": "6364cc82b653d6000167f847",
"name": "张三"
},
{
"_id": "6364cc82b653d6000167f848",
"name": "李四"
},
{
"_id": "6364cc82b653d6000167f849",
"name": "王五"
}
]
In this example, group and groupField are used, corresponding to the $group and $project stages of the Aggregate stage.
Use groupBy to group the product classification category field, use the sum expression in the groupField to add 1 to the product quantity (goodsNumber), and also use the sum expression to calculate the total inventory of the stock (stock).
// JQL
db.collection('goods').groupBy('category').groupField('sum(1) as goodsNumber, sum(stock) as stock').get()
Compared with the above JQL method, the following Aggregate is slightly more complicated, but the general logic is the same.
In the first stage of Aggregate, group according to product classification, and add the goodsNumber and stock fields in the group. The calculation is the same as the above calculation method, and the result is passed to the next stage.
In the second stage, use the $project pipeline to trim the fields, remove the _id field, add the category field, and keep the goodsNumber and stock fields. If you use the JQL method, you don’t need to manually trim the fields.
// JQL Aggregate
const $ = db.command.aggregate
db.collection('goods').aggregate().group({
_id: "$category",
goodsNumber: $.sum(1),
stock: $.sum('$stock')
}).project({
_id: false,
category: "$_id",
goodsNumber: 1,
stock: 1
}).end()
Results of the
[
{
"category": "手机",
"goodsNumber": 4,
"stock": 370
},
{
"category": "电脑",
"goodsNumber": 3,
"stock": 300
}
]
Use where to preliminarily screen products whose value is greater than 5000, use groupBy to group the filtered products according to category, and use sum expression in groupField to add 1 to the number of products (goodsNumber).
// JQL
db.collection('goods').where('price > 5000').groupBy('category').groupField('sum(1) as goodsNumber').get()
In stage 1, use the $match pipeline to filter by item amount, and pass the result to the next stage.
In the second stage, the $group pipeline is used to group by category, and the goodsNumber field is added to the group, and the sum expression is used to add 1 to the quantity.
In the third stage, use the $project pipeline to trim the fields, remove the _id field, add the category field value to the product category passed in the previous stage, and keep the goodsNumber field.
// JQL Aggregate
db.collection('goods').aggregate().match({
price: $.gt(5000)
}).group({
_id: '$category',
goodsNumber: $.sum(1)
}).project({
_id: 0,
category: "$_id",
goodsNumber: 1
}).end()
Results of the
[
{
"category": "手机",
"goodsNumber": 3
},
{
"category": "电脑",
"goodsNumber": 2
}
]
The first stage uses the $sort pipeline to sort the goods table by price in reverse, passing the result to the next stage.
In the second stage, the $group pipeline is used to group by category. Since the price has been arranged in reverse order in the first stage, the maxGoodsName and maxGoodsPrice fields are added to the group using the $first expression to select the first document and the one with the largest price Indicates the item with the highest price. Conversely, the minGoodsName, minGoodsPrice fields use the $last expression to select the last document, which represents the item with the lowest price.
In the third stage, use the $project pipeline to trim the data, remove the _id field, add the category field value to the product category passed in the previous stage, maxGoods is the product with the highest price, and minGoods is the product with the lowest price.
// JQL Aggregate
db.collection('goods').aggregate().sort({
price: -1
}).group({
_id: "$category",
maxGoodsName: {$first: "$name"},
maxGoodsPrice: {$first: "$price"},
minGoodsName: {$last: "$name"},
minGoodsPrice: {$last: "$price"}
}).project({
_id: 0,
category: "$_id",
maxGoods: {
name: "$maxGoodsName",
price: "$maxGoodsPrice"
},
minGoods: {
name: "$minGoodsName",
price: "$minGoodsPrice"
}
}).end()
Results of the
[
{
"category": "电脑",
"maxGoods": {
"name": "Macbook Pro 512G",
"price": 10499
},
"minGoods": {
"name": "红米 Redmibook 15寸 256G",
"price": 3999
}
},
{
"category": "手机",
"maxGoods": {
"name": "iPhone 13 Pro Max 128G",
"price": 9688
},
"minGoods": {
"name": "小米 12 Ultra",
"price": 4599
}
}
]
The first stage uses the $match pipeline to filter orders for a certain day and pass the results to the next stage
The second stage uses the $group pipeline to calculate the average customer unit price using the avg expression
// JQL Aggregate
const $ = db.command.aggregate
db.collection('orders').aggregate().match({
createDate: $.and($.gt(new Date('2022-10-03T00:00:00.000Z')), $.lt(new Date('2022-10-04T00:00:00.000Z')))
}).group({
_id: null,
avgPrice: $.avg('$price')
}).end()
Results of the
[
{
"_id": null,
"avgPrice": 11364
}
]
// JQL
const orders = db.collection('orders').getTemp()
db.collection(orders, 'goods')
.foreignKey('orders.goodsId')
.field('arrayElemAt(goodsId, 0) as goods, buyNum')
.groupBy('goods._id as goodsId')
.groupField('sum(buyNum) as count, first(goods.name) as name, first(goods.category) as category')
.orderBy('count desc')
.get()
// JQL Aggregate
db.collection('orders').aggregate().lookup({
from: "goods",
let: {
goodsId: "$goodsId"
},
pipeline: $.pipeline()
.match(db.command.expr(
db.command.eq(['$_id', '$$goodsId'])
)).done(),
as: "goods"
}).unwind('$goods').group({
_id: "$goods._id",
count: $.sum("$buyNum"),
name: $.first("$goods.name"),
category: $.first("$goods.category")
}).sort({
count: -1
}).end()
Results of the
[
{
"_id": "6363669353a7f30001b46c84",
"category": "电脑",
"count": 5,
"name": "Macbook Pro 512G"
},
{
"_id": "63636681ff2a54000133afd7",
"category": "手机",
"count": 3,
"name": "小米 12 Ultra"
},
{
"_id": "63636678a899370001a22627",
"category": "手机",
"count": 2,
"name": "华为 Meta P50"
},
{
"_id": "6363668cd69bc10001765c5f",
"category": "电脑",
"count": 2,
"name": "红米 Redmibook 15寸 256G"
},
{
"_id": "6363666826e8170001b62baa",
"category": "手机",
"count": 2,
"name": "iPhone 14 512G"
},
{
"_id": "6363666f3aeb530001925bb6",
"category": "手机",
"count": 2,
"name": "iPhone 13 Pro Max 128G"
}
]
// JQL
const orders = db.collection('orders').getTemp()
db.collection(orders, 'goods', 'users')
.where('goodsId.category=="手机"')
.field('arrayElemAt(goodsId, 0) as goods, arrayElemAt(userId, 0) as user')
.groupBy('goods.category as category')
.groupField('addToSet(user) as users')
.get()
// Aggregate
db.collection('orders').aggregate().lookup({
from: "goods",
let: {
goodsId: "$goodsId"
},
pipeline: $.pipeline().match(db.command.expr(
db.command.eq(['$_id', '$$goodsId'])
)).done(),
as: "goods"
}).match({
'goods.category': "手机"
}).unwind("$goods").lookup({
from: "users",
let: {
userId: "$userId"
},
pipeline: $.pipeline().match(db.command.expr(
db.command.eq(['$_id', '$$userId'])
)).done(),
as: "user"
}).unwind('$user').group({
_id: "$goods.category",
users: {$addToSet: "$user"}
}).end()
Results of the
[
{
"category": "手机",
"users": [
{
"_id": "6364cc82b653d6000167f849",
"name": "王五"
},
{
"_id": "6364cc82b653d6000167f848",
"name": "李四"
}
]
}
]