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.

+3


source to share


1 answer


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 field isFollowing

    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 array followers

    with extra field isFollowing

    .

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 .

+1


source







All Articles