微信小程序开发文档 第7页
Aggregate.end(): Promise<Object> 支持端:小程序 2.7.4, 云函数 0.8.1, Web 标志聚合操作定义完成,发起实际聚合操作 返回值 Promise.<Object> 属性 类型 说明 list Array.<any> 聚合结果列表 示例代码 const $ = db.command.aggregate db.collection('books').aggregate() .group({ // 按 category 字段分组 _id: '$category', // 让输出的每组记录有一个 avgSales 字段,其值是组内所有记录的 sales 字段的平均值 avgSales: $.avg('$sales') }) .end() .then(res => console.log(res)) .catch(err => console.error(err)) 小程序端兼容支持 callback 风格 const $ = db.command.aggregate db.collection('books').aggregate() .group({ // 按 category 字段分组 _id: '$category', // 让输出的每组记录有一个 avgSales 字段,其值是组内所有记录的 sales 字段的平均值 avgSales: $.avg('$sales') }) .end({ success: function(res) { console.log(res) }, fail: function(err) { console.error(err) } })
Aggregate.unwind(value:string|object): Aggregate 支持端:小程序 2.7.4, 云函数 0.8.1, Web 聚合阶段。使用指定的数组字段中的每个元素,对文档进行拆分。拆分后,文档会从一个变为一个或多个,分别对应数组的每个元素。 参数 value: string|object 返回值 Aggregate API 说明 使用指定的数组字段中的每个元素,对文档进行拆分。拆分后,文档会从一个变为一个或多个,分别对应数组的每个元素。 unwind 有两种使用形式: 参数是一个字段名 unwind(<字段名>) 参数是一个对象 unwind({ path: <字段名>, includeArrayIndex: <string>, preserveNullAndEmptyArrays: <boolean> }) 字段 类型 说明 path string 想要拆分的数组的字段名,需要以 $ 开头。 includeArrayIndex string 可选项,传入一个新的字段名,数组索引会保存在这个新的字段上。新的字段名不能以 $ 开头。 preserveNullAndEmptyArrays boolean 如果为 true,那么在 path 对应的字段为 null、空数组或者这个字段不存在时,依然会输出这个文档;如果为 false,unwind 将不会输出这些文档。默认为 false。 示例 拆分数组 假设我们有一个 products 集合,包含数据如下: { "_id": "1", "product": "tshirt", "size": ["S", "M", "L"] } { "_id": "2", "product": "pants", "size": [] } { "_id": "3", "product": "socks", "size": null } { "_id": "4", "product": "trousers", "size": ["S"] } { "_id": "5", "product": "sweater", "size": ["M", "L"] } 我们根据 size 字段对这些文档进行拆分 db.collection('products') .aggregate() .unwind('$size') .end() 输出如下: { "_id": "1", "product": "tshirt", "size": "S" } { "_id": "1", "product": "tshirt", "size": "M" } { "_id": "1", "product": "tshirt", "size": "L" } { "_id": "4", "product": "trousers", "size": "S"...
Aggregate.sortByCount(object:Object): Aggregate 支持端:小程序 2.7.4, 云函数 0.8.1, Web 聚合阶段。根据传入的表达式,将传入的集合进行分组(group)。然后计算不同组的数量,并且将这些组按照它们的数量进行排序,返回排序后的结果。 参数 object: Object 返回值 Aggregate API 说明 sortByCount 的调用方式如下: sortByCount(<表达式>) 表达式的形式是:$ + 指定字段。请注意:不要漏写 $ 符号。 示例 统计基础类型 假设集合 passages 的记录如下: { "category": "Web" } { "category": "Web" } { "category": "Life" } 下面的代码就可以统计文章的分类信息,并且计算每个分类的数量。即对 category 字段执行 sortByCount 聚合操作。 db.collection('passages') .aggregate() .sortByCount('$category') .end() 返回的结果如下所示:Web 分类下有2篇文章,Life 分类下有1篇文章。 { "_id": "Web", "count": 2 } { "_id": "Life", "count": 1 } 解构数组类型 假设集合 passages 的记录如下:tags 字段对应的值是数组类型。 { "tags": [ "JavaScript", "C#" ] } { "tags": [ "Go", "C#" ] } { "tags": [ "Go", "Python", "JavaScript" ] } 如何统计文章的标签信息,并且计算每个标签的数量?因为 tags 字段对应的数组,所以需要借助 unwind 操作解构 tags 字段,然后再调用 sortByCount。 下面的代码实现了这个功能: db.collection('passages') .aggregate() .unwind(`$tags`) .sortByCount(`$tags`) .end() 返回的结果如下所示: { "_id": "Go", "count": 2 } { "_id": "C#", "count": 2 } { "_id": "JavaScript", "count": 2 } { "_id": "Python", "count": 1 }
Aggregate.sort(object: Object): Aggregate 支持端:小程序 2.7.4, 云函数 0.8.1, Web 聚合阶段。根据指定的字段,对输入的文档进行排序。 参数 object: Object 返回值 Aggregate API 说明 形式如下: sort({ <字段名1>: <排序规则>, <字段名2>: <排序规则>, }) <排序规则>可以是以下取值: 1 代表升序排列(从小到大); -1 代表降序排列(从大到小); 示例 升序/降序排列 假设我们有集合 articles,其中包含数据如下: { "_id": "1", "author": "stark", "score": 80, "age": 18 } { "_id": "2", "author": "bob", "score": 60, "age": 18 } { "_id": "3", "author": "li", "score": 55, "age": 19 } { "_id": "4", "author": "jimmy", "score": 60, "age": 22 } { "_id": "5", "author": "justan", "score": 95, "age": 33 } db.collection('articles') .aggregate() .sort({ age: -1, score: -1 }) .end() 上面的代码在 students 集合中进行聚合搜索,并且将结果排序,首先根据 age 字段降序排列,然后再根据 score 字段进行降序排列。 输出结果如下: { "_id": "5", "author": "justan", "score": 95, "age": 33 } { "_id": "4", "author": "jimmy", "score": 60, "age": 22 } { "_id": "3", "author": "li", "score": 55, "age": 19 } { "_id": "1",...
Aggregate.skip(value: number): Aggregate 支持端:小程序 2.7.4, 云函数 0.8.1, Web 聚合阶段。指定一个正整数,跳过对应数量的文档,输出剩下的文档。 参数 value: number 返回值 Aggregate 示例 db.collection('users') .aggregate() .skip(5) .end() 这段代码会跳过查找到的前 5 个文档,并且把剩余的文档输出。
Aggregate.sample(size: number): Aggregate 支持端:小程序 2.7.4, 云函数 0.8.1, Web 聚合阶段。随机从文档中选取指定数量的记录。 参数 size: number 返回值 Aggregate API 说明 sample 的形式如下: sample({ size: <正整数> }) 请注意:size 是正整数,否则会出错。 示例 假设文档 users 有以下记录: { "name": "a" } { "name": "b" } 随机选取 如果现在进行抽奖活动,需要选出一名幸运用户。那么 sample 的调用方式如下: db.collection('users') .aggregate() .sample({ size: 1 }) .end() 返回了随机选中的一个用户对应的记录,结果如下: { "_id": "696529e4-7e82-4e7f-812e-5144714edff6", "name": "b" }
Aggregate.replaceRoot(object:Object): Aggregate 支持端:小程序 2.7.4, 云函数 0.8.1, Web 聚合阶段。指定一个已有字段作为输出的根节点,也可以指定一个计算出的新字段作为根节点。 参数 object: Object 返回值 Aggregate API 说明 replaceRoot 使用形式如下: replaceRoot({ newRoot: <表达式> }) 表达式格式如下: 格式 说明 <字段名> 指定一个已有字段作为输出的根节点(如果字段不存在则报错) <对象> 计算一个新字段,并且把这个新字段作为根节点 示例 使用已有字段作为根节点 假设我们有一个 schools 集合,内容如下: { "_id": 1, "name": "SFLS", "teachers": { "chinese": 22, "math": 18, "english": 21, "other": 123 } } 下面的代码使用 replaceRoot,把 teachers 字段作为根节点输出: db.collection('schools') .aggregate() .replaceRoot({ newRoot: '$teachers' }) .end() 输出如下: { "chinese": 22, "math": 18, "english": 21, "other": 123 } 使用计算出的新字段作为根节点 假设我们有一个 roles 集合,内容如下: { "_id": 1, "first_name": "四郎", "last_name": "黄" } { "_id": 2, "first_name": "邦德", "last_name": "马" } { "_id": 3, "first_name": "牧之", "last_name": "张" } 下面的代码使用 replaceRoot,把 first_name 和 last_name 拼在一起: const { concat } = db.command.aggregate db.collection('roles') .aggregate() .replaceRoot({ newRoot: { full_name: concat(['$last_name', '$first_name']) } }) .end() 输出如下: { "full_name": "黄四郎" } { "full_name": "马邦德" } { "full_name": "张牧之" }
Aggregate.project(object: Object): Aggregate 支持端:小程序 2.7.4, 云函数 0.8.1, Web 聚合阶段。把指定的字段传递给下一个流水线,指定的字段可以是某个已经存在的字段,也可以是计算出来的新字段。 参数 object: Object 返回值 Aggregate API 说明 project 的形式如下: project({ <表达式> }) 表达式可以有以下格式: 格式 说明 <字段>: <1 或 true> 指定包含某个已有字段 _id: <0 或 false> 舍弃 _id 字段 <字段>: <表达式> 加入一个新字段,或者重置某个已有字段 <字段>: <0 或 false> 舍弃某个字段(如果你指定舍弃了某个非 _id 字段,那么在此次 project 中,你不能再使用其它表达式) 指定包含字段 _id 字段是默认包含在输出中的,除此之外其他任何字段,如果想要在输出中体现的话,必须在 project 中指定; 如果指定包含一个尚不存在的字段,那么 project 会忽略这个字段,不会加入到输出的文档中; 指定排除字段 如果你在 project 中指定排除某个字段,那么其它字段都会体现在输出中; 如果指定排除的是非 _id 字段,那么在本次 project 中,不能再使用其它表达式; 加入新的字段或重置某个已有字段 你可以使用一些特殊的表达式加入新的字段,或重置某个已有字段。 多层嵌套的字段 有时有些字段处于多层嵌套的底层,我们可以使用点记法: "contact.phone.number": <1 or 0 or 表达式> 也可以直接使用嵌套的格式: contact: { phone: { number: <1 or 0 or 表达式> } } 示例 假设我们有一个 articles 集合,其中含有以下文档: { "_id": 666, "title": "This is title", "author": "Nobody", "isbn": "123456789", "introduction": "......" } 指定包含某些字段 下面的代码使用 project,让输出只包含 _id、title 和 author 字段: db.collection('articles') .aggregate() .project({ title: 1, author: 1 }) .end() 输出如下: { "_id" : 666, "title" : "This is title", "author" : "Nobody" } 去除输出中的 _id 字段 _id 是默认包含在输出中的,如果不想要它,可以指定去除它: db.collection('articles') .aggregate() .project({ _id: 0, // 指定去除 _id 字段 title:...
Aggregate.match(object: Object): Aggregate 支持端:小程序 2.7.4, 云函数 0.8.1, Web 聚合阶段。根据条件过滤文档,并且把符合条件的文档传递给下一个流水线阶段。 参数 object: Object 返回值 Aggregate API 说明 match 的形式如下: match(<查询条件>) 查询条件与普通查询一致,可以用普通查询操作符,注意 match 阶段和其他聚合阶段不同,不可使用聚合操作符,只能使用查询操作符。 // 直接使用字符串 match({ name: 'Tony Stark' }) // 使用操作符 const _ = db.command match({ age: _.gt(18) }) match 内使用查询操作符从小程序基础库 2.8.3、云函数 SDK 1.3.0 开始支持。 示例 假设集合 articles 有如下记录: { "_id" : "1", "author" : "stark", "score" : 80 } { "_id" : "2", "author" : "stark", "score" : 85 } { "_id" : "3", "author" : "bob", "score" : 60 } { "_id" : "4", "author" : "li", "score" : 55 } { "_id" : "5", "author" : "jimmy", "score" : 60 } { "_id" : "6", "author" : "li", "score" : 94 } { "_id" : "7", "author" : "justan", "score" : 95 } 匹配 下面是一个直接匹配的例子: db.collection('articles') .aggregate()...
Aggregate.lookup(object: Object): Aggregate 支持端:云函数 1.3.0 聚合阶段。聚合阶段。联表查询。与同个数据库下的一个指定的集合做 left outer join(左外连接)。对该阶段的每一个输入记录,lookup 会在该记录中增加一个数组字段,该数组是被联表中满足匹配条件的记录列表。lookup 会将连接后的结果输出给下个阶段。 参数 object: Object 返回值 Aggregate API 说明 lookup 有两种使用方式 1. 相等匹配 将输入记录的一个字段和被连接集合的一个字段进行相等匹配时,采用以下定义: lookup({ from: <要连接的集合名>, localField: <输入记录的要进行相等匹配的字段>, foreignField: <被连接集合的要进行相等匹配的字段>, as: <输出的数组字段名> }) 参数详细说明 参数字段 说明 from 要进行连接的另外一个集合的名字 localField 当前流水线的输入记录的字段名,该字段将被用于与 from 指定的集合的 foreignField 进行相等匹配。如果输入记录中没有该字段,则该字段的值在匹配时会被视作 null foreignField 被连接集合的字段名,该字段会被用于与 localField 进行相等匹配。如果被连接集合的记录中没有该字段,该字段的值将在匹配时被视作 null as 指定连接匹配出的记录列表要存放的字段名,这个数组包含的是匹配出的来自 from 集合的记录。如果输入记录中本来就已有该字段,则该字段会被覆写 这个操作等价于以下伪 SQL 操作: SELECT *, <output array field> FROM collection WHERE <output array field> IN (SELECT * FROM <collection to join> WHERE <foreignField>= <collection.localField>); 例子: 指定一个相等匹配条件 对数组字段应用相等匹配 组合 mergeObjects 应用相等匹配 2. 自定义连接条件、拼接子查询 如果需要指定除相等匹配之外的连接条件,或指定多个相等匹配条件,或需要拼接被连接集合的子查询结果,那可以使用如下定义: lookup({ from: <要连接的集合名>, let: { <变量1>: <表达式1>, ..., <变量n>: <表达式n> }, pipeline: [ <在要连接的集合上进行的流水线操作> ], as: <输出的数组字段名> }) 参数详细说明 参数字段 说明 from 要进行连接的另外一个集合的名字 let 可选。指定在 pipeline 中可以使用的变量,变量的值可以引用输入记录的字段,比如 let: { userName: '$name' } 就代表将输入记录的 name 字段作为变量 userName 的值。在 pipeline 中无法直接访问输入记录的字段,必须通过 let 定义之后才能访问,访问的方式是在 expr 操作符中用 $$变量名 的方式访问,比如 $$userName。 pipeline 指定要在被连接集合中运行的聚合操作。如果要返回整个集合,则该字段取值空数组 []。在 pipeline 中无法直接访问输入记录的字段,必须通过 let 定义之后才能访问,访问的方式是在 expr 操作符中用 $$变量名 的方式访问,比如 $$userName。 as 指定连接匹配出的记录列表要存放的字段名,这个数组包含的是匹配出的来自 from 集合的记录。如果输入记录中本来就已有该字段,则该字段会被覆写 该操作等价于以下伪 SQL 语句: SELECT *, <output array field> FROM collection WHERE <output array field> IN (SELECT <documents...