Please consider below model.
interface Model {
title: string
content: string
comments: {
content: string
likes?: number
subComments: {
parentCommentId: string
content: string
likes?: number
}[]
}[]
}
const post: Model = {
title: 'test',
content: 'content',
comments: [
{
content: 'level2',
likes: 3,
subComments: [
{
parentCommentId: '1',
content: 'level3',
likes: 3,
},
],
},
{
content: 'level2',
likes: 3,
subComments: [
{
parentCommentId: '1',
content: 'level3',
likes: 5,
},
{
parentCommentId: '1',
content: 'level3',
likes: 5,
},
],
},
],
}
Let's say we have a post that has comment that has subComment.
The level of subComment is at level 3 but the depth is fixed.
Is there a way to filter subComments that has optional key "likes" and whose value is greater than 3 with MongoClient?
CodePudding user response:
Y don't know exactly what output do you want but you can try something like this example using only projection into find query:
Here there are two $filter
and one map.
The $map
get each object into comments
array and:
- Set the content as it is:
content: "$$comment.content"
- Set the subcomment as an array filtered only by these one objects where likes is greater than 3.
- *I've not added
likes
because it seems no congruent but can be added usinglikes: "$$comment.likes"
So this produce an array with only obbjects where there are more than 3 likes.
That's mean it can produce an empty subComments
array. So the result of the $map
is used into another $filter
to get only object where subComments
is not empty (i.e. there is at least one comment with more than 3 likes).
db.collection.find({},
{
title: 1,
content: 1,
comments: {
$filter: {
input: {
$map: {
input: "$comments",
as: "comment",
in: {
content: "$$comment.content",
subComments: {
$filter: {
input: "$$comment.subComments",
as: "subComment",
cond: {
$gt: [
"$$subComment.likes",
3
]
}
}
}
}
}
},
cond: {
$ne: [
"$$this.subComments",
[]
]
}
}
}
})
Example here.
Which is also the same to use $project
in an aggregate query: example