3

MongoDB データベース コレクションの 1 つで単純な map/reduce 関数を作成しようとしています。データを取得しましたが、間違っているようです。地図の部分がわかりません。このように IF/ELSE を使用できますか?

アップデート

ファイルを所有している作成者の数を取得したい。つまり、アップロードされたファイルを所有している作成者の数と、ファイルを所有していない作成者の数です。

コレクション内のオブジェクトは次のようになります。

{
    "_id": {
        "$id": "4fa8efe33a34a40e52800083d"
    },
    "file": {
        "author": "john",
        "type": "mobile",
        "status": "ready"
    }
}

map / reduce は次のようになります。

$map = new MongoCode ("function() {

if (this.file.type != 'mobile' && this.file.status == 'ready') {

 if (!this.file.author) {

  return;

 }

 emit (this.file.author, 1);

}

}");

$reduce = new MongoCode ("function( key , values) {

 var count = 0;

 for (index in values) {

  count += values[index];

 }

 return count;

}");

$this->cimongo->command (array (

 "mapreduce" => "files",  

 "map"       => $map,   

 "reduce"    => $reduce,  

 "out"       => "statistics.photographer_count"

)

);
4

2 に答える 2

1

私はあなたのマップを試して、モンゴシェルで減らしたところ、正しい(合理的に見える)結果が得られました。

あなたがしていることを行うことができるもう1つの方法は、マップ内の内部の「if」条件を取り除き、適切なクエリ句でmapreduce関数を呼び出すことです。次に例を示します。

db.files.mapreduce(map,reduce,{out:'outcollection', query:{"file.author":{$exists:true}}})

または、クエリを効率的にするためにたまたまインデックスがある場合は、すべての if を取り除き、句を指定して mapreduce を実行しquery:{"file.author":{$exists:true},"file.type":"mobile","file.status":"ready"}ます。合計したい実際のケースに一致するように条件を変更します。

2.2 (現在 rc0 として利用可能な次期バージョン) では、map/reduce 関数を記述する代わりに、このタイプのクエリに集計フレームワークを使用できます。

于 2012-07-21T19:31:11.113 に答える
1

地図の部分は大丈夫そうです。reduce 部分を少し変更します。

values.forEach(function(v) {
  count += v;
}

loop を使用して配列を反復するべきではありません。これは意図されたものではありません。for inオブジェクトのプロパティを列挙するためのものです。詳しい説明はこちら。

なぜあなたのデータは間違っていると思いますか? ソースデータは何ですか? あなたは何を得ますか?あなたは何を得ることを期待していますか?

于 2012-07-20T10:03:50.520 に答える