【问题标题】:Query Mongodb Sum of firsts element of an array of objects查询对象数组的第一个元素的Mongodb总和
【发布时间】:2020-02-29 01:46:42
【问题描述】:

我想为我的数据库的每个元素编写一个查询,对数组中第一个对象的每个字段 payment 求和。

架构如下:

var schema = new Schema({
    plate : String,
    category : String,
    brand : String,
    model : String,
    sign : String,

    tax : [{
        date : { type: Date, default: Date.now },
        payment : { type: Number, default: 0 },
    }],


});

我为我的查询编写了以下函数:

function(callback){     
        Machine.aggregate(
            [
                {$unwind: "$tax"},
                {$group : {
                    _id : null ,
                    tot : { $sum: "$tax.payment"}
                }}
            ]
        ,callback);
    }

但是通过这种方式,我检索了数组 tax 中所有付款的总和。我的目标是只取第一个,所以我尝试使用$tax.0.payment 并使用arrayElemAt : [$tax,0],但我所有的试验都给出了 tot = 0。

【问题讨论】:

  • arrayElemAt 是解决此问题的一种正确方法。我已经发布了基于此的答案..检查是否可以解决它。

标签: arrays mongodb mongoose aggregation-framework


【解决方案1】:

像这样在你的聚合中添加 $arrayElemAt..

Machine.aggregate(
        [
            {$unwind: "$tax"},
            {$group : {
                _id : null ,
                tot : { $sum:  { $arrayElemAt : [ "$tax.payment", 0  ]}
            }}
        ]
    ,callback);

【讨论】:

  • 这会导致错误的结果,大多数情况下 tot 将是 0。因为 tax.payment 首先不是一个可以使用的数组(根据 OP)。
【解决方案2】:

这里的想法是通过 $arrayElemAt 用投影选择每个 payment 数组字段的第一个元素,然后对字段 $group $sum 进行分组求和。

查询:

db.collection.aggregate([
  {
    $project: {
      firstPayment: {
        $arrayElemAt: [
          "$tax",
          0
        ]
      }
    }
  },
  {
    $group: {
      _id: null,
      PaymentSum: {
        $sum: "$firstPayment.payment"
      }
    }
  }
]);

演示 O/P:

[
  {
    "PaymentSum": 11,
    "_id": null
  }
]

【讨论】:

    【解决方案3】:
    Machine.aggregate({$unwind: 
            {path: "$tax"}
        },
        {$group:{
             _id: "$_id",
             payment: {$first: "$tax.payment"}
        }},
        {$group: {
            _id: null,
            total: {$sum: "$payment"}
        }}
    )
    

    说明:

    首先我在税收上使用了$unwind,然后在第一个$group stage中我根据_id对它们进行了分组,

    这样我就可以从 unwinded tax 数组中获取第一笔付款信息。

    然后我使用 $sum 将它们添加到第二个 $group stage

    我用这些数据进行了测试:

    机器集合文档:

    {
        "_id" : ObjectId("5dbf09a4d7912bcbc61ee9e4"),
        "tax" : [
            {
                "payment" : 10
            },
            {
                "payment" : 20
            }
        ]
    },
    {
        "_id" : ObjectId("5dbf09aad7912bcbc61ee9e5"),
        "tax" : [
            {
                "payment" : 30
            },
            {
                "payment" : 40
            }
        ]
    },
    {
        "_id" : ObjectId("5dbf09afd7912bcbc61ee9e6"),
        "tax" : [
            {
                "payment" : 50
            },
            {
                "payment" : 60
            }
        ]
    }
    

    我得到的结果是:

    { "_id" : null, "tot" : 90 }
    

    我希望这能满足您的要求。

    【讨论】:

      猜你喜欢
      • 2013-10-11
      • 2015-04-25
      • 2019-09-20
      • 2018-05-04
      • 2021-10-14
      • 2022-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多