【问题标题】:Need to sum from array object value in mongodb需要从 mongodb 中的数组对象值求和
【发布时间】:2018-03-26 12:14:13
【问题描述】:

如果该值存在,我正在尝试计算总值。但查询不能 100% 工作。所以有人可以帮我解决这个问题。这是我的示例文档。我附上了两份文件。请查阅这些文件并找出最佳解决方案 文件:1

{
    "_id" : 1"),
    "message_count" : 4,
    "messages" : {
        "data" : [ 
            {
                "id" : "11",
                "saleValue": 1000
            }, 
            {
                "id" : "112",
                "saleValue": 1400
            }, 
            {
                "id" : "22",

            }, 
            {
                "id" : "234",
                "saleValue": 111
            }
        ],

    },
    "createdTime" : ISODate("2018-03-18T10:18:48.000Z")
}

文档:2

 {
        "_id" : 444,
        "message_count" : 4,
        "messages" : {
            "data" : [ 
                {
                    "id" : "444",
                    "saleValue" : 2060
                }, 
                {
                    "id" : "444",
                }, 
                {
                    "id" : 234,
                    "saleValue" : 260
                }, 
                {
                    "id" : "34534",
                }
            ]
        },

        "createdTime" : ISODate("2018-03-18T03:11:50.000Z")
    }

需要的输出:

{
   total : 4831
}

我的查询:

db.getCollection('myCollection').aggregate([
    {
        "$group": {
            "_id": "$Id",

            "totalValue": {
                $sum: {
                    $sum: "$messages.data.saleValue"
                }
            }

        }
    }
])

所以请尽可能帮我解决这个问题。提前致谢

【问题讨论】:

  • data 数组上使用展开,然后对data.value 求和

标签: mongodb mongodb-query


【解决方案1】:

它无法正常工作,因为它正在聚合集合中的所有文档;您正在对常量 "_id": "tempId" 进行分组,您只需要通过添加 $ 来引用正确的键:

db.getCollection('myCollection').aggregate([
    { "$group": {
        "_id": "$tempId",
        "totalValue": { 
            "$sum": { "$sum": "$messages.data.saleValue" } 
        }
    } }
])

本质上是聚合操作的单阶段管道版本,具有一个额外的字段,该字段在组管道之前保存总和表达式,然后将该字段称为组中的$sum 运算符。

上述工作自 MongoDB 3.2+ 中的 $sum$project$group 阶段以及在 @ 中使用时都可用987654325@阶段,$sum返回表达式列表的总和。表达式"$messages.data.value" 返回一个数字列表[120, 1200],然后将其用作$sum 表达式:

db.getCollection('myCollection').aggregate([
    { "$project": {
        "values": { "$sum": "$messages.data.value" },
        "tempId": 1,
    } },
    { "$group": {
        "_id": "$tempId",
        "totalValue": { "$sum": "$values" }
    } }
])

【讨论】:

  • 您的查询在我的演示文档中运行良好。但不适用于我的实际。如果我将与您分享我的实际数据,您可以检查一下吗??
  • 我已经更新了我的问题。请检查并帮助我弄清楚。
  • 它失败了,因为"saleValue" 是一个字符串,而不是一个数字。 $sum 不适用于字符串值,请在运行管道之前尝试将字段转换为数值。
  • 只需要 pageId 作为 _id & total。
  • 但查询不能 100% 工作 请显示您得到的结果以及您正在使用的查询。您还在 $group 管道步骤中使用 "_id": "pageId", 吗?如果是这样,您需要将其更改为指向正确的键,例如"_id": "$pageId",如果您关注的话,如上述答案中所述。还要检查您的 MongoDB 服务器版本是否 >= 3.2。
【解决方案2】:
db.getCollection('myCollection').aggregate([
   {
     $unwind: "$messages.data",
     $group: {
        "_id": "tempId",
        "totalValue": { $sum: "$messages.data.value" }
     }
   }
])

$unwind

【讨论】:

    【解决方案3】:

    根据上述问题的描述,作为解决方案,请尝试执行以下聚合查询

    db.myCollection.aggregate(
    
        // Pipeline
        [
            // Stage 1
            {
                $unwind: {
                    path: '$messages.data'
                }
            },
    
            // Stage 2
            {
                $group: {
                    _id: {
                        pageId: '$pageId'
                    },
                    total: {
                        $sum: '$messages.data.saleValue'
                    }
                }
            },
    
            // Stage 3
            {
                $project: {
                    pageId: '$_id.pageId',
                    total: 1,
                    _id: 0
                }
            }
    
        ]
    
    
    );
    

    【讨论】:

      【解决方案4】:

      你可以在你的$group之前添加一个$unwind,这样你就可以解构数据数组,然后你就可以正确分组了:

      db.myCollection.aggregate([
      {
          "$unwind": "$messages.data"
      },
      {
          "$group": {
              "_id": "tempId",
              "totalValue": {
                  $sum: {
                      $sum: "$messages.data.value"
                  }
              }
          }
      }
      ])
      

      输出:

      { "_id" : "tempId", "totalValue" : 1320 }
      

      【讨论】:

        猜你喜欢
        • 2021-05-29
        • 2016-09-05
        • 2023-04-04
        • 2021-03-05
        • 2021-08-09
        • 1970-01-01
        • 2017-02-12
        • 1970-01-01
        • 2019-09-01
        相关资源
        最近更新 更多