2013-03-14 20 views
15

Dizideki bazı değerleri döndürmem gereken belgeler üzerinde güncelleme işlemleri gerçekleştirmem gerekiyor. MongoDB güncelleme sorguları, bir güncellemede aynı alanda $pop ve daha sonra $push izin vermez. Çevrimiçi ortamda arama yaptıktan sonra, db.eval()'un atomizasyon sağladığından ve performansımın çok kısa olduğu için kullanımım için en uygun olduğuna karar verdim, bu yüzden db'yi çok uzun süre kilitlemeyecek.MongoDB db.eval() 'in javascript shell vs. pymongo'daki performansı

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

Ve bu mükemmel çalışıyor:

İşte yapmaya çalışıyorum şeyin bir örnek! Sonra eval() komut alıyordu kaç milisaniye görmek için profil mongodb etkin ve ben her zaman daha az olduğunu 1 milisaniye sonuçlarını almak istiyorum:

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

Bu benim uygulama Python olması dışında benim için iyi bir haber, bu yüzden eval() komutlarını gerçekleştirmek için bir pymongo istemcisini kullanıyorum.

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) 

Ben çok farklı profil sonuçlar elde: Ben pymongo kullanarak özdeş eval() komutlarını çalıştırdığınızda, şimdi (Yukarıdaki veriler Mongo kabuğundan olan) Ama

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

çalıştırma hakkında temelde farklı bir şey var mı aynı eval() mongo kabuk ve pymongo içinden gelen komutlar, sunucuda 14 ms daha fazla alarak pymongo'dan aynı komutları çalıştırabilir mi? Gördüğünüz farklılığın

+2

Python kodunuzu eşdeğer gösterebilir misiniz? Pratiği pymongo'dan nasıl arıyorsun? Kabuğun aldığı aynı tür "eval" kilitlerini mi alıyor? – WiredPrairie

+0

Soruyu düzenleyin. Ben pymongo'nun eval() sonucunun aynı değerlendirme komutunda olduğunu varsayalım. Karşılaştığım hiçbir şey başka türlü inanmamamı sağladı. – jlhawn

+0

MongoDB ve PyMongo sürümleriniz nedir? Cevap Writeconcern ayarlarında olabilir ... –

cevap

1

olası bir neden (şart olmamakla birlikte nedeni) olduğunu mongo kabuk ve (o alternatif olarak Spidermonkey kullanmak üzere yapılandırılabilir olsa da) varsayılan olarak mongod sunucu use Google's v8 Javascript engine için hem Verdiğiniz komutları yorumlamak.

Google'ın v8'i Javascript kodunda sıcak noktaları görüyor ve büyük olasılıkla kullanılan JIT koduna sahip olması olasıdır. Diğer taraftan, vanilya PyMongo written in pure Python'dur, bu da her zaman yorumlanacağı anlamına gelir, bu da kayda değer bir ek yüke sahip olan bir şeydir.

Henüz yapmadıysanız, bir seçenek varsayılan olarak PyMongo extension written in C'u kullanmak veya uygulamanızın geri kalanı uyumluysa Python için PyPy JIT yorumlayıcısını kullanmak olabilir.

Debian'dan (Ubuntu gibi) türetilen bir dağıtım kullanırsanız, python-pymongo-ext paketi PyMongo'nun C sürümünün önceden derlenmiş sürümünü sağlar.