SDK数据库 Command·聚合操作符·数组操作符
AggregateCommand.arrayElemAt(value: Expression[]): Object
支持端:小程序 2.7.4, 云函数 0.8.1, Web
聚合操作符。返回在指定数组下标的元素。
参数
value: Expression[]
[<array>, <index>]
返回值
Object
API 说明
语法如下:
db.command.aggregate.arrayElemAt([<array>, <index>])
<array> 可以是任意解析为数字的表达式。
<index> 可以是任意解析为整形的表达式。如果是正数,arrayElemAt 返回在 index 位置的元素,如果是负数,arrayElemAt 返回从数组尾部算起的 index 位置的元素。
示例代码
假设集合 exams 有如下记录:
{ "_id": 1, "scores": [80, 60, 65, 90] }
{ "_id": 2, "scores": [78] }
{ "_id": 3, "scores": [95, 88, 92] }
求各个第一次考试的分数和和最后一次的分数:
const $ = db.command.aggregate
db.collection('exams').aggregate()
.project({
first: $.arrayElemAt(['$scores', 0]),
last: $.arrayElemAt(['$scores', -1]),
})
.end()
返回结果如下:
{ "_id": 1, "first": 80, "last": 90 }
{ "_id": 2, "first": 78, "last": 78 }
{ "_id": 3, "first": 95, "last": 92 }
AggregateCommand.arrayToObject(value: any): Object
支持端:小程序 2.7.4, 云函数 0.8.1, Web
聚合操作符。将一个数组转换为对象。
参数
value: any
返回值
Object
API 说明
语法可以取两种:
第一种:传入一个二维数组,第二维的数组长度必须为 2,其第一个值为字段名,第二个值为字段值
db.command.aggregate.arrayToObject([
[<key1>, <value1>],
[<key2>, <value2>],
...
])
第二种:传入一个对象数组,各个对象必须包含字段 k 和 v,分别指定字段名和字段值
db.command.aggregate.arrayToObject([
{ "k": <key1>, "v": <value1> },
{ "k": <key2>, "v": <value2> },
...
])
传入 arrayToObject 的参数只要可以解析为上述两种表示法之一即可。
示例代码
假设集合 shops 有如下记录:
{ "_id": 1, "sales": [ ["max", 100], ["min", 50] ] }
{ "_id": 2, "sales": [ ["max", 70], ["min", 60] ] }
{ "_id": 3, "sales": [ { "k": "max", "v": 50 }, { "k": "min", "v": 30 } ] }
求各个第一次考试的分数和和最后一次的分数:
const $ = db.command.aggregate
db.collection('shops').aggregate()
.project({
sales: $.arrayToObject('$sales'),
})
.end()
返回结果如下:
{ "_id": 1, "sales": { "max": 100, "min": 50 } }
{ "_id": 2, "sales": { "max": 70, "min": 60 } }
{ "_id": 3, "sales": { "max": 50, "min": 30 } }
AggregateCommand.concatArrays(value: Expression[]): Object
支持端:小程序 2.7.4, 云函数 0.8.1, Web
聚合操作符。将多个数组拼接成一个数组。
参数
value: Expression[]
[ <array1>, <array2>, ... ]
返回值
Object
API 说明
语法如下:
db.command.aggregate.arrayToObject([ <array1>, <array2>, ... ])
参数可以是任意解析为数组的表达式。
示例代码
假设集合 items 有如下记录:
{ "_id": 1, "fruits": [ "apple" ], "vegetables": [ "carrot" ] }
{ "_id": 2, "fruits": [ "orange", "lemon" ], "vegetables": [ "cabbage" ] }
{ "_id": 3, "fruits": [ "strawberry" ], "vegetables": [ "spinach" ] }
const $ = db.command.aggregate
db.collection('items').aggregate()
.project({
list: $.concatArrays(['$fruits', '$vegetables']),
})
.end()
返回结果如下:
{ "_id": 1, "list": [ "apple", "carrot" ] }
{ "_id": 2, "list": [ "orange", "lemon", "cabbage" ] }
{ "_id": 3, "list": [ "strawberry", "spinach" ] }
AggregateCommand.filter(value: any): Object
支持端:小程序 2.7.4, 云函数 0.8.1, Web
聚合操作符。根据给定条件返回满足条件的数组的子集。
参数
value: any
返回值
Object
API 说明
语法如下:
db.command.aggregate.filter({
input: <array>,
as: <string>,
cond: <expression>
})
字段 | 说明 |
---|---|
input | 一个可以解析为数组的表达式 |
as | 可选,用于表示数组各个元素的变量,默认为 this |
cond | 一个可以解析为布尔值的表达式,用于判断各个元素是否满足条件,各个元素的名字由 as 参数决定(参数名需加 $$ 前缀,如 $$this ) |
参数可以是任意解析为数组的表达式。
示例代码
假设集合 fruits 有如下记录:
{
"_id": 1,
"stock": [
{ "name": "apple", "price": 10 },
{ "name": "orange", "price": 20 }
],
}
{
"_id": 2,
"stock": [
{ "name": "lemon", "price": 15 },
],
}
const _ = db.command
const $ = db.command.aggregate
db.collection('fruits').aggregate()
.project({
stock: $.filter({
input: '$stock',
as: 'item',
cond: $.gte(['$$item.price', 15])
})
})
.end()
返回结果如下:
{ "_id": 1, "stock": [ { "name": "orange", "price": 20} ] }
{ "_id": 2, "stock": [ { "name": "lemon", "price": 15 } ] }
AggregateCommand.in(value: Expression[]): Object
支持端:小程序 2.7.4, 云函数 0.8.1, Web
聚合操作符。给定一个值和一个数组,如果值在数组中则返回 true,否则返回 false。
参数
value: Expression[]
[<value>, <array>]
返回值
Object
API 说明
语法如下:
db.command.aggregate.in([<value>, <array>])
<value> 可以是任意表达式。
<array> 可以是任意解析为数组的表达式。
示例代码
假设集合 shops 有如下记录:
{ "_id": 1, "topsellers": ["bread", "ice cream", "butter"] }
{ "_id": 2, "topsellers": ["ice cream", "cheese", "yagurt"] }
{ "_id": 3, "topsellers": ["croissant", "cucumber", "coconut"] }
标记销量最高的商品包含 ice cream 的记录。
const $ = db.command.aggregate
db.collection('price').aggregate()
.project({
included: $.in(['ice cream', '$topsellers'])
})
.end()
返回结果如下:
{ "_id": 1, "included": true }
{ "_id": 2, "included": true }
{ "_id": 3, "included": false }
AggregateCommand.indexOfArray(value: Expression[]): Object
支持端:小程序 2.7.4, 云函数 0.8.1, Web
聚合操作符。在数组中找出等于给定值的第一个元素的下标,如果找不到则返回 -1。
参数
value: Expression[]
[ <array expression>, <search expression>, <start>, <end> ]
返回值
Object
API 说明
语法如下:
db.command.aggregate.indexOfArray([ <array expression>, <search expression>, <start>, <end> ])
字段 | 类型 | 说明 |
---|---|---|
<array>
|
string | 一个可以解析为数组的表达式,如果解析为 null,则 indexOfArray 返回 null |
<search>
|
string | 对数据各个元素应用的条件匹配表达式 |
<start>
|
integer | 可选,用于指定搜索的开始下标,必须是非负整数 |
<end>
|
integer | 可选,用于指定搜索的结束下标,必须是非负整数,指定了 <end> 时也应指定 <start> ,否则 <end> 默认当做 <start>
|
参数可以是任意解析为数组的表达式。
示例代码
假设集合 stats 有如下记录:
{
"_id": 1,
"sales": [ 1, 6, 2, 2, 5 ]
}
{
"_id": 2,
"sales": [ 4, 2, 1, 5, 2 ]
}
{
"_id": 3,
"sales": [ 2, 5, 3, 3, 1 ]
}
const $ = db.command.aggregate
db.collection('stats').aggregate()
.project({
index: $.indexOfArray(['$sales', 2, 2])
})
.end()
返回结果如下:
{ "_id": 1, "index": 2 }
{ "_id": 2, "index": 4 }
{ "_id": 3, "index": -1 }
AggregateCommand.isArray(value: Expression): Object
支持端:小程序 2.7.4, 云函数 0.8.1, Web
聚合操作符。判断给定表达式是否是数组,返回布尔值。
参数
value: Expression
表达式
返回值
Object
API 说明
语法如下:
db.command.aggregate.isArray(<expression>)
参数可以是任意表达式。
示例代码
假设集合 stats 有如下记录:
{
"_id": 1,
"base": 10,
"sales": [ 1, 6, 2, 2, 5 ]
}
{
"_id": 2,
"base": 1,
"sales": 100
}
计算总销量,如果 sales 是数字,则求 sales * base,如果 sales 是数组,则求数组元素之和与 base 的乘积。
const $ = db.command.aggregate
db.collection('stats').aggregate()
.project({
sum: $.cond({
if: $.isArray('$sales'),
then: $.multiply([$.sum(['$sales']), '$base']),
else: $.multiply(['$sales', '$base']),
})
})
.end()
返回结果如下:
{ "_id": 1, "index": 160 }
{ "_id": 2, "index": 100 }
AggregateCommand.map(value: any): Object
支持端:小程序 2.7.4, 云函数 0.8.1, Web
聚合操作符。类似 JavaScript Array 上的 map 方法,将给定数组的每个元素按给定转换方法转换后得出新的数组。
参数
value: any
返回值
Object
API 说明
语法如下:
db.command.aggregate.map({
input: <expression>,
as: <string>,
in: <expression>
})
字段 | 说明 |
---|---|
input | 一个可以解析为数组的表达式 |
as | 可选,用于表示数组各个元素的变量,默认为 this |
in | 一个可以应用在给定数组的各个元素上的表达式,各个元素的名字由 as 参数决定(参数名需加 $$ 前缀,如 $$this ) |
示例代码
假设集合 stats 有如下记录:
{
"_id": 1,
"sales": [ 1.32, 6.93, 2.48, 2.82, 5.74 ]
}
{
"_id": 2,
"sales": [ 2.97, 7.13, 1.58, 6.37, 3.69 ]
}
将各个数字截断为整形,然后求和
const $ = db.command.aggregate
db.collection('stats').aggregate()
.project({
truncated: $.map({
input: '$sales',
as: 'num',
in: $.trunc('$$num'),
})
})
.project({
total: $.sum('$truncated')
})
.end()
返回结果如下:
{ "_id": 1, "index": 16 }
{ "_id": 2, "index": 19 }
AggregateCommand.objectToArray(value: Expression<object>): Object
支持端:小程序 2.7.4, 云函数 0.8.1, Web
聚合操作符。将一个对象转换为数组。方法把对象的每个键值对都变成输出数组的一个元素,元素形如 { k: <key>, v: <value> }。
参数
value: Expression<object>
返回值
Object
API 说明
语法如下:
db.command.aggregate.objectToArray(<object>)
示例代码
假设集合 items 有如下记录:
{ "_id": 1, "attributes": { "color": "red", "price": 150 } }
{ "_id": 2, "attributes": { "color": "blue", "price": 50 } }
{ "_id": 3, "attributes": { "color": "yellow", "price": 10 } }
const $ = db.command.aggregate
db.collection('items').aggregate()
.project({
array: $.objectToArray('$attributes')
})
.end()
返回结果如下:
{ "_id": 1, "array": [{ "k": "color", "v": "red" }, { "k": "price", "v": 150 }] }
{ "_id": 2, "array": [{ "k": "color", "v": "blue" }, { "k": "price", "v": 50 }] }
{ "_id": 3, "array": [{ "k": "color", "v": "yellow" }, { "k": "price", "v": 10 }] }
AggregateCommand.range(value: Expression[]): Object
支持端:小程序 2.7.4, 云函数 0.8.1, Web
聚合操作符。返回一组生成的序列数字。给定开始值、结束值、非零的步长,range 会返回从开始值开始逐步增长、步长为给定步长、但不包括结束值的序列。
参数
value: Expression[]
[<start>, <end>, <non-zero step>]
返回值
Object
API 说明
语法如下:
db.command.aggregate.range([<start>, <end>, <non-zero step>])
字段 | 说明 |
---|---|
start | 开始值,一个可以解析为整形的表达式 |
end | 结束值,一个可以解析为整形的表达式 |
non-zero step | 可选,步长,一个可以解析为非零整形的表达式,默认为 1 |
示例代码
假设集合 stats 有如下记录:
{ "_id": 1, "max": 52 }
{ "_id": 2, "max": 38 }
const $ = db.command.aggregate
db.collection('stats').aggregate()
.project({
points: $.range([0, '$max', 10])
})
.end()
返回结果如下:
{ "_id": 1, "points": [0, 10, 20, 30, 40, 50] }
{ "_id": 2, "points": [0, 10, 20] }
AggregateCommand.reduce(value: any): Object
支持端:小程序 2.7.4, 云函数 0.8.1, Web
聚合操作符。类似 JavaScript 的 reduce 方法,应用一个表达式于数组各个元素然后归一成一个元素。
参数
value: any
返回值
Object
API 说明
语法如下:
db.command.aggregate.reduce({
input: <array>
initialValue: <expression>,
in: <expression>
})
字段 | 说明 |
---|---|
input | 输入数组,可以是任意解析为数组的表达式 |
initialValue | 初始值 |
in | 用来作用于每个元素的表达式,在 in 中有两个可用变量,value 是表示累计值的变量,this 是表示当前数组元素的变量 |
示例代码
简易字符串拼接
假设集合 player 有如下记录:
{ "_id": 1, "fullname": [ "Stephen", "Curry" ] }
{ "_id": 2, "fullname": [ "Klay", "Thompsom" ] }
获取各个球员的全名,并加 Player: 前缀:
const $ = db.command.aggregate
db.collection('player').aggregate()
.project({
info: $.reduce({
input: '$fullname',
initialValue: 'Player:',
in: $.concat(['$$value', ' ', '$$this']),
})
})
.end()
返回结果如下:
{ "_id": 1, "info": "Player: Stephen Curry" }
{ "_id": 2, "info": "Player: Klay Thompson" }
获取各个球员的全名,不加前缀:
const $ = db.command.aggregate
db.collection('player').aggregate()
.project({
name: $.reduce({
input: '$fullname',
initialValue: '',
in: $.concat([
'$$value',
$.cond({
if: $.eq(['$$value', '']),
then: '',
else: ' ',
}),
'$$this',
]),
})
})
.end()
返回结果如下:
{ "_id": 1, "name": "Stephen Curry" }
{ "_id": 2, "name": "Klay Thompson" }
AggregateCommand.reverseArray(value: Expression<any[]>): Object
支持端:小程序 2.7.4, 云函数 0.8.1, Web
聚合操作符。返回给定数组的倒序形式。
参数
value: Expression<any[]>
返回值
Object
API 说明
语法如下:
db.command.aggregate.reverseArray(<array>)
参数可以是任意解析为数组表达式。
示例代码
假设集合 stats 有如下记录:
{
"_id": 1,
"sales": [ 1, 2, 3, 4, 5 ]
}
取 sales 倒序:
const $ = db.command.aggregate
db.collection('stats').aggregate()
.project({
reversed: $.reverseArray('$sales'),
})
.end()
返回结果如下:
{ "_id": 1, "reversed": [5, 4, 3, 2, 1] }
AggregateCommand.size(value: Expression<any[]>): Object
支持端:小程序 2.7.4, 云函数 0.8.1, Web
聚合操作符。返回数组长度。
参数
value: Expression<any[]>
返回值
Object
API 说明
语法如下:
db.command.aggregate.size(<array>)
<array> 可以是任意解析为数组的表达式。
示例代码
假设集合 shops 有如下记录:
{ "_id": 1, "staff": [ "John", "Middleton", "George" ] }
{ "_id": 2, "staff": [ "Steph", "Jack" ] }
计算各个商店的雇员数量:
const $ = db.command.aggregate
db.collection('staff').aggregate()
.project({
totalStaff: $.size('$staff')
})
.end()
返回结果如下:
{ "_id": 1, "totalStaff": 3 }
{ "_id": 2, "totalStaff": 2 }
AggregateCommand.slice(value: Expression[]): Object
支持端:小程序 2.7.4, 云函数 0.8.1, Web
聚合操作符。类似 JavaScritp 的 slice 方法。返回给定数组的指定子集。
参数
value: Expression[]
[<array>, <n>]
返回值
Object
API 说明
语法有两种:
返回从开头或结尾开始的 n 个元素:
db.command.aggregate.slice([<array>, <n>])
返回从指定位置算作数组开头、再向后或向前的 n 个元素:
db.command.aggregate.slice([<array>, <position>, <n>])
<array> 可以是任意解析为数组的表达式。
<position> 可以是任意解析为整形的表达式。如果是正数,则将数组的第 <position> 个元素作为数组开始;如果 <position> 比数组长度更长,slice 返回空数组。如果是负数,则将数组倒数第 <position> 个元素作为数组开始;如果 <position> 的绝对值大于数组长度,则开始位置即为数组开始位置。
<n> 可以是任意解析为整形的表达式。如果 <position> 有提供,则 <n> 必须为正整数。如果是正数,slice 返回前 n 个元素。如果是负数,slice 返回后 n 个元素。
示例代码
假设集合 people 有如下记录:
{ "_id": 1, "hobbies": [ "basketball", "football", "tennis", "badminton" ] }
{ "_id": 2, "hobbies": [ "golf", "handball" ] }
{ "_id": 3, "hobbies": [ "table tennis", "swimming", "rowing" ] }
统一返回前两个爱好:
const $ = db.command.aggregate
db.collection('fruits').aggregate()
.project({
hobbies: $.slice(['$hobbies', 2]),
})
.end()
返回结果如下:
{ "_id": 1, "hobbies": [ "basketball", "football" ] }
{ "_id": 2, "hobbies": [ "golf", "handball" ] }
{ "_id": 3, "hobbies": [ "table tennis", "swimming" ] }
AggregateCommand.zip(value: any): Object
支持端:小程序 2.7.4, 云函数 0.8.1, Web
聚合操作符。把二维数组的第二维数组中的相同序号的元素分别拼装成一个新的数组进而组装成一个新的二维数组。如可将 [ [ 1, 2, 3 ], [ "a", "b", "c" ] ] 转换成 [ [ 1, "a" ], [ 2, "b" ], [ 3, "c" ] ]。
参数
value: any
返回值
Object
API 说明
语法如下:
db.command.aggregate.zip({
inputs: [<array1>, <array2>, ...],
useLongestLength: <boolean>,
defaults: <array>
})
inputs 是一个二维数组(inputs 不可以是字段引用),其中每个元素的表达式(这个可以是字段引用)都可以解析为数组。如果其中任意一个表达式返回 null,<inputs> 也返回 null。如果其中任意一个表达式不是指向一个合法的字段 / 解析为数组 / 解析为 null,则返回错误。
useLongestLength 决定输出数组的长度是否采用输入数组中的最长数组的长度。默认为 false,即输入数组中的最短的数组的长度即是输出数组的各个元素的长度。
defaults 是一个数组,用于指定在输入数组长度不一的情况下时采用的数组各元素默认值。指定这个字段则必须指定 useLongestLength,否则返回错误。如果 useLongestLength 是 true 但是 defaults 是空或没有指定,则 zip 用 null 做数组元素的缺省默认值。指定各元素默认值时 defaults 数组的长度必须是输入数组最大的长度。
示例代码
假设集合 stats 有如下记录:
{ "_id": 1, "zip1": [1, 2], "zip2": [3, 4], "zip3": [5, 6] ] }
{ "_id": 2, "zip1": [1, 2], "zip2": [3], "zip3": [4, 5, 6] ] }
{ "_id": 3, "zip1": [1, 2], "zip2": [3] ] }
只传 inputs
const $ = db.command.aggregate
db.collection('items').aggregate()
.project({
zip: $.zip({
inputs: [
'$zip1', // 字段引用
'$zip2',
'$zip3',
],
})
})
.end()
返回结果如下:
{ "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] }
{ "_id": 2, "zip": [ [1, 3, 4] ] }
{ "_id": 3, "zip": null }
设置 useLongestLength
如果设 useLongestLength 为 true:
const $ = db.command.aggregate
db.collection('items').aggregate()
.project({
zip: $.zip({
inputs: [
'$zip1', // 字段引用
'$zip2',
'$zip3',
],
useLongestLength: true,
})
})
.end()
返回结果如下:
{ "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] }
{ "_id": 2, "zip": [ [1, 3, 4], [2, null, 5], [null, null, 6] ] }
{ "_id": 3, "zip": null }
设置 defaults
const $ = db.command.aggregate
db.collection('items').aggregate()
.project({
zip: $.zip({
inputs: [
'$zip1', // 字段引用
'$zip2',
'$zip3',
],
useLongestLength: true,
defaults: [-300, -200, -100],
})
})
.end()
返回结果如下:
{ "_id": 1, "zip": [ [1, 3, 5], [2, 4, 6] ] }
{ "_id": 2, "zip": [ [1, 3, 4], [2, -200, 5], [-300, -200, 6] ] }
{ "_id": 3, "zip": null }
更多建议: