Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/477.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript MongoDB重复密钥错误_Javascript_Node.js_Mongodb - Fatal编程技术网

Javascript MongoDB重复密钥错误

Javascript MongoDB重复密钥错误,javascript,node.js,mongodb,Javascript,Node.js,Mongodb,所以现在,我正在开发一项服务,允许多个事件在MongoDB上存储数据。它们通过在每次出现新事件时在MongoDB上创建新集合来存储事件数据。如果同一事件需要存储不同的数据集,则应在MongoDB中创建一个新文档 下面的代码是我为处理此问题而创建的服务 import WhiteBoardEvent from '../model/event.model'; import IEventStore from '../interface/eventStore.interface'; import * as

所以现在,我正在开发一项服务,允许多个事件在MongoDB上存储数据。它们通过在每次出现新事件时在MongoDB上创建新集合来存储事件数据。如果同一事件需要存储不同的数据集,则应在MongoDB中创建一个新文档

下面的代码是我为处理此问题而创建的服务

import WhiteBoardEvent from '../model/event.model';
import IEventStore from '../interface/eventStore.interface';
import * as MongoClient from 'mongodb';

export class EventStore implements IEventStore {
    private mongoDBEndpoint = "mongodb://192.168.10.10:27017";


    public insert(event: WhiteBoardEvent, callback: (err: any) => void): void {
        MongoClient.connect(this.mongoDBEndpoint, { connectTimeoutMS: 1000 }, (connErr, db) => {
            if (connErr) { db.close(); callback(connErr); return; }
            this.getNextSequence(db, event, (err, sequence) => {
                if (err) { db.close(); callback(err); return; }
                event.sequence = sequence;
                db.collection(event.roomId).insert(event, (err) => {
                    db.close();
                    callback(err);
                });
            });
        });
    }

    private createCounterCollection(db: MongoClient.Db, event: WhiteBoardEvent, callback: (err: any) => void): void {
        db.collection("counters").insert({
            roomId: event.roomId,
            sequence: 0
        }, callback);
    }

    private getNextSequence(db: MongoClient.Db, event: WhiteBoardEvent, callback: (err: any, sequence: number) => void): void {
        var collection = db.collection("counters");
        collection.findOneAndUpdate(
            { roomID: event.roomId },
            {
                $inc: { sequence: 1 },
                // new: true
            },
            {
                upsert: true,
                returnOriginal: false
            },
            (err, r) => {
                if (err) {
                    this.createCounterCollection(db, event, (err) => {
                        if (err) { callback(err, -1); return; }
                        callback(null, 0);
                    });
                    return;
                }
                callback(null, r.value.sequence);
                console.log("counter : " + r.value.sequence);
            }
        );
    }
}
下面的代码是我创建的测试文件,以便查看MongoDB中的更改

import * as timers from 'timers';
import WhiteBoardEvent from './data/model/event.model';
import { EventStore } from './data/service/eventStore.service';

var model = new WhiteBoardEvent();
model.name = "t2";
model.roomId = "testRoom";
model.timestamp = new Date();
model.userId = "";


var model2 = new WhiteBoardEvent();
model2.name = "t1";
model2.roomId = "testRoom2";
model2.timestamp = new Date();
model2.userId = "";

var eventStore = new EventStore();

var timer1 = timers.setInterval(()=>{
    eventStore.insert(model, (err)=>{
        if(err){
            console.log(err);
        }else{
            console.log("Test Completed!");

        }
    });
}, 1000);

var timer2 = timers.setInterval(()=>{
    eventStore.insert(model2, (err)=>{
        if(err){
            console.log(err);
        }else{
            console.log("Test Completed!");

        }
    });
}, 1000);
这是我得到的输出的一个片段。这里显示了第一个实例的“testcompleted”,之后,我将得到重复的错误

counter : 1
counter : 1
Test Completed!
Test Completed!
counter : 2
{ MongoError: E11000 duplicate key error collection: admin.testRoom index: 
_id_ dup key: { : ObjectId('59d5da14cedd6f28a5db8c93') }

有人能帮我吗?提前谢谢你

很可能在您的方案中,您的密钥设置为
unique:true
。 添加具有相同密钥或未填充密钥的另一个对象将导致重复密钥错误。因为,如果一个字段没有被填充,它将被null填充。因此,2次null是一个重复的密钥错误。以确保这不会发生

使用
sparse:true
而不是
unique:true
。还请注意,具有
unique:true
的字段永远不能有两个相同的键。Sparse内部只能有多个空值(未定义),其工作原理与
unique:true
相同

在您的情况下,您必须对“”上的userid进行计时,如果将其设置为unique,则可能会导致错误。
model.userid=“”

希望这能解决你的问题。否则请给我们看看你的型号


Sven

您正在创建两个
WhiteBoardEvent
实例,但没有显式设置ID(这很好,但相关)。请看上面代码的摘录:

db.collection(event.roomId).insert(event, (err) => {
    db.close();
    callback(err);
});
事件
移交给MongoDB的
插入
后,将检查它是否有ID—它没有。因此,MongoDB代码会为您生成一个ID(请参阅)。这一切都很好——这是你想要的

但是,下次调用
setInterval
回调时会发生什么情况?嗯,
model
model2
现在有了一个ID集——它是根据我刚才描述的规则设置的。在这种情况下,既然
模型
上设置了一个ID进入
插入
,那么您正试图重用相同的ID,因为MongoDB代码不使用它

在测试代码中,只需清除
eventStore.insert
回调中的ID即可,以确保每次都生成一个新ID。e、 g:

eventStore.insert(model, (err)=>{
    model._id = null;

    if(err){
        console.log(err);
    }else{
        console.log("Test Completed!");
    }
});

我找到了一个我用铸造的替代品。就像:删除(模型)。\u id;