node.js - 通过检查数组 Mongodb 中的值从双重嵌套数组中进行投影
问题描述
{
_id: 'uniquewId',
programs: [
{
prgName: 'prgOne',
progress: '5',
addedBy: 'coach'
exercises: [
{
date: '1/12/20',
exercises: [
{
exId: 'pushup',
progress: 5,
attributes: [
{
id: 'myId',
done: true
},
{
id: 'myId2',
done: false
}
]
},
{
exId: 'situp',
progress: 5,
attributes: [
{
id: 'myId',
done: true
},
{
id: 'myId2',
done: true
}
]
}
]
},
{
date: '2/12/20',
exercises: [
{
exId: 'pushup',
progress: 5,
attributes: [
{
id: 'myId',
done: true
},
{
id: 'myId2',
done: false
}
]
},
{
exId: 'situp',
progress: 5,
attributes: [
{
id: 'myId',
done: fase
},
{
id: 'myId2',
done: false
}
]
}
]
}
]
},
{
prgName: 'prgTwo',
progress: '5',
addedBy: 'coach2'
exercises: [
{
date: '1/12/20',
exercises: [
{
exId: 'pushup',
progress: 5,
attributes: [
{
id: 'myId',
done: true
},
{
id: 'myId2',
done: true
}
]
},
{
exId: 'situp',
progress: 5,
attributes: [
{
id: 'myId',
done: false
},
{
id: 'myId2',
done: false
}
]
}
]
},
{
date: '2/12/20',
exercises: [
{
exId: 'pushup',
progress: 5,
attributes: [
{
id: 'myId',
done: true
},
{
id: 'myId2',
done: false
}
]
},
{
exId: 'situp',
progress: 5,
attributes: [
{
id: 'myId',
done: true
},
{
id: 'myId2',
done: false
}
]
}
]
}
]
}
]
}
以上是我的文档的结构。我想要做的是从程序数组中投影出练习的名称,这些练习的名称在属性数组中至少有一个文档,该文档已将键标记为真。我想要做的是找出在属性数组中设置为 true 的练习
有什么办法可以得到如下输出:
{
_id: 'uniquewId',
programs: [
{
prgName: 'prgOne',
exercises: [
'pushup',
'situp'
]
},
{
prgName: 'prgTwo',
exercises: [
'pushup',
'situp'
]
}
]
}
解决方案
这是一个乏味的过程。
使用$map运算符,我们可以遍历数组。还$map
允许将对象数组转换为字符串数组。
[{k1:v1}, {k2:v2}, ...] -> [v1, v2, ...]
伪代码
第一步。我们执行复杂的聚合并预先计算值
for (Programs program: doc.programs) {
return {
prgName : program.prgName,
exercises : [
for (Exercises exer1: program.exercises) {
for (Exercises exer2: exer1.exercises) {
return {
exId : exer2.exId,
done : exer2.attributes.done.contains(true)
}
}
}
]
}
}
第二步。我们构建期望的结果
db.collection.aggregate([
{
$project: {
programs: {
$map: {
input: "$programs",
as: "program",
in: {
prgName: "$$program.prgName",
exercises: {
$reduce: {
input: {
$map: {
input: "$$program.exercises",
as: "exer1",
in: {
$map: {
input: "$$exer1.exercises",
as: "exer2",
in: {
exId: "$$exer2.exId",
done: {
$in: [
true,
"$$exer2.attributes.done"
]
}
}
}
}
}
},
initialValue: [],
in: {
$concatArrays: [
"$$value",
"$$this"
]
}
}
}
}
}
}
}
},
{
$project: {
programs: {
$map: {
input: "$programs",
as: "program",
in: {
prgName: "$$program.prgName",
exercises: {
$reduce: {
input: {
$filter: {
input: "$$program.exercises",
cond: {
$eq: [
"$$this.done",
true
]
}
}
},
initialValue: [],
in: {
$concatArrays: [
"$$value",
{
$cond: [
{
$in: [
"$$this.exId",
"$$value"
]
},
[],
[
"$$this.exId"
]
]
}
]
}
}
}
}
}
}
}
}
])
推荐阅读
- html - 如何在 HTML 中创建子选项卡
- python - 图像的 Python pyinstaller onefile 可执行文件问题
- reactjs - 如何添加 paytabs 库以响应 js 项目
- mysql - 如何修复 PUT,错误 500 id = undefined ReactJs NodeJs
- jquery - 对 jquery 数据表进行分页
- java - 如何在后台执行服务并检查其状态
- vb.net - 数字思维插入点
- java - 尝试使用数组列表查看用户填写了多少编辑文本
- c++ - C++20 `constinit` 可以免除对漂亮反制成语的需要吗?
- bluestacks - 使用多实例时,是否可以自动启动应用程序?