MongoDB在插入

时间:2016-02-06 20:25:45

标签: python mongodb pymongo nosql

我正在使用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 dup key:{:   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})

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

2 个答案:

答案 0 :(得分:1)

问题是你的save方法正在使用一个名为“id”的字段来决定它是应该插入还是upsert。你想用“_id”代替。 You can read about the _id field and index here. PyMongo会自动为您的文档添加_id(如果尚未存在)。 You can read more about that here.

答案 1 :(得分:1)

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

我不太明白你是什么意思:

  

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

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

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正在使用某种哈希算法来为你的auto-gen _id插入而不改变种子。

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

编辑: 我刚试过这个并且有效:

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

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

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