2015-09-09 2 views
2

Я просмотрел несколько похожих вопросов/ответов, например. this one, но я не могу решить свой случай.Объединение MongoDB с несколькими ключами

У меня есть коллекция под названием output с документами вида

{ 
    "_id" : ObjectId("55e06ac3cd8a52ac141012f2"), 
    "Date" : ISODate("2010-11-02T00:00:00Z"), 
    "output" : 0, 
    "region" : "Gotham" 
} 

Эти документы охватывают несколько лет и регионы, я пытаюсь запустить агрегат, чтобы получить разбивку общего объема производства, в регионе, в год. Если я игнорирую год я могу получить первую часть с помощью этого

output.aggregate(
    [ 
     { "$group": { 
     "_id": { region: "$region"}, 
     "output": { "$sum": "$output" } 
     }} 
    ], 
    function(err,results) { 
     console.log(results); 
     db.close(); 
    } 
); 

, который дает мне

[ { _id: { region: 'Gotham' }, output: 2115715 }, 
    { _id: { region: 'London' }, output: 6799038 }, 
    { _id: { region: 'Tokyo' }, output: 8744809 } 

но выход здесь через несколько лет, я хочу, с разбивкой в ​​год.

Я попытался следующие, но это не работает

output.aggregate(
    [ 
    { 
     $project : { 
     year: { 
      $year: "$Date" 
     } 
     } 
    }, 
    { 
     "$group": { 
     "_id": { 
      region: "$region", 
      year: ""$year 
     }, 
     "output": { "$sum": "$output" } 
     } 
    } 
    ], 
    function(err,results) { 
    console.log(results); 
    db.close(); 
    } 
); 

это результаты в

[ { _id: { year: 2015 }, output: 0 }, 
    { _id: { year: 2014 }, output: 0 }, 
    { _id: { year: 2013 }, output: 0 }, 
    { _id: { year: 2012 }, output: 0 }, 
    { _id: { year: 2009 }, output: 0 }, 
    { _id: { year: 2008 }, output: 0 }, 
    { _id: { year: 2011 }, output: 0 }, 
    { _id: { year: 2010 }, output: 0 } ] 
+0

Что вы подразумеваете под * "не работает" *? – GolfWolf

+0

Возможно ли, что он терпит неудачу из-за неправильного цитирования '$ year'? – GolfWolf

+0

Обновленный вопрос, чтобы показать, почему он «не работает» –

ответ

2

агрегации Основная ошибка.

При использовании оператора конвейера, как $project того только значения, которые приходят через к следующему этапу трубопровода является только тех, кого вы specifiy явно. Поэтому ваша проблема заключается в том, что вы ссылаетесь на поля в $group, которые больше не существуют в документе, потому что вы «опустили их».

Итак, после $project, где вы не укажете «область», это поле больше не находится в документе, который будет обрабатываться на следующей стадии трубопровода, и это вызовет проблемы.

Основная поправка «включает их», но на самом деле, просто использовать оператор непосредственно в $group, как это более эффективно в любом случае:

output.aggregate(
    [ 
    { 
     "$group": { 
     "_id": { 
      "region": "$region", 
      "year": { "$year": "$Date" } 
     }, 
     "output": { "$sum": "$output" } 
     } 
    } 
    ], 
    function(err,results) { 
    console.log(results); 
    db.close(); 
    } 
); 

И это сделано

Think «Юникс труба» как это:

ps aux | grep mongo | grep something 

А если вы уже отфильтрованы «монго», то, если у вас не было «монго что-то» в результатах, то есть больше не больше «someth чтобы соответствовать. Это основной принцип «трубопроводов».

+0

Я задал вопрос в надежде, что вы ответите на него, помогая мне вчера. Это прекрасно работает, спасибо. Я не могу принять ответ правильно, однако, потому что еще 5 минут еще не закончилось –

+0

@robocode Я жду с наживкой. Попробуйте прочитать и «переварить» аналогию «unix pipe», которую я дал в конце. Это действительно дает понять, когда вы думаете об этом на минуту. –

+1

Это действительно так, я не рассматривал конвейер агрегации в этом контексте, я думаю, я должен был обратить внимание на словосочетание! –