首页 > 解决方案 > node.js db.collection.insertOne - MongoError:E11000 重复键错误集合:_id_ dup

问题描述

在 node.js 中,从一个 javascript 循环中,我试图将一个 json 对象插入到一个 mongodb 集合中,但在 _id 列上出现重复键错误。

{ MongoError:E11000 重复键错误集合:app.Tab2017index:id重复键:{:ObjectId('5cbc813227b2ca2864b3c66a')}

这是我的 javascript 代码的一部分,它导致错误。

const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
const url = 'mongodb://localhost:27017';
const dbName = 'app';    
var jsonData = {};

  MongoClient.connect(url,{useNewUrlParser: true}, function(err, client) {
    assert.equal(null, err);
    if(err) { return console.dir(err); }
    const db = client.db(dbName);
    const collection = db.collection('Tab2017')

    for (var i = 0; i < 5; i++) {        
            jsonData["test"] = "line";                          
                console.log('LINE_'+i+'- '+JSON.stringify(jsonData));
                collection.insertOne(jsonData, (err, result) => {                       
                    if(err) { console.dir(err); }                           
                    console.log('mongodb insert done');             
                })              
        }     
  })

上面的代码在控制台上显示错误,

D:\app\server\routes>node linmon.route-backup3.js
LINE_0- {"test":"line"}
LINE_1- {"test":"line","_id":"5cbc813227b2ca2864b3c66a"}
LINE_2- {"test":"line","_id":"5cbc813227b2ca2864b3c66a"}
LINE_3- {"test":"line","_id":"5cbc813227b2ca2864b3c66a"}
LINE_4- {"test":"line","_id":"5cbc813227b2ca2864b3c66a"}
mongodb insert done
-------------------------------------------
{ MongoError: E11000 duplicate key error collection: app.Tab2017 index: _id_ dup key: { : ObjectId('5cbc813227b2ca2864b3c66a') }
    at Function.create (D:\app\server\node_modules\mongodb\node_modules\mongodb-core\lib\error.js:43:12)
    at toError (D:\app\server\node_modules\mongodb\lib\utils.js:149:22)
    at coll.s.topology.insert (D:\app\server\node_modules\mongodb\lib\operations\collection_ops.js:859:39)
    at D:\app\server\node_modules\mongodb\node_modules\mongodb-core\lib\connection\pool.js:397:18
    at process._tickCallback (internal/process/next_tick.js:61:11)

我没有插入 _id 列值并允许它由系统生成。这是 getindexes 的输出。

> db.Tab2017.getIndexes()
[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "app.Tab2017"
        }
]
>

当我通过 mongo shell 命令行插入相同的对象时,它可以正常工作。看起来 javascript 不等待 mongodb 插入操作完成。

标签: node.jsmongodb

解决方案


我自己解决了这个问题。Nodejs 执行异步操作,因此它完成了循环,但也不断插入到 mongodb 集合中。我注意到,第一次操作总是成功并且后续插入失败。mongodb 以某种方式为第一次插入生成“_id”值,并在 json 对象中保持相同的“_id”。这就是它抛出重复错误的原因。我只是在 mongo 插入之前添加了一行以从 json 对象中删除“_id”并且它起作用了。

这是我修改后的代码。

for (var i = 0; i < 5; i++) {        
            jsonData["test"] = "line"; 
            **delete jsonData["_id"];**
                console.log('LINE_'+i+'- '+JSON.stringify(jsonData));
                collection.insertOne(jsonData, (err, result) => {                       
                    if(err) { console.dir(err); }                           
                    console.log('mongodb insert done');             
                })              
        } 

推荐阅读