skip to Main Content

I have a collection like this:

{
  _id: "blabla",
  userName: "blablabla",
  ..
  interactedUsers: [
    "blabla2"
    "some other user's id",
    "some other user's id",
  ]
},
{
  _id: "blabla2",
  userName: "blablabla2",
  ..
  interactedUsers: [
    "some other user's id",
    "some other user's id",
  ]
},

Now if i am the user with "_id: "blabla" i want to fetch all users except "blabla2" because its in my "interactedUsers" array. How can i do that? I tried so many aggregation combinations but couldn’t really get the wanted result.

2

Answers


  1. Since you probably don’t want to use $facet as it will merge all your collection into one big document, another option is to use $lookup.

    This allows you to add the "ignored" document to all other documents and then remove from the answer the ones that contain it. The advantage here is that all your documents are kept separated along the process:

    db.collection.aggregate([
      {
        $addFields: {"ignore": "blabla" }
      },
      {
        $lookup: {
          from: "collection",
          localField: "ignore",
          foreignField: "_id",
          as: "ignore"
        }
      },
      {
        $set: {ignore: {$arrayElemAt: ["$ignore", 0]}}
      },
      {
        $match: {
          $expr: {$not: {$in: ["$_id", "$ignore.interactedUsers"]}}
        }
      },
      {
        $unset: "ignore"
      },
      {
        $match: {$expr: {$ne: ["$_id", "blabla"]}}
      }
    ])
    

    Playground example

    Login or Signup to reply.
  2. Here’s another way to return all "_id" in the collection not in "interactedUsers".

    db.collection.aggregate([
      { "$match": { "_id": "blabla0" } },
      {
        "$lookup": {
          "from": "collection",
          "let": { "notIds": { "$setUnion": [ [ "$_id" ], "$interactedUsers" ] } },
          "pipeline": [
            { "$match": { "$expr": { "$not": { "$in": [ "$_id", "$$notIds" ] } } } },
            { "$project": { "_id": 1 } }
          ],
          "as": "strangers"
        }
      },
      {
        "$set": {
          "strangers": {
            "$map": {
              "input": "$strangers",
              "in": "$$this._id"
            }
          }
        }
      }
    ])
    

    Try it on mongoplayground.net.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search