Vijay
Vijay

Reputation: 159

How to use NOT IN array condition inside mongodb $lookup aggregate

I have two collections:

Users:
{
    _id: ObjectId('5e11d2d8ad9c4b6e05e55b82'),
    name:"vijay"
}

Followers :
{
    _id:ObjectId('5ed0c8faac47af698ab9f659'),
    user_id:ObjectId('5e11d2d8ad9c4b6e05e55b82'),
    following:[
        ObjectId(5ee5ca5fac47af698ab9f666'),
        ObjectId('5df7c0a66243414ad2663088')
    ]
    created_at:"2020-05-29T08:34:02.959+00:00"
}

I need to list all users who are not in the following array from users table for a particular user, I've come up with the below by writing aggregate function in followers table.

[
  {
    '$match': {
      'user_id': new ObjectId('5e11d2d8ad9c4b6e05e55b82')
    }
  }, {
    '$project': {
      'user_id': '$user_id', 
      'following': '$following'
    }
  }, {
    '$lookup': {
      'from': 'users', 
      'pipeline': [
        {
          '$match': {
            '_id': {
              '$nin': [
                '$following'
              ]
            }
          }
        }
      ], 
      'as': 'result'
    }
  }
]

but this is not populating the output I needed.

Can anyone help me with this?

Thanks

Upvotes: 4

Views: 3817

Answers (1)

turivishal
turivishal

Reputation: 36104

You should use $not $in with $expr expression, Because $nin is a query operator not for aggregation expression,

  • one more fix you need to create variable using let: { following: "$following"} and use inside pipeline $$following, because lookup pipeline will not allow to access fields without reference,
  {
    $lookup: {
      from: "Users",
      let: {
        following: "$following"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $not: {
                $in: [
                  "$_id",
                  "$$following"
                ]
              }
            }
          }
        }
      ],
      as: "result"
    }
  }

Working Playground: https://mongoplayground.net/p/08OT6NnuYHx

Upvotes: 3

Related Questions