You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB嵌套$Lookup实现服务分类ID转分类名称

解决MongoDB服务分类ID转名称数组的聚合查询修改方案

针对你的需求——已关联stores与services集合,现在要把services中categories字段的ID数组替换为categories集合对应的名称数组——可以通过两种方式修改聚合查询实现:

方案一:在关联services时同步处理分类名称

直接在关联services的$lookup中嵌入子管道,对每个服务单独处理分类ID转名称:

db.stores.aggregate([
  {
    $lookup: {
      from: "services",
      localField: "services",
      foreignField: "_id",
      as: "services",
      pipeline: [
        // 关联categories集合,获取分类文档
        {
          $lookup: {
            from: "categories",
            localField: "categories",
            foreignField: "_id",
            as: "categoryNames"
          }
        },
        // 替换categories为名称数组,清理临时字段
        {
          $set: {
            categories: { $map: { input: "$categoryNames", as: "cat", in: "$$cat.name" } },
            categoryNames: "$$REMOVE"
          }
        }
      ]
    }
  }
])

逻辑说明:

  1. 外层$lookup保持原有逻辑,关联stores与services集合,得到门店对应的服务列表。
  2. 内层pipeline对每个匹配到的service做两件事:
    • 用$lookup根据service的categories ID数组,从categories集合拉取对应的分类文档,存到临时字段categoryNames。
    • 用$map遍历categoryNames,提取每个分类的name字段,替换原categories字段,再用$$REMOVE删除临时字段。

方案二:先拉取所有分类,再批量匹配名称

如果服务数量较多,这种方式可以减少多次关联的开销:

db.stores.aggregate([
  // 原逻辑:关联stores与services
  {
    $lookup: {
      from: "services",
      localField: "services",
      foreignField: "_id",
      as: "services"
    }
  },
  // 拉取所有涉及的分类文档到临时字段
  {
    $lookup: {
      from: "categories",
      localField: "services.categories",
      foreignField: "_id",
      as: "allCategories"
    }
  },
  // 遍历服务列表,替换categories为名称数组
  {
    $set: {
      services: {
        $map: {
          input: "$services",
          as: "service",
          in: {
            // 保留服务原有所有字段
            ..."$$service",
            // 匹配分类名称
            categories: {
              $map: {
                input: "$$service.categories",
                as: "catId",
                in: {
                  $getField: {
                    field: "name",
                    input: {
                      $first: {
                        $filter: {
                          input: "$allCategories",
                          cond: { $eq: ["$$this._id", "$$catId"] }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      // 删除临时分类字段
      allCategories: "$$REMOVE"
    }
  }
])

逻辑说明:

  1. 完成stores与services的关联后,用$lookup一次性拉取所有服务涉及的分类文档,存到allCategories。
  2. 用$map遍历每个服务,保留原有字段的同时,对每个分类ID,从allCategories中过滤匹配的文档并提取name字段,最终形成名称数组替换原categories。
  3. 最后清理临时的allCategories字段。

两种方案都能输出你期望的格式,比如某个服务的categories字段会变成:

"categories": [
  "cat 1",
  "cat 2"
]

内容的提问来源于stack exchange,提问作者Mariano L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 18:33:11