2

私の Rails+MongoId アプリケーションでは、統計目的でデータを集計する必要があります。私のモデルは、多くのバージョン (別名: バンドル) と相対的なユーザー アクティベーションを持つ一般的な Web アプリケーションを表現しています。

App = {
  "_id" : ObjectId("4ff2e2eab528571384000eb4"),
  "name" : "my app",
  "category_id": "4ff2e2eab528571384000cc0",
  "bundles": [{
    "_id" : ObjectId("4ff2e2eab528571384000dca"),
    "activations" : [{
      "user" : "user_0",
      "_id" : ObjectId("4ff2e2eab528571384000dd0")
     },
     ... 
  },
  ...
  ]
}

今、私がしなければならないことは、アプリケーション CATEGORY_ID ごとの ACTIVATIONS の数を返すことです。

results = [
  {
    "_id": "4ff2e2eab528571384000cc0",
    "value": 243
  },
  ...
]

この mapreduce 関数を使用して、CATEGORY_ID ごとの BUNDLES の総数を簡単に取得できます。

map = function() { 
  for (var bundle in this.bundles) { 
    emit(this.category_id, 1); 
  }
};
reduce = function(key, values) { 
  var sum = 0; 
  values.forEach(function(value) { 
    sum += value; 
  }); 
  return sum; 
};

しかし、1 レベル深く入力しようとすると、まったく結果が得られません。

map = function() { 
  for (var bundle in this.bundles) { 
    for (var activation in bundle.activations) {
      emit(this.category_id, 1); 
    }
  }
};
reduce = function(key, values) {
  var sum = 0; 
  values.forEach(function(value) { 
    sum += value;
  });
  return sum;
};

どんなアイデアでも大歓迎です。よろしくお願いします

マイク・コスタ

4

2 に答える 2

1

ヒントをありがとうNOMOA、

map 関数を次のように変更することで、問題を解決できます。

map = function() { 
  var len = this.bundles.length; 
  for (var i = 0; i < len; i++) {
    if (this.bundles[i].activations !== undefined) { 
      emit(this.category_id, this.bundles[i].activations.length);
    } 
  }
};

より伝統的な for..i++ を優先して for..in 構造を削除し、「未定義」チェックを追加する必要がありました (ご提案のとおり)。完全に機能します (二重ループも回避します)。

よろしく M.コスタ

于 2012-07-04T13:19:40.937 に答える
0

map reduce 関数が正しく実行されていると確信していますか?

bundle.activations が null でないかどうかを確認する必要があると思います。サーバー ログ内でエラーを確認します。また、サーバー ログを使用すると、デバッグ プリント ステートメントを表示できます。

于 2012-07-03T14:23:59.907 に答える