2015-06-03 4 views
1

У меня есть два документа MongoDB. Я хочу, чтобы найти потенциал реальных и Барселону стадионов, предположив Реал имеет два стадиона (извините Merengues :)Массив встроенных документов - MongoDB

{ 
     "_id" : "Bar.43", 
     "official_name" : "Futbol Club Barcelona 
     "country" : "Spain", 
     "started_by" : { 
       "day" : 28, 
       "month" : 11, 
       "year" : 1899 
     }, 
     "stadium" : { 
       "name" : "Camp Nou", 
       "capacity" : 99354 
     }, 
     "palmarès" : { 
       "La Liga" : 23, 
       "Copa del Rey" : 27, 
       "Supercopa de Espana" : 11, 
       "UEFA Champions League" : 4, 
       "UEFA Cup Winners Cup" : 4, 
       "UEFA Super Cup" : 4, 
       "FIFA Club World cup" : 2 
     }, 
     "uniform" : "blue and dark red" 
}, 

{ 
     "_id" : "RMa.103", 
     "official_name" : "Real Madrid Club de Fùtbol 
     "country" : "Spain", 
     "started_by" : { 
       "day" : 6, 
       "month" : 3, 
       "year" : 1902 
     }, 
     "stadium" : [{ 
       "name" : "Santiago Bernabeu", 
       "capacity" : 85454 
     }, 
        { 
       "name" : "Vicente Calderon" 
       "capacity" : 54907 
     }], 
     "palmarès" : { 
       "La Liga" : 32, 
       "Copa del Rey" : 19, 
       "Supercopa de Espana" : 9, 
       "UEFA Champions League" : 10, 
       "UEFA Europa League" : 2, 
       "UEFA Super Cup" : 2, 
       "FIFA Club World cup" : 4 
     }, 
     "uniform" : "white" 
} 

Ну, мой запрос:

db.team.aggregate([{$group:{_id:"$country", capacityStadium:{$sum:"$stadium.capacity"}}}]) 

Но это не работает. Если в «Реале» есть только один стадион, вместо этого мой запрос работает. Итак, в общем случае, когда у меня есть массив встроенных документов, и я хочу использовать агрегаты, должен ли я использовать $ unwind для разделения документов этого массива? Проблема в полевом стадионе Барселоны - это не массив документов, и запрос получает сообщение об ошибке.

ответ

0

Возможно, вам потребуется изменить структуру документа, потому что поле stadium должно быть массивом для каждого документа. Для этого вам необходимо найти документы, где стадион не является массивом и обновить их с помощью «Bulk» операции для достижения максимальной эффективности

var bulk = db.team.initializeOrderedBulkOp(); 
var count = 0; 
db.team.find({ "stadium.0": { "$exists": false }}).forEach(function(doc) { 
    bulk.find({ "_id": doc._id }) 
     .updateOne({ "$set": { "stadium": [doc.stadium] }}); 
    count++; 
    if(count % 100 == 0) {  
    bulk.execute();  
    bulk = db.team.initializeOrderedBulkOp(); } }) 

if(count % 100 > 0) { 
    bulk.execute(); 
} 

Теперь использовать структуру агрегации.

db.team.aggregate(
    [ 
     { "$project": { "stadium.capacity": 1 }}, 
     { "$unwind": "$stadium" }, 
     { "$group": { "_id": "$_id", "totalCapacity": { "$sum": "$stadium.capacity" }}} 
    ] 
) 

Который возвращает:

{ "_id" : "RMa.103", "totalCapacity" : 140361 } 
{ "_id" : "Bar.43", "totalCapacity" : 99354 } 
Смежные вопросы