【问题标题】:Insert to MongoDB collection that has unique key with Python使用 Python 插入具有唯一键的 MongoDB 集合
【发布时间】:2016-01-06 20:16:41
【问题描述】:

我有一个名为englishWords 的集合,唯一索引是“单词”字段。 当我这样做时

from pymongo import MongoClient

tasovshik = MongoClient()
db = tasovshik.tongler
coll = db.englishWords

f = open('book.txt')
for word in f.read().split():
    coll.insert( { "word": word } } )

我收到此错误消息

pymongo.errors.DuplicateKeyError: E11000 duplicate key error index: tongler.englishWords.$word_1 dup key: { : "Harry" }
,但在插入第一个现有单词时停止插入。

我不想执行存在性检查,我想毫无问题地利用唯一索引的好处。

【问题讨论】:

    标签: python mongodb mongodb-query pymongo


    【解决方案1】:

    您可以执行以下操作:

    for word in f.read().split():
        try:
            coll.insert( { "word": word } } )
        except pymongo.errors.DuplicateKeyError:
            continue
    

    这将忽略错误。

    另外,你在尝试之前是否放弃了收藏?

    【讨论】:

    • 不,我没有,我将获取许多文本文件并将所有英文单词插入该集合,所以我不会丢弃它。它 python 删除此错误消息 Traceback (最近一次调用最后): File "main.py", line 14, in except pymongo.errors.DuplicateKeyError: NameError: name 'pymongo' is not defined
    • 我在开头添加了 import pymongo ,它工作了,谢谢。
    【解决方案2】:

    为了避免不必要的异常处理,你可以做一个 upsert:

    from pymongo import MongoClient
    
    tasovshik = MongoClient()
    db = tasovshik.tongler
    coll = db.englishWords
    
    for word in f.read().split():
        coll.replace_one({'word': word}, {'word': word}, True)
    

    最后一个参数指定如果值不存在,MongoDB 应该插入该值。

    这里是the documentation


    编辑:为了更快地处理一长串单词,您可以像这样批量执行:

    from pymongo import MongoClient
    
    tasovshik = MongoClient()
    db = tasovshik.tongler
    coll = db.englishWords
    
    bulkop = coll.initialize_unordered_bulk_op()
    for word in f.read().split():
        bulkop.find({'word':word}).upsert()
    
    bulkop.execute()
    

    取自bulk operations documentation

    【讨论】:

    • 抱歉,在这种情况下 upsert 有效吗?
    • 这是因为您在 word 列上有一个唯一索引。如果您希望在长长的单词列表中提高效率,我将更新我的答案以提供更快的变体。
    • .. 在word *属性上,不是列:)
    • 第二个变体返回此 Traceback(最近一次调用最后一次):文件“main.py”,第 31 行,在 bulkop.execute() 文件“/Library/Python/2.7/site -packages/pymongo-3.2-py2.7-macosx-10.9-intel.egg/pymongo/bulk.py”,第 628 行,在执行文件“/Library/Python/2.7/site-packages/pymongo-3.2-py2. 7-macosx-10.9-intel.egg/pymongo/bulk.py",第 450 行,在执行 pymongo.errors.InvalidOperation:没有要执行的操作
    • 它是每次都返回还是在第一次之后返回?
    【解决方案3】:

    我刚刚运行了您的代码,一切看起来都不错,只是最后一行有一个额外的}。删除它,您就不会删除任何集合。每个insert 都会创建自己的一批数据,因此无需删除之前的集合。

    嗯,错误消息表明密钥Harry 已经插入,您正尝试使用相同的密钥再次插入。在您的整个代码中看起来不是这样吗?

    【讨论】:

      猜你喜欢
      • 2014-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多