4

たくさんのmap_reduceチュートリアルを見つけましたが、それらのいずれにも「where」句が含まれていないか、ドキュメント/レコードを検討対象から除外する他の方法がないようです。私は一見簡単なクエリに取り組んでいます。タイムスタンプ、IPアドレス、キャンペーンIDを含むイベントの基本的なログファイルがあります。特定のキャンペーンについて、特定のタイムスタンプ範囲内のユニークユーザーの数を取得したいと思います。簡単そうですね!

次のようなクエリオブジェクトを作成しました。

{'ts': {'$gt': 1345840456, '$lt': 2345762454}, 'cid': '2636518'}

それで、私は2つのことを試しました。1つはdistinctを使用し、もう1つはmap_reduceを使用します。

明確

db.alpha2.find(query).distinct('ip').count()

mongoシェルでは、クエリを個別の関数の2番目のパラメーターとして配置でき、そこで機能しますが、pymongoではそれを実行できないことを読みました。

Map_reduce

map = Code("function () {"
        "    emit(this.ip, 1);"
        "}")
reduce = Code("function (key, values) {"
    "  var total = 0;"
    "  for (var i = 0; i < values.length; i++) {"
    "    total += values[i];"
    "  }"
    "  return total;"
    "}")

totaluniqueimp = db.alpha2.map_reduce(map, reduce, "myresults").count();

(reduce関数が不要なことを実行していることに気付きました。デモから取得しました)。これは正常に機能しますが、私の「どこ」のパラメータを使用しません。私はこれを試してみます:

totaluniqueimp = db.alpha2.find(query).map_reduce(map, reduce, "myresults").count();`

そして、私はこのエラーを受け取ります:

AttributeError: 'Cursor' object has no attribute 'map_reduce'

結論

基本的に、これは私がmysqlでやろうとしていることです:

select count(*) from records where ts<1000 and ts>900 and campaignid=234 group by ipaddress

とてもシンプルなようです!これをmongoでどのように行いますか?

更新:回答

以下のドミトリーの答えに基づいて、私は自分の解決策を解決(そして単純化)することができました(これは私がそれを作ることができるのと同じくらい簡単ですか?):

#query is an object that was built above this
map = Code("function () { emit(this.ip, 1);}")
reduce = Code("function (key, values) {return 1;}")
totaluniqueimp = collection.map_reduce(map, reduce, "myresults", query=query).count();

ありがとうドミトリー!

4

2 に答える 2

4

あなたはこれを使ってみることができます:

totaluniqueimp = db.alpha2.map_reduce(map, reduce, {
    out: "myresults",
    query: {'ts': {'$gt': 1345840456, '$lt': 2345762454}, 'cid': '2636518'}
}).count();

更新:上記のステートメントはmongoシェルで機能します。pymongoでは、4番目のパラメーターとしてクエリを追加する必要があります。

totaluniqueimp = db.alpha2.map_reduce(map, reduce, "myresults", query={'ts': {'$gt': 1345840456, '$lt': 2345762454}, 'cid': '2636518'})

詳細なドキュメントはここにあります。

于 2012-08-31T23:30:58.240 に答える
0

これがpymongoを介して可能かどうかはわかりませんが、マニュアルにはそうすべきであると記載されていますが、mongoDBシェルにはgroup()関数があり、質問のSQLを簡単に書き直すことができます。

select count(*) 
  from records 
 where ts<1000 
   and ts>900 
   and campaignid=234
 group by ipaddress;

として:

db. alpha2.group(
   { cond: { 'ts': {'$gt': 900, '$lt': 1000}, 'campaignid': '234' }
   , key: {  "ipaddress" : 1 }
   , initial: {count : 0}
   , reduce: function(doc, out){ out.count++}
   }
);
于 2012-11-15T17:14:10.710 に答える