Python 检查MongoDB中是否存在记录

Python 检查MongoDB中是否存在记录,python,performance,mongodb,pymongo,Python,Performance,Mongodb,Pymongo,我正在构建一个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 da

我正在构建一个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的数据来说,这已经存在严重的性能问题,因为每次查找似乎都会显著降低速度

有没有办法加快速度?也许我根本就做错了?
我只需要避免在某一组字段上重复,不是所有字段都重复,也就是说,也有数字2,可以不同,但如果所有其他字段都匹配,我仍然希望它是重复的。

插入前检查并不是防止重复的好方法。要防止密钥重复,请使用主键。看

此外,如果这对你不好,至少添加

我认为解决这个问题的最佳方法是从所有相关字段生成密钥,然后执行以下2项中的1项:

检查该键,如果该键是索引键,则会更快 将此密钥作为主键,则插入将失败
插入前检查并不是防止插入的好方法。要防止密钥重复,请使用主键。看

此外,如果这对你不好,至少添加

我认为解决这个问题的最佳方法是从所有相关字段生成密钥,然后执行以下2项中的1项:

检查该键,如果该键是索引键,则会更快 将此密钥作为主键,则插入将失败 您可以在搜索mongo shell语法的字段上构建:

db.mycollection.ensureIndex({_id:1, date1:1, date2:1, number:1, type:1}, {unique: true});
并捕获约束冲突异常,并在插入重复项时忽略它(如果合适)

通常,这会提高性能,因为重复项检查是通过索引查找完成的。

您可以在搜索mongo shell语法的字段上构建:

db.mycollection.ensureIndex({_id:1, date1:1, date2:1, number:1, type:1}, {unique: true});
并捕获约束冲突异常,并在插入重复项时忽略它(如果合适)


通常这会提高性能,因为重复项检查是通过索引查找完成的。

您可以使用Upsert标志执行更新操作,请参阅

此外,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
    )

可以使用Upsert标志执行更新操作,请参阅

此外,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
    )

你不必让某个东西成为主键就可以在上面有一个唯一的索引!你不必让某个东西成为主键就可以在上面有一个唯一的索引!是的,我想我错过了一个问题,这个问题加快了事情的发展。也许这只是一个额外的信息,说明有一个upsert操作可以替换find+insert。如果你们认为这会让事情变得混乱,我可以删除这个答案:我确实认为一个upsert是相关的-这是找到文档的答案,如果你更新它,如果你不插入它,但我认为这与最初的问题不同,如果它存在,他不想做任何事情…是的,我想我错过了加快速度的问题。也许这只是一个额外的信息,说明有一个upsert操作可以替换find+insert。如果你们认为这会让事情变得混乱,我可以删除这个答案:我确实认为一个upsert是相关的-这是找到文档的答案,如果你更新它,如果你不插入它,但我认为这与最初的问题不同,如果它存在,他不想做任何事情。。。