3

私はMongoDBにかなり慣れていませんが、長年のMySQL担当者であり、小さな障害に直面しています。

以下のサンプル データの場合:
TeamID Day OrderAmount
100 4/1 50
100 4/1 40
200 4/2 50
100 4/2 20

チームの 1 日あたりの平均注文額を見つけようとしています。mapReduce 関数を使用して簡単なクエリを実行し、TeamId と Day を使用してグループ化することができます。だから今私は持っています:

TeamID 日 平均金額
100 4/1 45
200 4/2 50
100 4/2 20

今、私はそのデータをロールアップして、チームごとの 1 日あたりの平均注文額を取得しようとしています。これは次のようになります。

日平均金額
4/1 47.5
4/2 35

これは MySQL で簡単に行うことができますが、MongoDB で行うのではなく、アプリ側で手動で行わずに MongoDB でこれを行う方法を理解するのに苦労しています。

4

2 に答える 2

4

これらの集計は、map-reduceまたはgroup()関数のいずれかを使用して計算できます。group()を使用しているのは、少し単純で高速だからですが、シャーディングされたクラスターにクエリを分散する必要がある場合は、map-reduceを使用する必要があります。

最初にデータをロードします。

db.orders.insert( { teamid: 100, date: "4/1", amount: 50 })
db.orders.insert( { teamid: 100, date: "4/1", amount: 40 })
db.orders.insert( { teamid: 200, date: "4/2", amount: 50 })
db.orders.insert( { teamid: 100, date: "4/2", amount: 20 })

チームごと、1日あたり:

db.orders.group({
    key: { teamid: true, date: true },
    reduce: function(doc, out) { out.sum += doc.amount; out.count++; },
    initial: { sum: 0, count: 0 },
    finalize: function(out) { out.average = out.sum / out.count }
});

日次集計をロールアップするには、キーを変更するだけです。

db.orders.group({
    key: { date: true },
    reduce: function(doc, out) { out.sum += doc.amount; out.count++; },
    initial: { sum: 0, count: 0 },
    finalize: function(out) { out.average = out.sum / out.count }
});
于 2011-05-21T01:42:53.477 に答える
0

少し調査した後、解決策を思い付くことができました。MongoDB と map/reduce の考え方が初めてであるため、これが最も最適化されたソリューションであることに満足していません。他の誰かがより良いものを持っている場合は、私を修正してください。具体的には、arr_team オブジェクトの長さを取得できなかったため、インクリメントするカウンターを用意する必要がありました。

リデュース機能:


    function(doc, prev) { 
      var retVal  = {team_count: 0, day_total: 0};

      if(!prev.arr_team[doc.team_id]) {
        prev.arr_team[doc.team_id] = 0;
        prev.team_count++;
      }

      prev.arr_team[doc.team_id]++;

      prev.order_count++; 
      if(doc.total_amount)
         prev.total_amount += doc.total_amount 

      return retVal;
    }

ファイナライズ:


function(out) {
      out.avg_team_order_amount = out.total_amount/out.team_count;
    }
于 2011-05-22T19:26:02.173 に答える