0

I have a Promise, which I am resolving and then I am iterating through it while saving to a mongo database with mongoose.

I am absolutely sure that I have no duplicates (see output) and I still get the following duplicate key error. It might be related to the promise. The first object gets saved normally, and then it crashes.

Promise.resolve(members).then(function(value){
    value.forEach(member => {
        Player.findById(member['id'], function(err, foundPlayer){
            if (err){
                console.log(err);
                return;
            }else{
                if(foundPlayer) console.log(member['id'] + ' already registered.');
                else{
                    console.log('saving with id ' + member['id']);
                    new Player({name: member['nickname'], _id: member['id']}).save();
                } 
            }
        });
    });
});

The output is:

saving with id 515595203781066753
saving with id 725997594014384139
saving with id 740967607624269855
(node:29052) UnhandledPromiseRejectionWarning: MongoError: E11000 duplicate key error collection: users.players index: id_1 dup key: { id: null }
...
(node:29052) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
...
(node:14580) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:14580) UnhandledPromiseRejectionWarning: MongoError: E11000 duplicate key error collection: users.players index: id_1 dup key: { id: null }
...
(node:14580) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)

What I tried:

  • I tried implementing async behaviour, but failed.
  • I tried using the default assigned IDs by mongoose instead of mine, but same error

The model:

var mongoose    = require('mongoose');

var PlayerSchema = new mongoose.Schema({
     _id: {type: String},
     name: String,
     points: {type: Number, default: 0}
});

module.exports = mongoose.model("Player", PlayerSchema);

EDIT

In the mongo database, this gets saved:

{"_id":"515595203781066753","points":{"$numberInt":"0"},"name":"somename","__v":{"$numberInt":"0"}}

Lukas
  • 397
  • 6
  • 21
  • Is it possible to show the list of players and their ID's that you're trying to use? – Moe Sep 25 '20 at 15:01
  • @MohamedMoselhy How do you mean? The ids are visible in the output. And the member['nickname'] field is a string, it is unique, but shouldn't have to be. (At the moment I'm only trying to save those 3 players). If you mean the result in the mongodb, I can add it. But it is just the first id with a random name. – Lukas Sep 25 '20 at 15:04
  • This could be related to https://stackoverflow.com/questions/24430220/e11000-duplicate-key-error-index-in-mongodb-mongoose Maybe you're trying to insert two documents (sure, they might have different ID's, but they could be both storing a null no-duplicates field) – Moe Sep 25 '20 at 15:08
  • @MohamedMoselhy I read this before I wrote the question and it did not help, because he actually had a duplicate (even if it was empty) – Lukas Sep 25 '20 at 15:09
  • I wonder why the second object doesn't get saved, even though it doesn't produce an error right away – Moe Sep 25 '20 at 15:17
  • @MohamedMoselhy sorry, my fault. The error gets repeated multiple times after the first time. I will change the OP – Lukas Sep 25 '20 at 15:20
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/222082/discussion-between-mohamed-moselhy-and-hertelukas). – Moe Sep 25 '20 at 15:23

1 Answers1

0

According to the error message, there is a unique index on a field named id.

index: id_1 dup key: { id: null }

In the save call, you are setting _id, but not id:

new Player({name: member['nickname'], _id: member['id']}).save();

When building index entries, MongoDB represents missing fields with null.

The save() function returns a promise, so it is quite likely that you have reached the 3rd or 4th document before the first error gets returned.

Joe
  • 25,000
  • 3
  • 22
  • 44
  • I tried that. I changed the mentioned line to this: ```new Player({name: member['nickname'], _id: member['id'], id: member['id']}).save();``` And before saving I print out ```member['id']```, so I am absolutely sure it is unique. I get the exact same error message – Lukas Sep 26 '20 at 09:01