Mongodb returns 所有 $lookup 外国文档不存在的文档的聚合

Mongodb aggregation that returns all documents where $lookup foreign doc DOESN'T exist

我现在正在使用 CMS 系统,如果页面被删除,相关内容不会被删除。对于我的一个客户来说,这已经成为一种负担,因为随着时间的推移,我们现在积累了数百万内容文档,这使得执行日常功能变得令人望而却步,比如恢复数据库、备份数据库等。

考虑这个结构:

页面文档:

{
  _id: pageId,
  contentDocumentId: someContentDocId
}

内容文档:

{
  _id: someContentDocId,
  page_id: pageId,
  content: [someContent, ...etc]
}

有没有办法制作一个 MongoDB 聚合,我们根据检查 page_id 聚合内容文档,如果我们检查 page_id returns 为空,那么我们汇总那个文件?这不像 $lookup 中的 foreignField 设置为 null 这么简单,是吗?

这应该可以解决问题:

db.content.aggregate([
  {
    "$lookup": {
      "from": "pages",
      "localField": "page_id",
      "foreignField": "_id",
      "as": "pages"
    }
  },
  {
    "$addFields": {
      "pages_length": {
        "$size": "$pages"
      }
    }
  },
  {
    "$match": {
      "pages_length": 0
    }
  },
  {
    "$unset": [
      "pages",
      "pages_length"
    ]
  }
])

我们从 content 集合创建一个聚合,并用 pages 集合做一个正常的 $loopup。当找不到匹配的页面时,数组 pages 将是 [] 所以我们只过滤数组为空的每个文档。

不能在$match里面使用$size来过滤数组长度,所以我们需要创建一个临时字段pages_length来存储数组的长度。

最后我们删除了 $unset 的临时字段。

Playground