Mongodb subquery in aggregation
I have a collection followers
in mongodb as shown below:
[{
user : <userId> ,
followers : [
{
user : <userId>
, createdOn : <Date>
,...
}
,
{
user : <userId>
, createdOn : <Date>
,...
}
]
},
{
user : <userId> ,
followers : [
{
user : <userId>
, createdOn : <Date>
,...
}
,
{
user : <userId>
, createdOn : <Date>
,...
}
]
}]
When users request /api/users/<userId>/followers
, I try to provide all of the user's subscribers <userId>
. Also, I'm also trying to set a flag to indicate whether a particular follower is followed by a <userId>
user loggedIn
or not. I am trying to output something like below:
{
user : <userId>
, followers : [
{
user : <userId>
, isFollowing : <Boolean>
}
,
{
user : <userId>
, isFollowing : <Boolean>
}
]
}
I give a try and my failed attempt looks like this:
app.get('/users/:userId/followers', function(req, res) {
var userId = req.params.userId;
var loginUser = req.user._id; // I am using passport for user authentication
var Follower = mongoose.model('followers'); // I am using mongoose also
var DocumentObjectId = mongoose.Types.ObjectId;
Follower.aggregate([
{$match : { user : DocumentObjectId(userId)}}
, {$project : {"followers" : 1, "_id" : 0}}
, {$unwind : "$followers"}
, {$group : {
_id : {"user : "$user"}
, "followers" : {$push:{
"user" : "$followers.user"
, "isFollowing" : {$and : [{user: "$followers.user"}, {"followers.user" : loginUser}]}
}}
}}
])
})
But I am getting this error from mongodb:
exception: dotted field names are only allowed at the top level
What should I do to know what a particular one follower
is followed
on logged in user
. So that I can display the button Follow
or Unfollow
in the UI when some user is viewing other users.
source to share
You need to use an aggregation pipeline as shown below:
-
Match
user with corresponding userId. -
Unwind
array of followers. - For each unlisted follower , a
project
name fieldisFollowing
that conditionally states whether or not it is a registered user, implying that it is a follower of the Search User. -
Group
return unrecorded records based on user and create arrayfollowers
with extra fieldisFollowing
.
Code:
var loginUser = 2;
var userId = 3;
var documentObjectId = mongoose.Types.ObjectId;
Follower.aggregate(
{$match:{"user":documentObjectId(userId)}},
{$unwind:"$followers"},
{$project:{"user":1,"_id":0,
"follower":"$followers.user",
"isFollowing":{$cond:[{$eq:["$followers.user",loginUser]}
,true,false]}}},
{$group:{"_id":"$user",
"followers":{$push: {"user":"$follower",
"isFollowing":"$isFollowing"}}}},
function(err,resp){//handle response}
);
But I am getting this error from mongodb: exception: dotfield names are only allowed at the top level
You cannot do {"followers.user" : loginUser}
in a group in stages, this is a criterion statement that can only be applied in a stage $match
. To view the entire applicable group of operators, contact the operators .
source to share