I had a query that worked before when likes
collection had users stored as from
and to
fields. The query below checked for the two fields and if like
was true.
Since then I changed the way users are stored in the likes
collection.
.collection('likes')
.aggregate([ {$match: {$and : [{$or: [{from: userId}, {to: userId}]}, {like: true}]}},
{$group: {
_id: 0,
from: {$addToSet: "$from"},
to: {$addToSet: "$to"},
}
},
{$project: {
_id: 0,
users: {
$filter: {
input: {$setIntersection: ["$from", "$to"]},
cond: {$ne: ["$$this", userId]}
}
}
}
},
This is how likes
collection used to store data (and above query worked) in figuring out mutual likers for a userId
passed in req.body
{
"_id": "xw5vk1s_PpJaal46di",
"from": "xw5vk1s",
"to": "PpJaal46di"
"like": true,
}
and now I changed users to an array.
{
"_id": "xw5vk1s_PpJaal46di",
"users": [
"xw5vk1s",//first element equivalent to from
"PpJaal46di"//equivalent to previously to
],
"like": true,
}
I am not sure how to modify the query to now check for array elements in users
field now that from
and to
is not where the two users liking each other are stored.
CodePudding user response:
For MongoDB v5.2 , you can use $sortArray
to create a common key for the field users
and $group
to get the count. You will get mutual likes by count > 1.
db.collection.aggregate([
{
$match: {
users: "xw5vk1s"
}
},
{
$group: {
_id: {
$sortArray: {
input: "$users",
sortBy: 1
}
},
count: {
$sum: 1
}
}
},
{
"$match": {
count: {
$gt: 1
}
}
}
])
Prior to MongoDB v5.2, you can create sorted key for grouping through $unwind
and $sort
then $push
back the users
in $group
.
db.collection.aggregate([
{
$match: {
users: "xw5vk1s"
}
},
{
"$unwind": "$users"
},
{
$sort: {
users: 1
}
},
{
$group: {
_id: "$_id",
users: {
$push: "$users"
},
like: {
$first: "$like"
}
}
},
{
"$group": {
"_id": "$users",
"count": {
"$sum": 1
}
}
},
{
"$match": {
count: {
$gt: 1
}
}
}
])