1

我正在构建一个 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()每次这样做似乎都会显着减慢速度。

有没有办法加快速度?也许我从根本上做错了?我只需要避免在某些字段上重复,而不是在所有字段上重复(即,还有“number2”,它可能不同,但如果所有其他字段都匹配,我仍然希望它是重复的)。

4

3 回答 3

4

您可以在要搜索的字段上构建唯一索引(mongo shell 语法):

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

并在插入重复项时捕获约束冲突异常(并在适当时忽略它)。

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

于 2013-06-03T03:52:12.317 回答
1

插入前检查不是防止它的好方法。为防止键重复,请使用主键。查看如何在 mongodb 中设置主键

另外,如果对您不利,至少添加mongo index

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

  1. 检查那个键,如果它将是索引 - 会更快
  2. 将此键设为主键,插入将失败
于 2013-06-03T03:38:43.807 回答
0

您可以使用 Upsert 标志执行 update() 操作,请参阅使用 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
    )
于 2013-06-03T03:52:45.873 回答