【问题标题】:Summing across arrays during aggregation pipeline在聚合管道期间跨数组求和
【发布时间】:2016-05-27 22:57:21
【问题描述】:

我有一个模型,其中包含几个相同固定大小的数组,我一直在尝试确定是否可以使用聚合管道对数组索引求和,但一直很难找到任何有用的东西.

例如:

{  
    label: "label1",

    A: [0, 0, 0],   
    B: [1, 1, 1],  
    C: [0, 0, 1],

    etc: ... ,
}

在投影期间需要生成以下求和数组,或者在管道下游对标签键进行分组时生成另一个类似数组:

{  
    Z: [1, 1, 2]  
}  

使用 Mongo 3.2,我可以展开数组并维护其索引,但我仍然不确定如何使用这些索引和值重建数组。

如果有人有任何想法或建议,那将意义重大。提前感谢您的任何回复。

【问题讨论】:

  • 数组的最大尺寸是多少?

标签: arrays mongodb mongoose


【解决方案1】:

如果数组很小(3x3 表示 9 次操作),可以使用 $slice 对数组进行切片,但展开它会为 3x3 数组生成 27 个文档,因此将它们连接回来是一种痛苦。

或者您可以使用 forEach 使用更简单的解决方案

var arraySize=3;
var a=[];
db.david.find({label:"label2"}).forEach(function(myDoc) {     
      for(var i=0;i<arraySize;i++){ 
          a[i]=myDoc.A[i]+myDoc.B[i]+myDoc.C[i];
      }
      })
 printjson( a )

编辑

我仍然不确定如何以更动态的方式解决这个问题 - 但这是一种针对 3 个数组的提议,每个数组包含 3 个元素。

var arraySumprojection = {
            $project : {
                col1 : {
                    $let : {
                        vars : {
                            a : {
                                "$arrayElemAt" : ["$A", 0]
                            },
                            b : {
                                "$arrayElemAt" : ["$B", 0]
                            },
                            c : {
                                "$arrayElemAt" : ["$C", 0]
                            },

                        },
                        in : {
                            $add : ["$$a", "$$b","$$c"]
                        }
                    }
                },

                col2 : {
                    $let : {
                        vars : {
                            a : {
                                "$arrayElemAt" : ["$A", 1]
                            },
                            b : {
                                "$arrayElemAt" : ["$B", 1]
                            },
                            c : {
                                "$arrayElemAt" : ["$C", 1]
                            },

                        },
                        in : {
                            $add : ["$$a", "$$b","$$c"]
                        }
                    }
                },
                col3 : {
                    $let : {
                        vars : {
                            a : {
                                "$arrayElemAt" : ["$A", 2]
                            },
                            b : {
                                "$arrayElemAt" : ["$B", 2]
                            },
                            c : {
                                "$arrayElemAt" : ["$C", 2]
                            },

                        },
                        in : {
                            $add : ["$$a", "$$b","$$c"]
                        }
                    }
                },
            }
        }
    ])

【讨论】:

  • 感谢您的洞察力!如果我的理解是正确的,则 forEach(...) 方法仅在聚合管道之后应用于游标,因此如果对数组求和是一个中间步骤,我将无法使用该方法。我会玩弄它,看看我是否有任何进展。
  • @DavidB 数组的最大大小是多少?
  • @DavidB 28*28?这可能很复杂
  • 每个文档都有 1 到大约 15 个这些 28 项数组,我正在尝试找出一种在保持索引的同时产生对其中一些数量求和的结果的好方法。我可能会选择使用每个索引的显式键重构数据,并在聚合管道期间以这种方式组合它们。
  • @DavidB - 这是一个不错的挑战 - 请查看我的更新 - 我希望这将指导您获得解决方案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-16
  • 2020-12-12
  • 1970-01-01
  • 2013-03-14
  • 2021-01-04
  • 2016-05-03
  • 2020-08-13
相关资源
最近更新 更多