首页 > 解决方案 > MongoDB如何使用未定义的$lookups(聚合)查找文档

问题描述

我在原始集合中有一个文档,该文档包含或不包含对外国集合文档的引用 - 密钥不是强制性的,因此有时它会丢失。

在这种情况下,$lookup 是“失败的”,并且没有从数据库中获取所需的文档。

这是管道:

{
    $lookup: {
      from: "tables",
      let: { "enginefuel_type": "$engine.fuel_type" },
      pipeline: [
        { $match: { $expr: { $eq: ["$_id", "$$enginefuel_type"] }}},
        { $project: { title: 1 }}
      ],
      as: "engine.fuel_type"
    }
  },
  {
    $unwind: "$engine.fuel_type"
  },

  {
    $lookup: {
      from: "tables",
      let: { "enginegear": "$engine.gear" },
      pipeline: [
        { $match: { $expr: { $eq: ["$_id", "$$enginegear"] }}},
        { $project: { title: 1 }}
      ],
      as: "engine.gear"
    }
  },
  {
    $unwind: "$engine.gear"
  }

无论如何,我都需要找到该文档 - 无论它是否具有engine.fuel_type和/或engine.gear字段。如果有,那么它应该从外部获取文档,否则保持为空而不忽略整个文档。

我考虑过在进行聚合查询之前进行一些 pre-if 语句检查该字段是否存在(也可以更有效,减少对数据库的请求)。

有什么好办法吗?

标签: mongodbnosqlaggregate

解决方案


查找阶段按您的需要工作,即使原始集合中不存在该字段,文档也不会被忽略,并且将成为包含 0 个元素的“engine.fuel_type”数组的结果的一部分。

这是一个展开阶段,它删除了具有 0 个数组元素的文档。幸运的是,$unwind阶段提供了 preserveNullAndEmptyArrays: 选项,包括所有结果。所以你可以尝试做这样的事情: -

$lookup: {
      from: "tables",
      let: { "enginefuel_type": "$engine.fuel_type" },
      pipeline: [
        { $match: { $expr: { $eq: ["$_id", "$$enginefuel_type"] }}},
        { $project: { title: 1 }}
      ],
      as: "engine.fuel_type"
    }
  },
  {
    $unwind: {
      path: "engine.fuel_type",
      preserveNullAndEmptyArrays: true
    }
  }

推荐阅读