首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Mongodb聚合-累积

Mongodb聚合-累积
EN

Stack Overflow用户
提问于 2018-10-20 11:57:25
回答 1查看 716关注 0票数 0

我有集合PurchaseOrder和嵌套数组PurchaseOrderLines,在PurchaseOrderLines中有两个字段ReceivingQtySendingQty

我想计算库存趋势(Group => ProductIDDateTotalReceivingQty-TotalSendingQty)的结果应该如下所示:

代码语言:javascript
复制
ProductID | TotalQty | SeqTotal | Date

1         | 5        | 5        | 01-01

1         | -2       | (5-2)=3  | 01-02

1         | 10       | (3+10)=13| 01-03

1         | -5       | (13-5)=8 | 01-04

我做过这件事

代码语言:javascript
复制
db.PurchaseOrder.aggregate(
  [       
    { "$unwind":"$PurchaseOrderLines"},
    {
      "$group": {
        "_id": {
          "Warehouse": "$Warehouse",
          "PurchaseOrderLines_ProductID": "$PurchaseOrderLines.ProductID",
          "WarehouseTypeID": "$WarehouseTypeID"
          ,"NowDate": "$NowDate"
        },
        "TotalReceivingQty":{"$sum":"$PurchaseOrderLines.ReceivingQty"},
        "TotalSendingQty":{"$sum":"$PurchaseOrderLines.SendingQty"},
        "GProductID":{"$first":"$PurchaseOrderLines.ProductID"}
      }
    },
    {
        "$lookup": {
               from: "Product",
               localField: "GProductID",
               foreignField: "ProductId",
               as: "product_doc_list"
             }
    },
    {
      "$project": {
        "ProductID": "$_id.PurchaseOrderLines_ProductID",
        "Product": {
            $map: {
              input: "$product_doc_list",
              as: "product_doc",
              in: "$$product_doc"
            }
        },
        "TotalQty": {"$subtract": ["$TotalReceivingQty", "$TotalSendingQty"]},
        "WarehouseTypeID": "$_id.WarehouseTypeID",
        "Warehouse": "$_id.Warehouse",
        "TotalReceivingQty":"$TotalReceivingQty",
        "TotalSendingQty":"$TotalSendingQty",
        "Date":"$_id.NowDate"
      }
    }
],{ allowDiskUse: true });

This应答使用$lookup进行自连接。但我不知道它是如何与数组一起工作的。

示例:

代码语言:javascript
复制
/* 1 */
{   
    "ProductID" : NumberDecimal("26.101"),
    "TotalQty" : NumberDecimal("52.000000"),
    "TotalReceivingQty" : NumberDecimal("52.000000"),
    "TotalSendingQty" : 0,
    /* need this property */
    "SeqTotal":sum(prev(SeqTotal),TotalQty)=NumberDecimal("52.000000"),
    "Date" : "01-01"
},

/* 2 */
{
    "ProductID" : NumberDecimal("26.101"),
    "TotalQty" : NumberDecimal("-1.000000"),
    "TotalReceivingQty" : 0,
    "TotalSendingQty" : NumberDecimal("1.000000"),
    /* need this property */
    "SeqTotal":sum(prev(SeqTotal),TotalQty)=52-1=>51,
    "Date" : "01-03"
},

/* 3 */
{
    "ProductID" : NumberDecimal("26.101"),
    "TotalQty" : NumberDecimal("1.000000"),
    "TotalReceivingQty" : NumberDecimal("1.000000"),
    "TotalSendingQty" : 0,
    /* need this property */
    "SeqTotal":sum(prev(SeqTotal),TotalQty)=51+1=>52,
    "Date" : "01-04  "
},

/* 4 */
{
    "ProductID" : NumberDecimal("26.101"),
    "TotalQty" : NumberDecimal("92.000000"),
    "TotalReceivingQty" : NumberDecimal("92.000000"),
    "TotalSendingQty" : 0,
    /* need this property */
    "SeqTotal":sum(prev(SeqTotal),TotalQty)=52+92=>144,
    "Date" : "01-17"
},

/* 5 */
{
    "ProductID" : NumberDecimal("26.101"),
    "TotalQty" : NumberDecimal("-96.000000"),
    "TotalReceivingQty" : 0,
    "TotalSendingQty" : NumberDecimal("96.000000"),
    /* need this property */
    "SeqTotal":sum(prev(SeqTotal),TotalQty)=144-96=>48,
    "Date" : "01-20"
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-22 07:19:02

好的!感谢@Veeram的评论,我最终得到了这个解决方案。

代码语言:javascript
复制
db.PurchaseOrder.aggregate(
    [    
        { '$unwind': '$PurchaseOrderLines'},
        {
            '$group': {
                    _id: {
                        'wh': '$Warehouse',
                        'pid': '$PurchaseOrderLines.ProductID',
                        'wht': '$WarehouseTypeID',
                        'dt': '$NowDate'
                    },
                    'trq':{'$sum': {$ifNull: [ '$PurchaseOrderLines.ReceivingQty', 0 ] }},
                    'tsq':{'$sum': {$ifNull: [ '$PurchaseOrderLines.SendingQty', 0 ] }}
            }
        },
        {
            '$sort': {
                 '_id.dt': 1
            }
        },
        {
            '$group': {
                '_id': {pid:'$_id.pid'},
                '_gp': { '$push': '$_id' },
                'totals': { '$push': {'$subtract': ['$trq', '$tsq']} }
            }
        },
        {
            '$unwind': {
                'path' : '$_gp',
                'includeArrayIndex' : 'index'
            }
        },
        {
        '$lookup': {
               from: 'Product',
               localField: '_id.pid',
               foreignField: 'ProductId',
               as: 'product_doc_list'
             }
        },
        {
            '$project': {
                '_id': 0,
                'Product': {
                    $map: {
                      input: '$product_doc_list',
                      as: 'product_doc',
                      in: '$$product_doc'
                    }
                 },
                 'WarehouseTypeID': '$_gp.wht',
                 'Warehouse': '$_gp.wh',
                 'TotalQty': { '$arrayElemAt': [ '$totals', '$index' ] },
                 'SeqTotal':{ '$sum': { '$slice': [ '$totals', { '$add': [ '$index', 1 ] } ] } },
                 'Date':'$_gp.dt'
            }
        }
    ],{allowDiskUse:true}
);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52905402

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档