2013-06-03 58 views
1

我建立MongoDB數據庫中存在記錄,問題是,我想避免重複的條目。目前我(只檢查,如果條目不存在後插入文檔)這樣做:檢查是否MongoDB中

from pymongo import Connection 
import pandas as pd 
from time import strftime 
from collections import OrderedDict 

connection = Connection() 
db = connection.mydb 
collection = db.mycollection 

data = pd.read_csv("data/myfile.csv", parse_dates=[2,5]) 

for i in range(len(data)): 
    if(collection.find({ "id":  data.ix[0],       \ 
         "date1": data.ix[i, 2].strftime("%Y-%m-%d"), \ 
         "date2": data.ix[i, 5].strftime("%Y-%m-%d"), \ 
         "number": int(data.ix[i, 6]),     \ 
         "type": data.ix[i, 7]}).count() == 0): 
     collection.insert(here goes what I'd like to insert) 

這確實工作得很好,但是這已經有顯著的性能問題(只〜100MB的數據),像做find()似乎每次都會顯着減慢速度。

有沒有辦法加快速度?也許我從根本上做錯了? 我需要避免只在一組特定領域的重複,不是所有的人(即,也有「號碼2」,它可以是不同的,但我還是想把它作爲複製如果所有其他領域相匹配)。

回答

4

你可以建立在您正在搜索領域的unique index(蒙戈shell語法):

db.mycollection.ensureIndex({_id:1, date1:1, date2:1, number:1, type:1}, {unique: true}); 

和捕獲約束違反異常(如果適當忽略)被插入重複時。

典型地,這應該提高性能爲重複檢查由索引查找完成。

1

檢查之前插入不阻止它的好方法。爲了防止密鑰的重複,請使用主鍵。看到how to set a primary key in mongodb

此外,如果它不是對你有好處,至少添加mongo index

解決這個(我認爲)最好的辦法將是所有相關的和隨後的做1場生成密鑰2:

  1. 檢查是關鍵,而如果將指標 - 將會更快
  2. 將此鍵主鍵,插入就會失敗
+1

你不必有什麼東西是一個主鍵,以在其上具有唯一索引! –

0

您可以使用Upsert標誌執行update()操作,請參閱Update Operations with the Upsert Flag

而且已經有一個建在MongoDB中ID名爲「_id」,所以你可以,如果你想使用它。 下面是它會是什麼樣子:

collection.update(
    { "_id": ObjectID(data.ix[0]), 
     "date1": data.ix[i, 2].strftime("%Y-%m-%d") 
    }, 
    { "_id": ObjectID(data.ix[0]), 
     "date1": data.ix[i, 2].strftime("%Y-%m-%d") 
    }, 
    True 
    ) 
+0

你的建議在所描述的案例中都沒有幫助... –

+0

是的,我想我錯過了這個問題(這是加快速度)。也許這可以作爲一個額外的信息,有一個可以代替find()+ insert()的upsert操作。如果你們認爲這只是混淆的東西,我可以刪除這個答案:) – yoneal

+0

我認爲upsert是相關的 - 這是「找到文檔,如果你更新它,如果你不插入它的答案「但我認爲這與所陳述的最初問題不同(如果它存在,他不想做任何事情)...... –

相關問題