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

feat(model): add insertOne() function to insert a single doc #15162

Merged
merged 4 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -2774,6 +2774,49 @@ Model.create = async function create(doc, options) {
return res;
};

/**
* Shortcut for saving one document to the database.
* `MyModel.insertOne(obj, options)` is almost equivalent to `new MyModel(obj).save(options)`.
* The difference is that `insertOne()` checks if `obj` is already a document, and checks for discriminators.
*
* This function triggers the following middleware.
*
* - `save()`
*
* #### Example:
*
* // Insert one new `Character` document
* await Character.insertOne({ name: 'Jean-Luc Picard' });
*
* // Create a new character within a transaction.
* await Character.insertOne({ name: 'Jean-Luc Picard' }, { session });
*
* @param {Object|Document} docs Document to insert, as a POJO or Mongoose document
vkarpov15 marked this conversation as resolved.
Show resolved Hide resolved
* @param {Object} [options] Options passed down to `save()`.
* @return {Promise}
* @api public
*/

Model.insertOne = async function insertOne(doc, options) {
_checkContext(this, 'insertOne');

const discriminatorKey = this.schema.options.discriminatorKey;
const Model = this.discriminators && doc[discriminatorKey] != null ?
this.discriminators[doc[discriminatorKey]] || getDiscriminatorByValue(this.discriminators, doc[discriminatorKey]) :
this;
if (Model == null) {
throw new MongooseError(
`Discriminator "${doc[discriminatorKey]}" not found for model "${this.modelName}"`
);
}
let toSave = doc;
vkarpov15 marked this conversation as resolved.
Show resolved Hide resolved
if (!(toSave instanceof Model)) {
toSave = new Model(toSave);
}

return await toSave.$save(options);
};

/**
* _Requires a replica set running MongoDB >= 3.6.0._ Watches the
* underlying collection for changes using
Expand Down
31 changes: 31 additions & 0 deletions test/model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8461,6 +8461,37 @@ describe('Model', function() {
assert.deepStrictEqual(toDrop, []);
});
});

describe('insertOne() (gh-14843)', function() {
it('should insert a new document', async function() {
const userSchema = new Schema({
name: String
});
const User = db.model('User', userSchema);

const res = await User.insertOne({ name: 'John' });
assert.ok(res instanceof User);

const doc = await User.findOne({ _id: res._id });
assert.equal(doc.name, 'John');
});

it('should support validateBeforeSave: false option', async function() {
const userSchema = new Schema({
name: {
type: String,
required: true
}
});
const User = db.model('User', userSchema);

const res = await User.insertOne({}, { validateBeforeSave: false });
assert.ok(res instanceof User);

const doc = await User.findOne({ _id: res._id });
assert.equal(doc.name, undefined);
});
});
});


Expand Down
10 changes: 10 additions & 0 deletions test/types/models.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -988,3 +988,13 @@ async function gh14802() {
const conn2 = mongoose.createConnection('mongodb://127.0.0.1:27017/mongoose_test');
Model.useConnection(conn2);
}

async function gh14843() {
const schema = new mongoose.Schema({
name: String
});
const Model = model('Test', schema);

const doc = await Model.insertOne({ name: 'taco' });
expectType<ReturnType<(typeof Model)['hydrate']>>(doc);
}
2 changes: 2 additions & 0 deletions types/models.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,8 @@ declare module 'mongoose' {
Array<MergeType<THydratedDocumentType, Omit<DocContents, '_id'>>>
>;

insertOne<DocContents = AnyKeys<TRawDocType>>(doc: DocContents | TRawDocType, options?: SaveOptions): Promise<THydratedDocumentType>;
vkarpov15 marked this conversation as resolved.
Show resolved Hide resolved

/**
* List all [Atlas search indexes](https://www.mongodb.com/docs/atlas/atlas-search/create-index/) on this model's collection.
* This function only works when connected to MongoDB Atlas.
Expand Down
Loading