diff --git "a/_posts/2024-09-05-\346\225\260\346\215\256\345\272\223\350\201\232\345\220\210\346\223\215\344\275\234.md" "b/_posts/2024-09-05-\346\225\260\346\215\256\345\272\223\350\201\232\345\220\210\346\223\215\344\275\234.md" new file mode 100644 index 0000000..9b14120 --- /dev/null +++ "b/_posts/2024-09-05-\346\225\260\346\215\256\345\272\223\350\201\232\345\220\210\346\223\215\344\275\234.md" @@ -0,0 +1,169 @@ +--- +layout: post +title: 数据库聚合操作 +subtitle: db.command.aggregate +date: 2024-09-05 09:12:30 GMT+0800 +author: 920 +header-img: +catalog: true +stickie: false +tags: + - uniapp + - uniCloud +--- + +#### 示例 + +```js +async list() { + const $ = db.command.aggregate + let res = await db.collection("dcloud-inc").aggregate() + .group({ + // 按照 date 字段进行分组 + _id: "$date", + // 对 inctype=0 的数据中的 money 进行求和计算,并将所求之和作为 normoney 输出 + normoney: { + $sum: { + $cond: { + if: { $eq: ["$inctype", 0] }, + then: "$money", + else: 0 + } + } + }, + // 对 inctype=1 的数据中的 money 进行求和计算,并将所求之和作为 extmoney 输出 + extmoney: { + $sum: { + $cond: { + if: { $eq: ["$inctype", 1] }, + then: "$money", + else: 0 + } + } + }, + /* + * 对同一 date 下的所有 mark 合并处理; + * 处理方式: + * 对每条数据的 mark 做非空判断,不为空就将此条 mark+分号,加入到 allmark + * 为空就将空字符串加入到 allmark + * + * 注意: + * 这时输出的 allmark 是一个数组, + * 对非空 mark 拼接分号是为了下一步处理成字符串做准备 + */ + allmark: { + $addToSet: { + $cond: { + if: { $ne: ["$mark", ""] }, + then: { $concat: ["$mark", ";"] }, + else: "" + } + } + } + }) + .addFields({ + /* + * allmark 字段可能是一个包含多个字符串的数组。 + * $reduce 是一个聚合操作符,它会遍历数组中的每个元素并根据定义的逻辑来处理这些元素。 + * 在这里,input: "$allmark" 指定了要处理的数组,即 allmark 字段中的值。 + * initialValue: "" 表示初始值为空字符串,它是 $reduce 操作的初始累加器的值。 + * in: { $concat: ["$$value", "$$this"] } 定义了在每次迭代中如何处理元素。 + * $$value 表示当前的累加器值; + * $$this 表示当前处理的元素.在这里,每次迭代都将当前元素连接到累加器值后面。 + */ + allmark: { + $reduce: { + input: "$allmark", + initialValue: "", + in: { $concat: ["$$value", "$$this"] } + } + } + }) + /* + * 在当前集合和 'dcloud-works' 集合之间建立一个关联, + * 根据当前集合中的 _id 字段与 'dcloud-works' 集合中的 date 字段进行匹配, + * 并将匹配的结果作为一个数组存储在名为 'works' 的新字段中. + * + * 注意: + * 这时输出的 works 是一个数组. + */ + .lookup({ + from: 'dcloud-works', + // 当前集合的字段 + localField: '_id', + // 关联表中的字段 + foreignField: 'date', + // 关联结果存储在 works 中输出 + as: 'works', + }) + .addFields({ + /** + * 这段代码的作用是将字段 works 处理为一个对象。 + * 如果 works 是一个空数组,则将 works 设置为一个空对象。 + * 如果 works 不是一个空数组,则将 works 数组中的第一个元素输出 + */ + works: { + $cond: { + if: { + // 判断数组的长度是否为0 + $eq: [ {$size: "$works"}, 0] + }, + then: {}, + else: { $arrayElemAt: ["$works", 0] } + } + } + }) + .sort({ + _id: -1 + }) + .end() + + console.log("rk===>[res]", res); + + return { + errSubject: '', + errCode: 0, + errMsg: 'ok' + } +} + +``` + + +#### 结果 + +``` +{ + "affectedDocs": 2, + "data": [ + { + "_id": "2024-09", + "normoney": 500000, + "extmoney": 0, + "allmark": "", + "works": { + "_id": "66d812adf2949ce0c74562ab", + "year": "2024", + "date": "2024-09", + "isfull": 1, + "fullday": 30, + "eventhour": 0, + "create_time": 1725436589212, + "update_time": 1725436589212 + } + }, + { + "_id": "2024-08", + "normoney": 550000, + "extmoney": 120000, + "allmark": "111;", + "works": { + + } + } + ] +} +``` + + +