2017-06-02 15 views
0

我在Mongoldb的領域是; id,website_url,狀態。如何在循環中使用批量upsert?

我需要找到website_url並將其狀態更新爲3並添加一個名爲err_desc的新字段。

我有一個website_urls列表,它的狀態和它的err_desc。

以下是我的代碼。

client = MongoClient('localhost', 9000) 
db1 = client['Company_Website_Crawl'] 
collection1 = db1['All'] 
posts1 = collection1.posts 
bulk = posts1.initialize_ordered_bulk_op() 
website_url = ["http://www.example.com","http://example2.com/"] 
err_desc = ["error1","error2"] 
for i in website_url: 
    parsed_uri = urlparse(i) 
    domain = '{uri.scheme}://{uri.netloc}/'.format(uri=parsed_uri) 
    final_url = domain 
    final_url_strip = domain.rstrip("/") 
    print i,final_url,final_url_strip,"\n" 
    try: 
     k = bulk.find({'website_url':i}).upsert().update({'$push':{'err_desc':err_desc,'status':3}}) 
     k = bulk.execute() 
     print k 
    except Exception as e: 
     print "fail" 
     print e 

錯誤

fail batch op errors occurred

fail Bulk operations can only be executed once.

起初我用

k = posts1.update({'website_url':final_url_strip},{'$set':{'err_desc':err_desc,'status':3}},multi=True) 

這是爲5M記錄太慢。所以我想使用批量更新選項。請幫助我在這種情況下使用bulk upsert。

回答

0

錯誤消息告訴您需要在調用execute()後重新初始化批處理寫入操作。但事情是,你做錯了。在你的情況下,你需要的末尾呼籲execute for循環是這樣的:

from itertools import count 


ct = count() 

for url in website_url: 
    ... 
    try: 
     bulk.find({'website_url':i}).upsert().update({'$push':{'err_desc':err_desc,'status':3}}) 
     val = next(ct) 
    except Exception as e: 
     ... 
if val > 0: 
    bulk.execute()  

還要注意的是Bulk()現在已經過時,與bulkwrite

+0

感謝@ S.M.Styvane取代。我有兩個澄清。 1.還要注意Bulk()現在已被棄用,並被大量寫入(我無法理解你指的是哪裏)。2. pymongo.errors.BulkWriteError:發生的批處理操作錯誤是我遇到的錯誤。 – NiviSRa

+0

查看3.2發行說明[此處](https://docs.mongodb.com/manual/release-notes/3.2/#mongo-shell-and-crud-api)中bulkwrite的描述 – styvane

+0

Thanks @ SMStyvane。有效。你能否給我澄清另一個疑問。是否有可能找到任何記錄失敗。例如,如果** i **的值在數據庫中找不到,我需要替換另一個值並嘗試查找記錄並進行更改。有沒有可能,如果可以,我該如何處理? – NiviSRa