MongoDB 如何实现子文档分组汇总

MongoDB作为当前最流行的非关系型数据库,能通过嵌套子文档,实现一对多的关联关系。应用开发中,常会遇到对嵌套子文档结构的记录,进行分组汇总,如有数据:

{
"warehouseNsId":"10","brandId":37,
"financeOwnerId":1231882808817905665,"amount":0,
"items":[
 {"goodsNsId":"1353","price":"256.00","count":3},
 {"goodsNsId":"1799","price":"254.80","count":6},
 {"goodsNsId":"1353","price":"256.00","count":10}
   ]
  },{
  "warehouseNsId":"15","brandId":35,
"financeOwnerId":1231882808817905600,"amount":0,
"items":[
 {"goodsNsId":"1327","price":"238.00","count":17},
 {"goodsNsId":"1539","price":"154.80","count":25},
 {"goodsNsId":"1327","price":"238.00","count":13},
 {"goodsNsId":"1539","price":"154.80","count":15}
  ]},
  ...
按每条记录的 items.goodsNsId 分组,对 items.count 求和,希望结果如下:
{
"warehouseNsId":"10","brandId":37,
"financeOwnerId":1231882808817905665,"amount":0,
"items":[
 {"goodsNsId":"1353","price":"256.00","count":13},
 {"goodsNsId":"1799","price":"254.80","count":6}
  ]
  },
...

用 MongoDB 脚本实现思路,可用 MapReduce 对每条记录的子记录进行分组求合,然后把得到的中间结果与源数据关联结合,实现过程比较麻烦。

使用集算器, 可将每条记录的子文档分组求和,再将汇总结果赋值给子文档,实现比较容易。
1、编写脚本 warehouse.dfx


A B
1 =mongo_open("mongodb://localhost:27017/cata") / 连接 mongodb
2 =mongo_shell(A1,"warehouse.find(,{_id:0})").fetch() / 获取 warehouse 集合
3 >A2.run(items=(items.groups(goodsNsId;   price, sum(count):count))) / 子文档分组求和结果赋值给子文档
4 >A1.close() / 关闭连接
  2、调试执行一下,可看到格值 A2 为:
A2 warehouseNsId brandId financeOwnerId amount items

10 37.0 1.23188280881790566E18 0.0 [[1353, 256.00, 3....]]
15 35.0 1.23188280881790566E18 0.0 [[1327, 238.00, 17...]]


  3、执行脚本返回结果:
A2 warehouseNsId brandId financeOwnerId amount items

10 37.0 1.23188280881790566E18 0.0 [1353, 1799]
15 35.0 1.23188280881790566E18 0.0 [1327,   1539]


点击序表首行记录字段 items 展开得:
goodsNsId price count
1353 256.00 13.0
1799 254.80 6.0

A3:run() 函数对每条记录的子文档分组求和,把计算结果再赋值给子记录