-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
169 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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": { | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
|
||
|