【问题标题】:MongoDB generating same ID between insertsMongoDB在插入之间生成相同的ID
【发布时间】:2016-05-16 17:23:00
【问题描述】:

我正在使用 pymongo,我正在尝试将 dicts 插入 mongodb 数据库。我的字典是这样的

{
    "name" : "abc",
    "Jobs" : [
        {
            "position" : "Systems Engineer (Data Analyst)",
            "time" : [
                "October 2014",
                "May 2015"
            ],
            "is_current" : 1,
            "location" : "xyz",
            "organization" : "xyz"
        },
        {
            "position" : "Systems Engineer (MDM Support Lead)",
            "time" : [
                "January 2014",
                "October 2014"
            ],
            "is_current" : 1,
            "location" : "xxx",
            "organization" : "xxx"
        },
        {
            "position" : "Asst. Systems Engineer (ETL Support Executive)",
            "time" : [
                "May 2012",
                "December 2013"
            ],
            "is_current" : 1,
            "location" : "zzz",
            "organization" : "xzx"
        },
    ],
    "location" : "Buffalo, New York",
    "education" : [
        {
            "school" : "State University of New York at Buffalo - School of Management",
            "major" : "Management Information Systems, General",
            "degree" : "Master of Science (MS), "
        },
        {
            "school" : "Rajiv Gandhi Prodyogiki Vishwavidyalaya",
            "major" : "Electrical and Electronics Engineering",
            "degree" : "Bachelor of Engineering (B.E.), "
        }
    ],
    "id" : "abc123",
    "profile_link" : "example.com",
    "html_source" : "<html> some_source_code </html>"
}

我收到此错误:

pymongo.errors.DuplicateKeyError: E11000 重复键错误索引: Linkedin_DB.employee_info.$id 复制密钥:{: ObjectId('56b64f6071c54604f02510a8') }

当我运行我的程序时,第一个文档被正确插入,但是当我插入第二个文档时,我得到了这个错误。当我再次启动我的脚本时,由于此错误而未插入的文档会被正确插入,并且下一个文档会出现错误,并且这种情况会继续。

显然 mognodb 在两次插入期间使用了相同的 objecID。我不明白为什么 mongodb 无法为新文档生成唯一 ID。

我保存传递数据的代码:

class Mongosave:
    """
        Pass collection_name and dict data
        This module stores the passed dict in collection
    """

    def __init__(self):
        self.connection = pymongo.MongoClient()
        self.db = self.connection['Linkedin_DB']

    def _exists(self, id):
        #To check if user alredy exists
        return True if list(self.collection.find({'id': id})) else False

    def save(self, collection_name, data):
        self.collection = self.db[collection_name]
        if not self._exists(data['id']):
            print (data['id'])
            self.collection.insert(data)
        else:
            self.collection.update({'id':data['id']}, {"$set": data})

我可以弄清楚为什么会这样。任何帮助表示赞赏。

【问题讨论】:

  • 我无法复制这个,你能告诉我们你是如何遍历你的字典的吗?
  • @SteveRossiter 我通过抓取网站来生成这些字典。另外,我正在生成一个类似的字典并一次插入一个。在save 数据中包含字典数据。
  • 您正在设置“id”键,请查看下面的答案。

标签: python mongodb pymongo nosql


【解决方案1】:

问题在于您的保存方法使用了一个名为“id”的字段来决定它应该执行插入还是更新插入。您想改用“_id”。 You can read about the _id field and index here. PyMongo 会自动将 _id 添加到您的文档中,如果其中不存在的话。 You can read more about that here.

【讨论】:

    【解决方案2】:

    您可能已经在一次运行中将同一文档的两个副本插入到您的集合中。

    我不太明白你的意思:

    当我再次启动我的脚本时,由于此错误而未插入的文档被正确插入,并且下一个文档出现错误,并且继续。

    我所知道的是,如果你这样做:

    from pymongo import MongoClient
    
    client = MongoClient()
    db = client['someDB']
    collection = db['someCollection']
    someDocument = {'x': 1}
    for i in range(10):
        collection.insert_one(someDocument)
    

    你会得到一个:

    pymongo.errors.DuplicateKeyError: E11000 重复键错误索引:

    这让我想,虽然 pymongo 会为你生成一个唯一的 _id,如果你不提供,它不能保证是唯一的,特别是如果提供的文档不是唯一的。大概 pymongo 在不更改种子的情况下对您为其自动生成 _id 插入的内容使用某种哈希算法。

    尝试生成自己的_id,看看是否会再次发生。

    编辑: 我刚试过这个,它有效:

    for i in range(10):
        collection.insert_one({'x':1})
    

    这让我觉得 pymongo 生成 _id 的方式与你输入它的对象相关联,这次我不再引用同一个对象,问题就消失了。

    您是否为您的数据库提供了同一对象的两个引用?

    【讨论】:

      猜你喜欢
      • 2023-03-04
      • 1970-01-01
      • 2016-12-04
      • 2012-07-04
      • 1970-01-01
      • 2017-03-17
      • 1970-01-01
      • 2016-08-28
      • 2011-07-21
      相关资源
      最近更新 更多