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

Sequelize嵌套结构中按orderMicrobial分组并聚合数量

问题需求

我希望简化Sequelize查询的返回结构,按照orderMicrobial中的字段进行分组,并对分组后的quantity字段求和,最终得到指定格式的结果。

期望结果

{
    "pendingInfo": [
        {
            "testTypeID": "1",
            "testType": "Breathing Air",
            "quantity": 5
        },
        {
            "testTypeID": "2",
            "testType": "Manufacturing",
            "quantity": 5
        },
        {
            "testTypeID": "3",
            "testType": "Microbial w/o spares",
            "quantity": 3
        },
        {
            "testTypeID": "3",
            "testType": "Microbial sealed pack",
            "quantity": 5
        },
        {
            "testTypeID": "3",
            "testType": "Microbial w/ spares",
            "quantity": 2
        }
    ]
}

当前返回结果

{
    "pendingInfo": [
        {
            "testTypeID": "1",
            "testType": "Breathing Air",
            "orders": [
                {
                    "quantity": 1,
                    "orderMicrobial": null
                },
                {
                    "quantity": 3,
                    "orderMicrobial": null
                },
                {
                    "quantity": 1,
                    "orderMicrobial": null
                }
            ]
        },
        {
            "testTypeID": "2",
            "testType": "Manufacturing",
            "orders": [
                {
                    "quantity": 5,
                    "orderMicrobial": null
                }
            ]
        },
        {
            "testTypeID": "3",
            "testType": "Microbial",
            "orders": [
                {
                    "quantity": 3,
                    "orderMicrobial": {
                        "hasSealedPlatePacks": null,
                        "hasSpares": null
                    }
                },
                {
                    "quantity": 4,
                    "orderMicrobial": {
                        "hasSealedPlatePacks": true,
                        "hasSpares": null
                    }
                },
                {
                    "quantity": 1,
                    "orderMicrobial": {
                        "hasSealedPlatePacks": true,
                        "hasSpares": null
                    }
                },
                {
                    "quantity": 2,
                    "orderMicrobial": {
                        "hasSealedPlatePacks": null,
                        "hasSpares": true
                    }
                }
            ]
        }
    ]
}

现有查询代码

const categorySummary = await TestType.findAll({
    include: [{
      model: Order,
      as: 'orders',
      include: [{
        model: OrderMicrobial,
        attributes: ['hasSealedPlatePacks', 'hasSpares']
      }],
      attributes: ['quantity']
    }],
    attributes: [
      ['testtypeID', 'testTypeID'],
      ['testtypeName', 'testType']
    ]
})

解决方案

方案一:通过Sequelize查询直接实现(推荐)

利用Sequelize的聚合函数和CASE语句,直接从数据库层面完成分组求和与类型名称映射:

const { sequelize } = require('./your-sequelize-instance'); // 替换为你的Sequelize实例路径

const pendingInfo = await Order.findAll({
    attributes: [
        ['testtypeID', 'testTypeID'],
        [
            sequelize.literal(`
                CASE
                    WHEN "orderMicrobial"."hasSealedPlatePacks" IS TRUE THEN 'Microbial sealed pack'
                    WHEN "orderMicrobial"."hasSpares" IS TRUE THEN 'Microbial w/ spares'
                    WHEN "TestType"."testtypeName" = 'Microbial' THEN 'Microbial w/o spares'
                    ELSE "TestType"."testtypeName"
                END
            `),
            'testType'
        ],
        [sequelize.fn('SUM', sequelize.col('quantity')), 'quantity']
    ],
    include: [
        {
            model: TestType,
            attributes: []
        },
        {
            model: OrderMicrobial,
            attributes: []
        }
    ],
    group: [
        'testtypeID',
        sequelize.literal(`
            CASE
                WHEN "orderMicrobial"."hasSealedPlatePacks" IS TRUE THEN 'Microbial sealed pack'
                WHEN "orderMicrobial"."hasSpares" IS TRUE THEN 'Microbial w/ spares'
                WHEN "TestType"."testtypeName" = 'Microbial' THEN 'Microbial w/o spares'
                ELSE "TestType"."testtypeName"
            END
        `)
    ],
    raw: true
});

const result = { pendingInfo };

方案二:查询后用JavaScript处理结果

如果数据库查询逻辑过于复杂,可先获取原始数据,再通过JS完成分组求和:

// 执行现有查询,开启raw和nest确保结构清晰
const categorySummary = await TestType.findAll({
    include: [{
      model: Order,
      as: 'orders',
      include: [{
        model: OrderMicrobial,
        attributes: ['hasSealedPlatePacks', 'hasSpares']
      }],
      attributes: ['quantity']
    }],
    attributes: [
      ['testtypeID', 'testTypeID'],
      ['testtypeName', 'testType']
    ],
    raw: true,
    nest: true
});

// 分组求和逻辑
const groupMap = new Map();
categorySummary.forEach(testType => {
    const baseID = testType.testTypeID;
    const baseName = testType.testType;

    testType.orders.forEach(order => {
        let displayName = baseName;
        if (baseName === 'Microbial') {
            const microbial = order.orderMicrobial;
            if (microbial?.hasSealedPlatePacks) {
                displayName = 'Microbial sealed pack';
            } else if (microbial?.hasSpares) {
                displayName = 'Microbial w/ spares';
            } else {
                displayName = 'Microbial w/o spares';
            }
        }
        const groupKey = `${baseID}-${displayName}`;
        if (groupMap.has(groupKey)) {
            groupMap.get(groupKey).quantity += order.quantity;
        } else {
            groupMap.set(groupKey, {
                testTypeID: baseID,
                testType: displayName,
                quantity: order.quantity
            });
        }
    });
});

const result = { pendingInfo: [...groupMap.values()] };

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 00:20:54