2013-03-14 3 views
15

配列内のいくつかの値をローテーションする必要があるドキュメントの更新操作を実行する必要があります。現在、MongoDBの更新クエリでは、更新の同じフィールドに$pop、次に$pushが許可されていません。アドバイスをオンラインで検索した後、私はdb.eval()がアトミック性を保証し、私が実行している操作が非常に短く、DBをあまりに長くロックしないで済むので、私の使用に最も適していると判断しました。JavaScriptでのdb.eval()のMongoDBのパフォーマンスpymongoと比較して

db.eval(function (id, newVal) { 
    doc = db.collection.findOne({_id: id}); 
    doc.values.shift(); 
    doc.values.push(newVal); 
    db.collection.save(doc); 
}, id, newVal); 

そして、これは完璧に動作します:ここで

は私がやろうとしている何かの例です!私はその後、eval()コマンドを取っていたどのように多くのミリ秒単位で見るために、プロファイリングのMongoDBを有効にして、私はいつもより少なく、1ミリ秒の結果を取得したい:

> db.system.profile.find({op: "command"}, {"millis": 1}) 
{ "millis" : 0 } 
{ "millis" : 0 } 
... 

これは私のアプリケーションはpythonであることを除いて、私には良いニュースです、私はeval()コマンドを実行するためにpymongoクライアントを使用しています。

conn = pymongo.Connection(mongo_server_hostname) 
db = conn.my_db 

db.eval("""function (id, newVal) { 
    doc = db.collection.findOne({_id: id}); 
    doc.values.shift(); 
    doc.values.push(newVal); 
    db.collection.save(doc); 
}""", id, new_val) 

私は非常に異なるプロファイリング結果を得る::私はpymongoを使用して、同一のeval()コマンドを実行すると、今(上記のデータは、モンゴシェルからである)。しかし

> db.system.profile.find({op: "command"}, {"millis": 1}) 
{ "millis" : 13 } 
{ "millis" : 14 } 
{ "millis" : 14 } 
... 

は実行に関する根本的に異なるものがあります同じeval()コマンドをmongoシェルとpymongoから実行すると、サーバーはpymongoから同じコマンドを実行するのに14ms以上かかるでしょうか? (代替としてSpiderMonkeyのを使用するように設定することができますが)あなたが見ている矛盾の

+2

同等のPythonコードを表示できますか? pymongoからどのように評価を呼んでいますか?シェルがとるのと同じタイプの 'eval'ロックを取っていますか? – WiredPrairie

+0

質問を編集しました。私はpymongoのeval()の結果が同じevalコマンドであると仮定します。私が遭遇したことは、私にそうでないと信じさせてくれました。 – jlhawn

+0

MongoDBとPyMongoのバージョンは何ですか?答えはwriteconcernの設定にすることができます... –

答えて

1

1つの原因(必ずしも必要ではないが原因が)のために、デフォルトでmongoシェルとmongodサーバーuse Google's v8 Javascript engine両方ということですあなたが与えるコマンドを解釈する。

Googleのv8では、Javascriptコードのホットスポットがあり、頻繁に使用されるJITコードになりそうです。

一方、バニラPyMongoはwritten in pure Pythonです。これは常に解釈されることを意味します。これはかなりのオーバーヘッドがあります。

まだ実行していない場合は、既定値の代わりにPyMongo extension written in Cを使用するか、アプリケーションの残りの部分に互換性がある場合は、Python用PyPy JITインタープリタを使用します。

Debianから派生した(Ubuntuのような)ディストリビューションを使用している場合、パッケージpython-pymongo-extは、PyMongoのCバージョンのプリコンパイル済みバージョンを提供します。

関連する問題