$sortArray(聚合)
定义
$sortArray
5.2 版本中的新增功能。
根据数组的元素对数组排序。排序顺序由用户指定。
$sortArray
通过以下语法实现:$sortArray: { input: <array>, sortBy: <sort spec> } 字段类型说明input
表达式(expression)待排序的数组。
如果表达式存在以下情况,则结果为
null
:计算结果为缺失。
计算结果为
null
。计算结果为
undefined
。
如果表达式的计算结果为任何其他非数组值,则操作会出错。
sortBy
文档或布尔值文档指定了排序顺序。
行为
$sortArray
表达式根据 sortBy
规范对 input
数组进行排序。
$sortArray
语法和语义与经 $sort
修改的 $push
操作中的行为相同
按文档字段排序
如果数组元素为文档,则可按文档字段排序。指定字段名称和排序方向:升序 (1
) 或降序 (-1
)。
{ input: <array-of-documents>, sortBy: { <document-field>: <sort-direction> } }
按值排序
要按值或按非文档的数组元素对整个数组排序,请标识输入数组并在 sortBy
参数中指定 1(升序)或 -1(降序)。
{ input: <array-of-documents>, sortBy: <sort-direction> }
Considerations
排序稳定性
未指定排序的稳定性。用户不应依赖 $sortArray
来使用特定的排序算法。
示例
本节中的 $sortArray
示例适用于 MongoDB 5.2 及更高版本。
创建 team
集合:
db.engineers.insertOne( { "team": [ { "name": "pat", "age": 30, "address": { "street": "12 Baker St", "city": "London" } }, { "name": "dallas", "age": 36, "address": { "street": "12 Cowper St", "city": "Palo Alto" } }, { "name": "charlie", "age": 42, "address": { "street": "12 French St", "city": "New Brunswick" } } ] } )
team
数组有三个元素。team
的每个元素都有嵌套子元素:name
、age
和 address
。以下示例展示如何使用这些子元素对 team
数组排序。
按字段排序
对数组元素中的字段排序:
db.engineers.aggregate( [ { $project: { _id: 0, result: { $sortArray: { input: "$team", sortBy: { name: 1 } } } } } ] )
name
字段是 team
数组中的一个子元素。该操作返回以下结果:
{ result: [ { name: 'charlie', age: 42, address: { street: '12 French St', city: 'New Brunswick' } }, { name: 'dallas', age: 36, address: { street: '12 Cowper St', city: 'Palo Alto' } }, { name: 'pat', age: 30, address: { street: '12 Baker St', city: 'London' } } ] }
对子字段排序
address
字段是具有自己的子字段的文档。使用点符号根据子字段对数组进行排序:
db.engineers.aggregate( [ { $project: { _id: 0, result: { $sortArray: { input: "$team", sortBy: { "address.city": -1 } } } } } ] )
排序方向为降序,因为 sortBy
值为“-1”。
{ result: [ { name: 'dallas', age: 36, address: { street: '12 Cowper St', city: 'Palo Alto' } }, { name: 'charlie', age: 42, address: { street: '12 French St', city: 'New Brunswick' } }, { name: 'pat', age: 30, address: { street: '12 Baker St', city: 'London' } } ] }
对多个字段进行排序
指定多个索引字段进行复合排序:
db.engineers.aggregate( [ { $project: { _id: 0, result: { $sortArray: { input: "$team", sortBy: { age: -1, name: 1 } } } } } ] )
示例输出:
{ name: 'charlie', age: 42, address: { street: '12 French St', city: 'New Brunswick' } }, { name: 'dallas', age: 36, address: { street: '12 Cowper St', city: 'Palo Alto' } }, { name: 'pat', age: 30, address: { street: '12 Baker St', city: 'London' } }
对整数数组排序
此示例直接指定输入数组。值的类型相同,都是 Int32:
db.engineers.aggregate( [ { $project: { _id: 0, result: { $sortArray: { input: [ 1, 4, 1, 6, 12, 5 ], sortBy: 1 } } } } ] )
示例输出:
[ { result: [ 1, 1, 4, 5, 6, 12 ] } ]
输入数组的位置 0 和位置 2 为“1”。这些值在结果中分组在一起,但不能保证这一组值如何相对于其原始顺序进行排序。
对混合类型字段排序
此示例将直接指定输入数组。这些值具有不同类型:
db.engineers.aggregate( [ { $project: { _id: 0, result: { $sortArray: { input: [ 20, 4, { a: "Free" }, 6, 21, 5, "Gratis", { a: null }, { a: { sale: true, price: 19 } }, Decimal128( "10.23" ), { a: "On sale" } ], sortBy: 1 } } } } ] )
示例输出:
{ result: [ 4, 5, 6, Decimal128("10.23"), 20, 21, 'Gratis', { a: null }, { a: 'Free' }, { a: 'On sale' }, { a: { sale: true, price: 19 } } ] }
结果已进行排序。
在更改 sortBy
字段以对文档字段 sortBy: { a: 1 }
排序后,标量和 null
值的排序顺序未定义:
{ result: [ 20, 4, 6, 21, 5, 'Gratis', { a: null }, Decimal128("10.23"), { a: 'Free' }, { a: 'On sale' }, { a: { sale: true, price: 19 } } ] }