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

MongoDB聚合查询如何返回指定扁平化三品牌厂商结构JSON响应

实现方案

优先推荐简化聚合逻辑、在应用层做格式转换的方案,代码可读性更高,后续调整字段更方便,不需要写复杂的MongoDB聚合语法。

方案1:简化聚合+应用层格式转换(推荐)

调整点说明

  • 移除原聚合中多余的$group阶段:原分组逻辑不仅容易因为_id取值问题出现分组异常,还额外增加了数据嵌套层级,直接在匹配、排序、取前3条之后拿到原始文档列表即可。
  • 公共字段直接从第一条返回文档提取:因为$match阶段已经限定了generic_name/form_name/dose_size三个筛选条件,返回的3条文档这几个字段值完全一致,不需要通过聚合的$first取值。
  • 遍历3条品牌数据,按顺序拼接品牌名(厂商名)字符串,赋值给对应序号的brand_name_x字段,完成扁平化映射。

完整调整后代码

getFilterData: function (req, res, next) {
    console.log('Itemfilterlist getAll ');
    const agg = [
        {'$match': {
            'generic_name': req.body.generic_name,
            'form_name': req.body.form_name,
            'dose_size': req.body.dose_size
        }},
        {'$sort': {'mrp': 1}},
        {'$limit': 3}
    ]

    MasterModel.aggregate(agg, function (err, arrList) {
        if (err) {
            return next(err);
        }
        const filterlist = []
        // 无匹配数据直接返回空列表
        if (arrList && arrList.length > 0) {
            const baseInfo = arrList[0]
            const formattedRes = {
                id: 1,
                molecule: baseInfo.generic_name,
                form: baseInfo.form_name,
                strength: baseInfo.dose_size,
                sub_category: baseInfo.subcategory_name
            }
            // 按排序顺序拼接品牌字段
            arrList.forEach((item, idx) => {
                formattedRes[`brand_name_${idx + 1}`] = `${item.brand_name}(${item.manufacturer_name})`
            })
            filterlist.push(formattedRes)
        }
        res.json({ filterList: filterlist })
    });
},

方案2:聚合层直接完成格式转换(不推荐)

如果需要完全在MongoDB聚合阶段完成格式映射,可以保留$group阶段,通过$concat拼接品牌和厂商字符串,再通过$replaceRoot+$arrayElemAt把数组项拆成独立字段,聚合写法如下:

const agg = [
    {'$match': {
        'generic_name': req.body.generic_name,
        'form_name': req.body.form_name,
        'dose_size': req.body.dose_size
    }},
    {'$sort': {'mrp': 1}},
    {'$limit': 3},
    {'$group': {
        _id: null,
        generic_name: {$first: "$generic_name"},
        form_name: {$first: "$form_name"},
        dose_size: {$first: "$dose_size"},
        subcategory_name: {$first: "$subcategory_name"},
        brands: {$push: {$concat: ["$brand_name", "(", "$manufacturer_name", ")"]}}
    }},
    {'$replaceRoot': {
        newRoot: {
            id: 1,
            molecule: "$generic_name",
            form: "$form_name",
            strength: "$dose_size",
            sub_category: "$subcategory_name",
            brand_name_1: {$arrayElemAt: ["$brands", 0]},
            brand_name_2: {$arrayElemAt: ["$brands", 1]},
            brand_name_3: {$arrayElemAt: ["$brands", 2]}
        }
    }}
]

注意:该方案如果匹配到的结果不足3条,对应序号的brand_name_x字段会返回null,需要额外做兼容处理。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 23:16:31