配列内のいくつかの値をローテーションする必要があるドキュメントに対して更新操作を実行する必要があります。現在、MongoDB 更新クエリでは、更新で同じフィールドに対して$pop
と を実行することはできません。$push
オンラインでアドバイスを検索した後、db.eval()
原子性が保証され、実行している操作が非常に短いため、データベースが長時間ロックされないため、これが私の使用に最も適していると判断しました。
これが私がやろうとしていることの例です:
db.eval(function (id, newVal) {
doc = db.collection.findOne({_id: id});
doc.values.shift();
doc.values.push(newVal);
db.collection.save(doc);
}, id, newVal);
そして、これは完全に機能します!次に、mongoDB プロファイリングを有効にして、コマンドが何ミリ秒eval()
かかったかを確認しました。結果は常に 1 ミリ秒未満でした。
> db.system.profile.find({op: "command"}, {"millis": 1})
{ "millis" : 0 }
{ "millis" : 0 }
...
私のアプリケーションが python であることを除けば、これは私にとって朗報です。そのため、pymongo クライアントを使用してeval()
コマンドを実行しています。(上記のデータはmongoシェルからのものです)しかし、今、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)
非常に異なるプロファイリング結果が得られます。
> db.system.profile.find({op: "command"}, {"millis": 1})
{ "millis" : 13 }
{ "millis" : 14 }
{ "millis" : 14 }
...
eval()
mongo シェルと pymongo 内から同じコマンドを実行すると、サーバーが pymongo から同じコマンドを実行するのに 14 ミリ秒多くかかるという根本的な違いはありますか?