跳到主要内容

聚合搜索

聚合主要用来处理数据(统计平均值,求和等)并返回计算后的数据结果。

流水线/管道#

聚合是一个流水线式的批处理作业,初始文档经过多个阶段的流水线处理后,得到转换后的聚合结果。

假设已有一个集合 books,其中包含以下格式记录:

[  {    "_id": "xxx",    "category": "Novel",    "name": "The Catcher in the Rye",    "onSale": true,    "sales": 80  }]

聚合示例如下:

// 云函数端示例const cloudbase = require("@cloudbase/node-sdk")const app = cloudbase.init()const db = app.database()const $ = db.command.aggregate
exports.main = async (event, context) => {    const res = await db.collection('books').aggregate()    .match({        onSale: true // 是否正在出售    })    .group({        // 按 category 字段分组        _id: '$category',        // 让输出的每组记录有一个 avgSales 字段,其值是组内所有记录的 sales 字段的平均值        avgSales: $.avg('$sales')    })    .end()    return {        res    }}

第一阶段:match 阶段过滤出了集合中的文档数据(onSale:true 表示找出正在出售的书籍)并传给下一个阶段。

第二阶段:group 阶段基于 category 字段进行分组,并统计出每组中所有记录的 sales 字段平均值。

API 及操作符#

参考 Node.js SDK API 文档,一览所有的聚合阶段 API操作符

优化执行#

利用索引#

matchsort 如果是在流水线的开头的话是可以利用索引的。geoNear 也可以利用地理位置索引,但要注意的是,geoNear 必须是流水线的第一个阶段。

尽早缩小数据集#

在不需要集合的全集情况下,应该尽早的通过 matchlimitskip 缩小要处理的记录数量。

注意事项#

除了 match 阶段,在各个聚合阶段中传入的对象中,可使用的操作符都是聚合操作符,需要特别注意的是,match 进行的是查询匹配,因此语法同普通查询 where 的语法,用的是普通查询操作符。