如何根据一个特定文档的数组过滤 MongoDB 个文档?

How to filter MongoDB documents based on one specific document's array?

我有一个 collection 这样的:

{
  _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",
  ]
},

现在,如果我是 "_id: "blabla" 的用户,我想获取除 "blabla2" 之外的所有用户,因为它在我的 "interactedUsers" 数组中。我怎样才能做到这一点?我尝试了很多聚合组合,但无法真正得到想要的结果。

由于您可能不想使用 $facet,因为它会将您的所有集合合并到一个大文档中,另一种选择是使用 $lookup.

这允许您将“忽略的”文档添加到所有其他文档,然后从答案中删除包含它的文档。这样做的好处是您的所有文档在整个过程中都是分开的:

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

这是 return 集合中所有 "_id" 而不是 "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"
        }
      }
    }
  }
])

mongoplayground.net 上试用。