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

如何通过MongoDB聚合获取搜索结果中去重的产品主副类别

解决方案

你可以通过MongoDB聚合管道实现需求,以下是具体的聚合查询,能返回去重后的主、子类别层级结构:

db.products.aggregate([
  // 1. 匹配全文搜索结果(不设limit,确保覆盖所有相关产品)
  {
    $match: {
      $text: { $search: 'IPhone 6' }
    }
  },
  // 2. 按主类别分组,收集唯一的子类别组合
  {
    $group: {
      _id: {
        main_category_id: "$main_category_id",
        main_category_name: "$main_category_name"
      },
      sub_category_entries: {
        $addToSet: {
          sub1_name: "$sub_category_1_name",
          sub1_id: "$sub_category_1_id",
          sub2_name: "$sub_category_2_name",
          sub2_id: "$sub_category_2_id",
          sub3_name: "$sub_category_3_name",
          sub3_id: "$sub_category_3_id"
        }
      }
    }
  },
  // 3. 整理子类别为层级嵌套结构
  {
    $addFields: {
      sub_categories: {
        $map: {
          input: {
            // 按一级子类别去重,合并二级子类别
            $reduce: {
              input: "$sub_category_entries",
              initialValue: [],
              in: {
                $let: {
                  vars: {
                    exists: {
                      $filter: {
                        input: "$$value",
                        cond: {
                          $and: [
                            { $eq: ["$$this.sub1_id", "$$current.sub1_id"] },
                            { $eq: ["$$this.sub1_name", "$$current.sub1_name"] }
                          ]
                        }
                      }
                    }
                  },
                  in: {
                    $cond: {
                      if: { $ne: [{ $size: "$$exists" }, 0] },
                      then: {
                        $map: {
                          input: "$$value",
                          as: "item",
                          in: {
                            $cond: {
                              if: {
                                $and: [
                                  { $eq: ["$$item.sub1_id", "$$current.sub1_id"] },
                                  { $eq: ["$$item.sub1_name", "$$current.sub1_name"] }
                                ]
                              },
                              then: {
                                $mergeObjects: [
                                  "$$item",
                                  {
                                    sub2_list: {
                                      $addToSet: {
                                        sub2_name: "$$current.sub2_name",
                                        sub2_id: "$$current.sub2_id",
                                        sub3_list: [{
                                          sub3_name: "$$current.sub3_name",
                                          sub3_id: "$$current.sub3_id"
                                        }].filter(x => x.sub3_name)
                                      }
                                    }
                                  }
                                ]
                              },
                              else: "$$item"
                            }
                          }
                        }
                      },
                      else: {
                        $concatArrays: [
                          "$$value",
                          [{
                            sub1_name: "$$current.sub1_name",
                            sub1_id: "$$current.sub1_id",
                            sub2_list: [{
                              sub2_name: "$$current.sub2_name",
                              sub2_id: "$$current.sub2_id",
                              sub3_list: [{
                                sub3_name: "$$current.sub3_name",
                                sub3_id: "$$current.sub3_id"
                              }].filter(x => x.sub3_name)
                            }].filter(x => x.sub2_name)
                          }]
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          as: "sub1",
          in: {
            sub_category_name_1: "$$sub1.sub1_name",
            sub_category_id_1: "$$sub1.sub1_id",
            sub_category_name_2: {
              $map: {
                input: "$$sub1.sub2_list",
                as: "sub2",
                in: {
                  sub_category_name_2: "$$sub2.sub2_name",
                  sub_category_id_2: "$$sub2.sub2_id",
                  sub_category_name_3: "$$sub2.sub3_list"
                }
              }
            }
          }
        }
      }
    }
  },
  // 4. 调整输出格式为期望结构
  {
    $project: {
      _id: 0,
      main_category_name: "$_id.main_category_name",
      main_category_id: "$_id.main_category_id",
      sub_categories: 1
    }
  },
  // 可选:按主类别名称排序
  {
    $sort: { main_category_name: 1 }
  }
])

关键说明:

  • 替换字段名:如果你的产品集合中子类别字段名不是sub_category_1_name、sub_category_1_id这类,需要将查询中对应的sub1_name、sub1_id等替换为实际字段名。
  • 空值处理:通过filter过滤掉未定义或空的子类别,确保空层级显示为数组。
  • 去重逻辑:使用$addToSet和$reduce实现各级子类别去重,避免重复条目。

内容的提问来源于stack exchange,提问作者Denys Medvediev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 04:10:12