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

MongoDB聚合$facet结果合并问题:按insuredId统计理赔数据

问题:MongoDB聚合$facet结果合并实现理赔统计

定义的理赔类型

type TClaim = {
  insuredId: number,
  treatmentInfo: { amount: number }[]
}

原始理赔数据

[
  {
    insuredId: 1,
    treatmentInfo: [{amount: 1}, {amount: 2}]
  },
  {
    insuredId: 1,
    treatmentInfo: [{amount: 3}, {amount: 4}]
  },
  {
    insuredId: 2,
    treatmentInfo: [{amount: 1}, {amount: 2}]
  }
]

期望统计结果

[
  {insuredId: 1, numberOfClaims: 2, amount: 10},
  {insuredId: 2, numberOfClaims: 1, amount: 3}
]

当前使用的$facet管道

$facet: {
  totalClaims: [
    { 
      $group: { 
        _id: '$insuredId', 
        totalClaims: { $count: {} } 
      } 
    }
  ],
  amount: [
    { $unwind: { path: '$treatmentInfo'}},
    { 
      $group: {  
        _id: '$insuredId', 
        amount: { $sum: '$treatmentInfo.amount' }
      }
    }
  ]
}

解决方案:合并$facet分支结果

要合并两个$facet分支的统计结果,需在$facet之后添加以下聚合阶段:

完整聚合管道

db.claims.aggregate([
  {
    $facet: {
      totalClaims: [
        { 
          $group: { 
            _id: '$insuredId', 
            totalClaims: { $count: {} } 
          } 
        }
      ],
      amount: [
        { $unwind: { path: '$treatmentInfo' } },
        { 
          $group: {  
            _id: '$insuredId', 
            amount: { $sum: '$treatmentInfo.amount' }
          }
        }
      ]
    }
  },
  {
    $zip: {
      inputs: ['$totalClaims', '$amount'],
      useLongestLength: true // 兼容某分支缺失数据的场景
    }
  },
  { $unwind: '$zip' },
  {
    $replaceRoot: {
      newRoot: { $mergeObjects: ['$$zip.0', '$$zip.1'] }
    }
  },
  {
    $project: {
      _id: 0,
      insuredId: '$_id',
      numberOfClaims: '$totalClaims',
      amount: 1
    }
  },
  {
    $match: {
      insuredId: { $exists: true },
      numberOfClaims: { $exists: true },
      amount: { $exists: true }
    }
  }
])

关键步骤说明

  • $zip:将totalClaims和amount两个数组的元素按位置一一配对,生成包含两个统计对象的子数组。useLongestLength参数确保即使某分支存在遗漏的insuredId,另一分支的数据仍能被保留。
  • $unwind:将$zip生成的配对数组展开为单个文档,每个文档对应一组同被保险人的两类统计数据。
  • $replaceRoot + $mergeObjects:将配对的两个统计对象合并为一个文档,此时文档包含_id(对应insuredId)、totalClaims和amount字段。
  • $project:重构文档结构,将_id重命名为insuredId,totalClaims重命名为numberOfClaims,同时移除原始_id字段。
  • $match:过滤可能存在的不完整文档,确保最终结果的每个文档都包含所有必填字段。

内容的提问来源于stack exchange,提问作者Nguyễn Đức Hiếu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 20:31:04