使用Golang和MongoDB(mgo)进行嵌套数组聚合

3

我可以为您翻译以下形式的MongoDB数据:

{"_id":"53eb9a5673a57578a10074ec","data":{"statistics":{"gsm":[{"type":"Attacks","value":{"team1":66,"team2":67}},{"type":"Corners","value":{"team1":8,"team2":5}},{"type":"Dangerous attacks","value":{"team1":46,"team2":49}},{"type":"Fouls","value":{"team1":9,"team2":14}},{"type":"Free kicks","value":{"team1":18,"team2":10}},{"type":"Goals","value":{"team1":2,"team2":1}},{"type":"Goal kicks","value":{"team1":10,"team2":11}},{"type":"Offsides","value":{"team1":1,"team2":4}},{"type":"Posession","value":{"team1":55,"team2":45}},{"type":"Shots blocked","value":{"team1":4,"team2":1}},{"type":"Shots off target","value":{"team1":7,"team2":5}}]}}}

我想使用Golang MongoDB驱动程序mgo,当data.statistics.gsm.type ==“Attacks”时,获取数据.statistics.gsm.value.team1的平均值。 到目前为止,我尝试了以下代码(使用以下其中一个或两个组语句):

pipeline := []bson.M{
    bson.M{"$match": bson.M{"kick_off.utc.gsm.date_time": bson.M{"$gt": start, "$lt": end}}}, 
bson.M{
        "$group": bson.M{
            "_id":     "$gsm_id",
    "event_array" : bson.M{"$first": "$data.statistics.gsm"}}},
bson.M{
            "$group": bson.M{
                "_id":     "$type",
          "avg_attack" : bson.M{"$avg": "$data.statistics.gsm.value.team1"}}}}

仅使用第一个分组语句,我得到了以下结果,但第二个分组语句并不能帮助我得到平均值。

[{"_id":1953009,"event_array":[{"type":"Attacks","value":{"team1":48,"team2":12}},{"type":"Corners","value":{"team1":12,"team2":0}},{"type":"Dangerous attacks","value":{"team1":46,"team2":7}},{"type":"Fouls","value":{"team1":10,"team2":3}},{"type":"Free kicks","value":{"team1":5,"team2":12}},{"type":"Goals","value":{"team1":8,"team2":0}}
1个回答

3

我总是觉得将JSON格式化输出很有帮助。这是你从第一组语句中获得的内容:

[  
{  
"_id":1953009,
"event_array":[  
  {  
    "type":"Attacks",
    "value":{  
      "team1":48,
      "team2":12
    }
  },
  {  
    "type":"Corners",
    "value":{  
      "team1":12,
      "team2":0
    }
  },
...

现在你使用的是第二组语句:
"$group": bson.M{
     "_id":     "$type",
     "avg_attack" : bson.M{"$avg": "$data.statistics.gsm.value.team1"}
}

你试图在第一组语句的结果中取得data.statistics.gsm.value.team1的平均值,但是这个值在第一组语句的结果中并不存在,所以当然不会给你一个平均值。

我建议你使用$unwind运算符来将数组分解成一组文档,然后你应该能够按照你想要的方式进行分组,例如使用{$avg: "$value.team1"}

因此,用于生成聚合的整个流程如下:$match -> $group1 -> $unwind -> $group2。请记住,管道的每个阶段都在前一个阶段产生的数据上进行操作,这就是为什么你的data.statistics.gsm.value.team1部分是错误的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接