0

私はこのようなエントリのコレクションを持っています:

db.mesh_captors.save({'arduino': 0xCB, 'pin': 14, 'value': 35, 'date': datetime.utcnow()})
db.mesh_captors.save({'arduino': 0xCB, 'pin': 14, 'value': 63, 'date': datetime.utcnow()})
db.mesh_captors.save({'arduino': 0xCB, 'pin': 15, 'value': 126, 'date': datetime.utcnow()})
db.mesh_captors.save({'arduino': 0x7B, 'pin': 14, 'value': 121, 'date': datetime.utcnow()})

arduinoの各ピンの最後の値を取得したい。MySQLを使用すると、私はこれを書いたでしょう:

SELECT DISTINCT pin, value
FROM mesh_captors
WHERE arduino = 203
GROUP_BY pin
ORDER BY date DESC

しかし、MongoDBを使用しているので、その方法がよくわかりません。

私はこのようなことを試みましたが、それで十分ですか?

reducer = Code("""
              function (doc, out) {
                  if(out.date == 0 || out.date < doc.date) {
                       out.date = doc.date;
                       out.value = doc.value;
                  }
              }
              """)

captors_value = db.mesh_captors.group(key=['pin'], condition={'arduino': int(arduino_id)}, reduce=reducer, initial={'date': 0})

今では、リクエストの実行に4.5秒以上かかり、エントリ数が増えるにつれて時間がかかります。

4

2 に答える 2

2

今後の2.2リリースの開発バージョンであるバージョン2.1を使用できる場合は、新しい集計フレームワークを使用して、map/reduceよりもはるかに高速にこのクエリを実行できます。

そのarguinoとpinの最新の日付である値を取得するための集計パイプラインは次のようになります。

[{$match:{arduino: 0xCB}},
{$project:
       {_id: 0, arduino:1, pin:1, maxVal: {date:1, val:"$value"} }
},
{$group:
       {_id:{"arduino":1, "pin":1},maxDate:{$max:"$maxVal"} }    
},
{$project:
       {_id:0, "arduino":"$_id.arduino" , "pin":"$_id.pin","date":"$maxDate.date",value:"$maxDate.val"}
}]

サンプルデータで実行すると、結果は次のようになります。

> db.mesh_captors.aggregate(agg)
{
    "result" : [
        {
            "arduino" : 203,
            "pin" : 15,
            "date" : "Sat Jun 09 2012 16:22:50 GMT-0700 (PDT)",
            "value" : 126
        },
        {
            "arduino" : 203,
            "pin" : 14,
            "date" : "Sat Jun 09 2012 16:23:00 GMT-0700 (PDT)",
            "value" : 63
        }
    ],
    "ok" : 1
}

のpymongoサポートを介してPythonから集約フレームワークにアクセスできますdb.runCommanddb.runCommandあなたはそれにドキュメントを渡すことを実行します

{"aggregate":"mesh_captors", "pipeline":<pipeline-goes-here>}
于 2012-06-09T23:51:03.617 に答える
0

シャーディングされたコレクションでグループを使用することはできません。そのため、ほとんどのタスクでグループを使用することはできません。シャードコレクションを使用していない場合は、最高のパフォーマンスに近い可能性があります。(間違っている場合は訂正してください)MapReduceを使用して同じタスクを実装し、パフォーマンスを集計して比較してみてください。

この記事は、mongodbからの高度な集計をよりよく理解するのに役立つはずです。

于 2012-06-09T13:23:23.807 に答える