Reputation: 888
I have this LikeSchema
for Posts
and what i want to achieve is check whether the user id
exists from these array of Likes Document's _user_id
Supposed I have this array of Likes
document
[
{
id: 'a',
_user_id: 'u1',
_post_id: 'p1'
},
{
id: 'b',
_user_id: 'u2',
_post_id: 'p1'
}
]
How do I check if user id u1
exists in likes array documents using aggregation?
I have this Like Schema
const LikeSchema = new Schema({
_post_id: {
type: Schema.Types.ObjectId,
ref: 'Post',
required: true
},
_user_id: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
})
And my aggregation
const result = await Post.aggregate([
{
$match: { privacy: 'public' }
},
{
$lookup: {
from: 'likes',
localField: '_id',
foreignField: '_post_id',
as: 'likes'
}
},
{
$addFields: {
isLiked: {
$in: [req.user._id, '$likes'] // WONT WORK SINCE I STILL HAVE TO MAP AS ARRAY OF _user_id
}
}
}
])
The solution I have in mind is to map first the array to only have user id values then perform the $in
expression.
How do I map the likes
array from lookup
in aggregation stages so that it will only contain arrays of user id values to make the $in
expression match? Or maybe there is a better way to check for value that exists in array of objects?
Upvotes: 2
Views: 3480
Reputation: 17858
It seems you can accomplish this in a cleaner way just using one addFields.
const result = await Post.aggregate([
{
$match: { privacy: 'public' }
},
{
$lookup: {
from: 'likes',
localField: '_id',
foreignField: '_post_id',
as: 'likes'
}
},
{
$addFields: {
isLiked: {
$in: [req.user._id, "$likes._id"]
}
}
}
])
Upvotes: 2
Reputation: 888
Finally found the answer.
Turns out, there exists a $map
operator in aggregation. This is how I used it
const result = await Post.aggregate([
{
$match: { privacy: 'public' }
},
{
$lookup: {
from: 'likes',
localField: '_id',
foreignField: '_post_id',
as: 'likes'
}
},
{
$addFields: {
likeIDs: { // map out array of like id's
$map: {
input: "$likes",
as: "postLike",
in: '$$postLike._id'
}
}
}
},
{
$addFields: {
isLiked: {
$in: [req.user._id, '$likeIDs'] // it works now
}
}
}
])
Upvotes: 2