使用Java驱动程序向Mongo插入数据时出现“err”:“E11000重复键错误”。

11

在主线程中发生异常:com.mongodb.MongoException$DuplicateKey: {"serverUsed" : "localhost/127.0.0.1:27017" , "err" : "E11000 duplicate key error index: twitterdb03.LevelAFollowers.$id dup key: { : ObjectId('52d5636de408652b4853a8fe') }" , "code" : 11000 , "n" : 0 , "connectionId" : 12 , "ok" : 1.0}

我正在使用mongo 2.11.1版本。

以前用Java进行简单的写操作从未出现过问题。

myMap.put(inid, followersList);
myObj.putAll(myMap);
myIdMapCollection.insert(myObj);
2个回答

23

我在这个页面上找到了答案。我猜你的代码大致是这样的(大大简化):

doc = {} 
for i in xrange(2): 
    doc['i'] = i 
    collection.insert(doc) 

问题在于,如果文档中不存在_id字段,PyMongo会在插入时将其注入文档中(_id始终由10gen驱动程序在客户端生成)。这意味着第一次通过循环时,_id将由插入方法添加。由于doc在循环外定义,每次循环通过时都使用相同的_id值。
解决方案:
  1. 删除键_id
for i in xrange(2): 
    doc['i'] = i 
    if '_id' in doc: 
        del doc['_id'] 
    collection.insert(doc)
或者手动创建一个新的:
from bson.objectid import ObjectId 
for i in xrange(2): 
    doc['i'] = i 
    doc['_id'] = ObjectId() 
    collection.insert(doc)

谢谢,终于有一个有用且简单的解决方案了。 - selotec

7
尝试调用myIdMapCollection.save(myObj);而不是myIdMapCollection.insert(myObj);insert不同,save方法执行upsert操作,这意味着如果文档包含_id,则替换该文档。
我的猜测是您使用光标|查询获取了DBObject,进行了操作,并希望保留更改。在这种情况下,使用save是正确的方法。
因此,在调用insert时,DBObject已经与_id相关联,因此调用insert会失败,因为您已经在集合中拥有一个具有该_id的文档,这应该是唯一的(重复索引错误)。

终于成功了,感谢您。我被卡在这里已经两天了。 - Nautilus_o
我有同样的问题!但使用.save并不能解决! - mshzmkot
但是我的重复键在我手动创建的索引中,而不是在 _id 上。这是为了什么目的?如果是的话,我该如何解决这个问题? - mshzmkot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接