2015-12-08 4 views
1

У меня есть база данных команд с вложенными игроками, как показано ниже:MongoDB - вычисление среднего вложенного массива атрибутов объектов

{ 
team_id: "eng1", 
date_founded: new Date("Oct 04, 1896"), 
league: "Premier League", 
points: 62, 
name: "Manchester United", 
players: [ { p_id: "Rooney", goal: 85, caps: 125, age: 28 }, 
      { p_id: "Scholes", goal: 15, caps: 225, age: 28 }, 
      { p_id: "Giggs", goal: 45, caps: 359, age: 38 } ] 
} 

Я пытаюсь вычислить средний возраст каждой команды (в среднем всех возрастов игроков), однако я не могу правильно получить значения $ player.age.

cursor = db.teams.aggregate({ 
    $group : { _id: "$name", avgAge : { 
    $avg : "$players.age" } 
    } 
}); 

Это просто возвращает следующее:

{ 
    { "_id": "AC Milan", avgAge: 0 }, 
    { "_id": "Barcelona", avgAge: 0 } 
    { "_id": "Real Madrid", avgAge: 0 } 
    ... 
} 

(The игроков возрасты все определенно есть)

Любая помощь?

+0

У вас есть опечатка. В вашем документе говорится «игроки», но ваш запрос говорит «игрок» –

+0

извините, опечатка была только в вопросе не в вопросе. все тот же результат с '" $ players.age "' – Rich131

ответ

4

Поскольку поле players является массивом, попытка доступа к его члену с $players.age слишком запутанна, mongo не знает, к какому элементу массива вы хотите получить доступ. Затем придет $unwind на помощь, он заставит каждый элемент массива стать встроенным элементом поля players. Если вы $unwind с документом «Манчестер Юнайтед», у вас будет что-то вроде этого

{ "_id" : ObjectId("5666fbbd755e59eab7a3e05e"), "team_id" : "eng1", "date_founded" : ISODate("1896-10-03T17:00:00Z"), "league" : "Premier League", "points" : 62, "name" : "Manchester United", "players" : { "p_id" : "Rooney", "goal" : 85, "caps" : 125, "age" : 28 } } 
{ "_id" : ObjectId("5666fbbd755e59eab7a3e05e"), "team_id" : "eng1", "date_founded" : ISODate("1896-10-03T17:00:00Z"), "league" : "Premier League", "points" : 62, "name" : "Manchester United", "players" : { "p_id" : "Scholes", "goal" : 15, "caps" : 225, "age" : 28 } } 
{ "_id" : ObjectId("5666fbbd755e59eab7a3e05e"), "team_id" : "eng1", "date_founded" : ISODate("1896-10-03T17:00:00Z"), "league" : "Premier League", "points" : 62, "name" : "Manchester United", "players" : { "p_id" : "Giggs", "goal" : 45, "caps" : 359, "age" : 38 } }` 

Поля players указанного документа есть 3 элемента, так что вы будете иметь 3 документы с тем же свойством, как и оригинал документ, но элемент в массиве переместился вверх, чтобы появился встроенный документ players. Тогда доступ к возрасту игрока легко с $players.age, потому что его встроенный документ.

Окончательный запрос

cursor = db.teams.aggregate([ 
    { $unwind: "$players" }, 
    { $group : { _id: "$name", avgAge : { $avg : "$players.age" } } } 
]); 
+0

Работал отлично, спасибо. Я посмотрю на '$ unwind' – Rich131

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