2014-11-13 4 views
2

у меня есть данные MongoDB в следующей форме:Golang MongoDB (MgO), агрегация с вложенными массивами

{"_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}}]}}} 

Я хочу, чтобы получить среднее data.statistics.gsm.value.team1 когда data.statistics.gsm .type == «Атаки» с использованием драйвера Golang MongoDB mgo. Код я пытался до сих пор (или с одним или оба заявления группы ниже):

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

Мне всегда полезно найти красивый вид на 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 operator, чтобы разбить массив на набор документов, тогда вы сможете сгруппировать их так, как вы пытаетесь здесь, с помощью {$avg: "$value.team1"} ,

Таким образом, общий трубопровод, используемый для создания агрегации, будет: $match -> $group1 -> $unwind -> $group2. Просто имейте в виду, что каждая фаза трубопровода работает с данными, полученными на предыдущем этапе, поэтому ваша часть data.statistics.gsm.value.team1 была неправильной.

Смежные вопросы