Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Model.create(doc, fn) should save all valid documents. #1731

Closed
danypype opened this issue Oct 9, 2013 · 9 comments · Fixed by #13544
Closed

Model.create(doc, fn) should save all valid documents. #1731

danypype opened this issue Oct 9, 2013 · 9 comments · Fixed by #13544
Labels
enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature
Milestone

Comments

@danypype
Copy link

danypype commented Oct 9, 2013

I'm trying to save a set of documents using Model.create(documents, function(error){...}) I found when a document is invalid, the previous documents were saved but the following will never be saved.

I think Model.create should save all valid documents. I would like an API like this.

//Passing one doc
Person.create({name: "John"}, function(error, john){...})

//Passing an array
var persons = [{name: "John"}, {name: "Doe"}];
Person.create(persons, function(errors, docs){...});

//Passing individual docs
Person.create({name: "John"}, {name: "Doe"}, function(errors, docs){...});

I would like to do a pull request, but first I want to know what do you think.

@nathanredblur
Copy link

yeap, I have the same problem.

@wbeckler
Copy link

Halleluja! Yes, this exactly!

@WhiteRavenPL
Copy link

Same here too.

@holisticode
Copy link

I have the same problem, but I vote for two APIs, one where it saves all or nothing, and one for all valid docs like requested above :)

@mahasooq
Copy link

Having the same problem here!

@lineus
Copy link
Collaborator

lineus commented Oct 7, 2018

@vkarpov15 Model.create() does currently create all valid documents, but it returns only the first document that failed in the Error. Should/Can we change the behavior of Model.create() to collate all errors and return some sort of collection in the Error?

The following script shows that an error is generated and returned for the first duplicated doc, the rest of the duplicated ones fail silently and all unique docs are created.

7097.js

#!/usr/bin/env node
'use strict';

const assert = require('assert');
const mongoose = require('mongoose');
mongoose.set('useCreateIndex', true);
const { Schema, connection} = mongoose;
const DB = '7097';
const URI = `mongodb://localhost:27017/${DB}`;
const OPTS = { family: 4, useNewUrlParser: true };

const schema = new Schema({
  name: {
    type: String,
    unique: true
  }
}, { autoIndex: false });

const tests = '122344445667889'.split('').map(n => { return { name: `test${n}`};});
const compare = '123456789'.split('').map(d => `test${d}`);

const errors = [];
function error(e) {
  console.dir(e);
  errors.push(e.message);
}

async function run() {
  assert.strictEqual(mongoose.version, '5.3.1');
  await mongoose.connect(URI, OPTS);
  await connection.dropDatabase();
  const Test = mongoose.model('test', schema);
  await Test.createIndexes();
  await Test.create(tests).catch(error);

  let created = await Test.find({}).lean();
  assert.strictEqual(created.length, 9);
  assert.deepStrictEqual(created.map(d => d.name), compare);
  assert.strictEqual(errors.length, 1);
  assert.ok(/^E11000/.test(errors[0]));
  console.log('All Assertions Pass');
  await connection.close();
}

run().catch(e => { console.error(e); return connection.close();});

Output:

issues: ./7097.js
{ MongoError: E11000 duplicate key error index: 7097.tests.$name_1 dup key: { : "test2" }
    at Function.create (/Users/lineus/dev/node/mongoose/node_modules/mongodb-core/lib/error.js:43:12)
    at toError (/Users/lineus/dev/node/mongoose/node_modules/mongodb/lib/utils.js:149:22)
    at coll.s.topology.insert (/Users/lineus/dev/node/mongoose/node_modules/mongodb/lib/operations/collection_ops.js:827:39)
    at /Users/lineus/dev/node/mongoose/node_modules/mongodb-core/lib/connection/pool.js:532:18
    at process._tickCallback (internal/process/next_tick.js:61:11)
  driver: true,
  name: 'MongoError',
  index: 0,
  code: 11000,
  errmsg:
   'E11000 duplicate key error index: 7097.tests.$name_1 dup key: { : "test2" }',
  [Symbol(mongoErrorContextSymbol)]: {} }
All Assertions Pass
issues:

@lineus lineus added the enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature label Oct 7, 2018
@vkarpov15
Copy link
Collaborator

@lineus we could just add a list of saved docs and a list of docs that failed to save in the error. Thoughts?

@vkarpov15 vkarpov15 added this to the 5.x Unprioritized milestone Oct 11, 2018
@lineus
Copy link
Collaborator

lineus commented Oct 12, 2018

sounds good to me. I'll take a stab at it.

@lineus lineus self-assigned this Oct 13, 2018
@vkarpov15 vkarpov15 modified the milestones: 5.x Unprioritized, 6.0 Aug 16, 2020
@vkarpov15 vkarpov15 modified the milestones: 6.0, 5.x Unprioritized Jan 13, 2021
hasezoey added a commit to hasezoey/mongoose that referenced this issue Jun 26, 2023
@vkarpov15
Copy link
Collaborator

#13544 adds an aggregateErrors option that should fix this one. Like @lineus mentioned, Model.create() does always create all valid documents, just without aggregateErrors option create() will throw the first error it gets, but it won't cancel the insertion of the other documents.

@vkarpov15 vkarpov15 modified the milestones: 7.x Unprioritized, 7.4.0 Jul 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants