查找未跨数组包含的MongoDB文档

cvxl0en2  于 2023-02-07  发布在  Go
关注(0)|答案(3)|浏览(140)

MongoDB集合A包含具有集合B的一些文档id的数组的文档:
集合A:

{
    some_ids_of_b: ["id1", ...]
}

集合B:

{
    _id: "id1"
},
{
    _id: "id2"
},
...

如何查询所有来自B的文档,其_ids未包含在A的文档的some_ids_of_b数组中?

ubbxdtey

ubbxdtey1#

从集合B到集合A的简单查找和过滤,只保留那些找不到任何匹配项的文档。

db.collb.aggregate([
  {
    "$lookup": {
      "from": "colla",
      "localField": "_id",
      "foreignField": "someIdsOfB",
      "as": "a"
    }
  },
  {
    $match: {
      $expr: {
        $eq: [{$size: "$a"}, 0]
      }
    }
  }
])

Demo

f8rj6qna

f8rj6qna2#

一种选择是:

db.collectionB.aggregate([
  {$lookup: {
      from: "collectionA",
      let: {my_id: "$_id"},
      pipeline: [
        {$match: {$and: [
              {_id: collADocId},
              {$expr: {$in: ["$$my_id", "$some_ids_of_b"]}}
        ]}},
        {$project: {_id: 1}}
      ],
      as: "some_ids_of_b"
  }},
  {$match: {"some_ids_of_b.0": {$exists: false}}},
  {$unset: "some_ids_of_b"}
])

了解它在playground example上的工作原理

xurqigkl

xurqigkl3#

您可以使用聚合框架来完成此操作:

  • $group$addToSet-从A集合中的所有文档获取所有$some_ids_of_b
  • $set with $reduce-使用B集合中ID的所有唯一值创建数组。
  • $lookup-从B集合中提取文档,其中$b_ids数组中不存在文档的_id
  • $project-将数据投影为预期输出。
db.A.aggregate([
  {
    "$group": {
      "_id": null,
      "b_ids": {
        "$addToSet": "$some_ids_of_b"
      }
    }
  },
  {
    "$set": {
      b_ids: {
        $reduce: {
          input: "$b_ids",
          initialValue: [],
          in: {
            $setUnion: [
              "$$value",
              "$$this"
            ]
          }
        }
      }
    }
  },
  {
    "$lookup": {
      from: "B",
      let: {
        b_ids: "$b_ids"
      },
      pipeline: [
        {
          "$match": {
            "$expr": {
              $ne: [
                {
                  "$in": [
                    "$_id",
                    "$$b_ids"
                  ]
                },
                true
              ]
            }
          }
        }
      ],
      as: "data"
    }
  },
  {
    "$project": {
      data: 1,
      _id: 0
    }
  }
])

Working Example

相关问题