Mongodb $lookup 带管道的嵌套对象

Mongodb $lookup nested objects with pipeline

我有以下架构 Thing:

{
  name: "My thing",
  files: [
    {
      name: "My file 1",
      versions: [
        {
          file_id: ObjectId("blahblahblah")
        },
        {
          file_id: ObjectId("blahblahblah")
        },
      ],
    },
    {
      name: "My file 2",
      versions: [
        {
          file_id: ObjectId("blahblahblah")
        },
        {
          file_id: ObjectId("blahblahblah")
        },
      ],
    }
  ]
}

然后我有一个 File 模式:

{
  _id: ObjectId("blahblah"),
  type: "image",
  size: 1234,
}

Thing 架构中的 file_id 是对 File 架构的 _id 的引用。

我想 $lookup 我的 Thing 中的所有文件。所以我从这个开始:

{
  "$lookup": {
    "from": "files",
    "let": { "files": "$files" },
    "pipeline": [
      { "$match": { "$expr": { "$in": [ "$_id", "$$files.versions.file_id" ] } } }.
    ],
    "as": "files.versions.file"
  }
}

但这显然是错误的。有人可以帮忙吗?

问题是当我们$$files.versions.file_id 访问 id 时,它会 return id 数组,所以 $in 不会匹配嵌套的 id 数组,

我可以看到您正在尝试在同一嵌套级别中投​​影文件详细信息,因此直接查找不会在嵌套数组中设置该详细信息,您必须在设置文件详细信息之前先解构数组,

  • $unwind解构files数组
  • $unwind解构versions数组
  • $lookupfiles 集合并通过 files.versions.file_id 作为 localField
  • $unwind解构files.versions.file_id数组
  • $group 通过 namefile name 并重新构造 versions 数组
  • $group 仅由 name 重建 files 数组
  { $unwind: "$files" },
  { $unwind: "$files.versions" },
  {
    $lookup: {
      from: "files",
      localField: "files.versions.file_id",
      foreignField: "_id",
      as: "files.versions.file_id"
    }
  },
  { $unwind: "$files.versions.file_id" },
  {
    $group: {
      _id: {
        name: "$name",
        file_name: "$files.name"
      },
      versions: { $push: "$files.versions" }
    }
  },
  {
    $group: {
      _id: "$_id.name",
      files: {
        $push: {
          name: "$_id.file_name",
          versions: "$versions"
        }
      }
    }
  }

Playground