最后一个数组元素的总和

时间:2018-05-09 02:03:33

标签: arrays mongodb mongodb-query aggregation-framework

场景:我必须汇总银行特定分行中所有客户的最新余额

要汇总的mongo中的文档

{
    "_id" : {
        "AccountNumber" : "123",
        "branchId" : "AXC",
        "@objectName" : "AccountBalance"
    },
    "Versions" : [ 
        {
            "value" : NumberDecimal("96562.88"),
            "version" : NumberLong(1)
        },
            {
            "value" : NumberDecimal("9612.88"),
            "version" : NumberLong(2)
        }
    ]
}

我尝试过此操作但返回结果0

db.getCollection('AccountInfo').aggregate([
  { "$project": { "Versions": { "$slice": [ "$Versions", -1 ] } } },
  { "$match": {    
    "_id.@objectName" : "AccountBalance",
  }},
  { "$group": { "_id": "$_id.branchId", "total": { "$sum": "$Versions.value" } } },
  { "$sort": { "total": -1 } }
])

感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

你并不遥远,你真正想要的操作是$arrayElemAt,而不是

db.getCollection('AccountInfo').aggregate([
  { "$match": { "_id.@objectName" : "AccountBalance" }},
  { "$group": {
    "_id": "$_id.branchId",
    "total": { 
      "$sum": {
        "$arrayElemAt": [ "$Versions.value", -1 ]
      }
    }
  }},
  { "$sort": { "total": -1 } }
])

$slice会返回一个“数组”,因此您仍然需要$sum元素:

db.getCollection('AccountInfo').aggregate([
  { "$match": { "_id.@objectName" : "AccountBalance" }},
  { "$group": {
    "_id": "$_id.branchId",
    "total": { 
      "$sum": {
        "$sum": { "$slice": [ "$Versions.value", -1 ] }
      }
    }
  }},
  { "$sort": { "total": -1 } }
])

但是,当你真正想要的时候,获得单个元素通常会更好。只使用$slice实际上意味着“多个”数组元素。

如果您不确定"version"是“最后”数组项,那么您可以与$indexOfArray$max匹配:

db.getCollection('AccountInfo').aggregate([
  { "$match": { "_id.@objectName" : "AccountBalance" }},
  { "$group": {
    "_id": "$_id.branchId",
    "total": { 
      "$sum": {
        "$arrayElemAt": [
          "$Versions.value",
          { "$indexOfArray": [
            "$Versions.version",
            { "$max": "$Versions.version" }
          ]}
        ]
      }
    }
  }},
  { "$sort": { "total": -1 } }
])

首先学会“永远”$match而不是$project元素,你可以在$group内“内联”做同样的事情。这使您的查询更有效率。

所有返回相同的结果:

{ "_id" : "AXC", "total" : NumberDecimal("9612.88") }

答案 1 :(得分:1)

如果Versions数组可以按任意顺序包含记录,那么如果最后一个元素的versions.value小于任何前一个元素,则聚合可能不正确(简而言之,如果versions数组在versions.value上没有顺序字段,最后一个元素不会给出正确的答案)。以下聚合不依赖于数组元素的位置,而是根据组合键,帐号和branchid的versions.value字段对数组元素进行排序。

$("#next_button").on("click", function(e){

    e.preventDefault();

    var form = $("#upload_files")[0];
    var data = new FormData(form);

    //Taking this variable on php with $_POST or $_REQUEST
    data.append("step", 1);
    data.append("file1", 1);
    data.append("file2", 2);
    data.append("file3", 3);
    data.append("max", 1);

    $.ajax({
      type: "POST",
      url: "upload.php",
      data: data,
      processData: false,
      contentType: false,
      cache: false,
      success: function(data) {
        alert(data);
      }
    });// end ajax

});// end next button