【问题标题】:solve E11000 duplicate key error collection: _id_ dup key in pymongo解决E11000重复键错误收集:pymongo中的_id_ dup key
【发布时间】:2020-09-16 00:24:21
【问题描述】:

我正在尝试使用 bulk_write 指令插入大量文档(+1M)。为此,我创建了一个 InsertOne 函数列表。

python version = 3.7.4

pymongo version = 3.8.0

文档创建:

document = {
    'dictionary': ObjectId(dictionary_id),
    'price': price,
    'source': source,
    'promo': promo,
    'date': now_utc,
    'updatedAt': now_utc,
    'createdAt:': now_utc
  }

# add line to debug
if '_id' in document.keys():
    print(document)

return document

我通过从元素列表中添加一个新字段来创建完整的文档列表,并使用 InsertOne 创建查询

bulk = []
for element in list_elements:
    for document in documents:
        document['new_field'] = element
        # add line to debug
        if '_id' in document.keys():
           print(document)
        insert = InsertOne(document)
        bulk.append(insert)
return bulk

我使用bulk_write 命令进行插入

collection.bulk_write(bulk, ordered=False)

我附上文档https://api.mongodb.com/python/current/api/pymongo/collection.html#pymongo.collection.Collection.bulk_write

根据文档,_id 字段是自动添加的 Parameter - document: The document to insert. If the document is missing an _id field one will be added.

不知何故,它似​​乎做错了,因为其中一些具有相同的价值。 1M 文档中的 700k 收到此错误(当然有不同的 _id) 'E11000 duplicate key error collection: database.collection index: _id_ dup key: { _id: ObjectId(\'5f5fccb4b6f2a4ede9f6df62\') }' 对我来说似乎是 pymongo 的一个错误,因为我在很多情况下都使用了这种方法,但我没有使用这么大的文档

_id 字段必须是唯一的,但是,由于这是由 pymongo 自动完成的,我不知道如何解决这个问题,也许使用带有 upsert True 的 UpdateOne 和不可能的过滤器和希望是最好的。

我会很感激这个问题的任何解决方案或解决方法

【问题讨论】:

    标签: python pymongo


    【解决方案1】:

    似乎当我添加文档的新字段并将其附加到列表中时,我创建了相同元素的类似实例,所以我有相同的查询len(list_elements) 次,这就是为什么我有重复键错误。

    为了解决这个问题,我将文档的副本附加到列表中

    bulk.append(document.copy())
    

    然后使用该列表创建查询

    我要感谢@Belly Buster 在这个问题上的帮助

    【讨论】:

    • 很高兴你把它整理好了。您可以接受自己的答案,以便其他人知道它已解决。
    • 谢谢,我还不能接受,我得等 13 个小时 T.T,但我会尽可能地接受
    • 谢谢,@CapiHidalgo 它解决了我的问题
    【解决方案2】:

    如果您的代码 sn-p 中的任何 documents 已经包含 _id,则不会添加新的 _id,并且您将面临出现重复错误的风险,正如您所观察到的那样。

    【讨论】:

    • 感谢您的回答,但在那些文档的定义中没有任何字段_id
    • 首先,你确定吗?如果您是,我们将需要查看更多代码,即如何创建文档以及处理bulk 的命令。同时发布你的 python 和 pymongo 版本。
    • 幽默吧。在你的内部循环中添加一个调试行if '_id' in document: print(document)
    • 我在原始问题上添加了代码和版本,现在我正在使用您建议的行进行调试,完成后我会尽快更新
    • 我刚刚使用您建议的调试行运行程序,但在创建 InsertOne 查询之前,它没有在其键中找到任何带有“_id”的文档
    猜你喜欢
    • 1970-01-01
    • 2018-07-26
    • 2019-09-10
    • 2019-10-11
    • 1970-01-01
    • 2015-06-01
    • 2022-01-05
    • 2021-07-25
    • 1970-01-01
    相关资源
    最近更新 更多