Node.js 通过检查数组Mongodb中的值,从双嵌套数组中进行投影
以上是我文件的结构。 我要做的是,从程序数组中,我要投影练习的名称,这些练习在属性数组中至少有一个文档,属性数组的done key标记为true。我想做的是找出在属性数组中设置为true的练习Node.js 通过检查数组Mongodb中的值,从双嵌套数组中进行投影,node.js,mongodb,aggregation-framework,Node.js,Mongodb,Aggregation Framework,以上是我文件的结构。 我要做的是,从程序数组中,我要投影练习的名称,这些练习在属性数组中至少有一个文档,属性数组的done key标记为true。我想做的是找出在属性数组中设置为true的练习 是否有任何方法可以获得如下输出: { _id: 'uniquewId', programs: [ { prgName: 'prgOne', progress: '5', addedBy: 'coach'
是否有任何方法可以获得如下输出:
{
_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
}
]
}
]
}
]
}
]
}
这是一个乏味的过程 使用运算符,我们可以迭代数组。另外,
$map
允许将对象数组转换为字符串数组
{
_id: 'uniquewId',
programs: [
{
prgName: 'prgOne',
exercises: [
'pushup',
'situp'
]
},
{
prgName: 'prgTwo',
exercises: [
'pushup',
'situp'
]
}
]
}
伪码 第一步。我们执行复杂的聚合和预计算值
[{k1:v1}, {k2:v2}, ...] -> [v1, v2, ...]
第二步。我们构造期望的结果
为什么
prgTwo
只有一个元素?很抱歉,它应该有两个元素感谢回复,但我的问题有一个错误。我已经更新了问题。抱歉:)谢谢,它能用:)。有没有什么方法可以用一个投影来完成呢。我只是想问问你curiosity@AkhilS当然,但它将是一个巨大的怪物:)
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"
]
]
}
]
}
}
}
}
}
}
}
}
])