Maria Jane
Maria Jane

Reputation: 2403

mongoose save vs insert vs create

What are different ways to insert a document(record) into MongoDB using Mongoose?

My current attempt:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var notificationsSchema = mongoose.Schema({
    "datetime" : {
        type: Date,
        default: Date.now
    },
    "ownerId":{
        type:String
    },
    "customerId" : {
        type:String
    },
    "title" : {
        type:String
    },
    "message" : {
        type:String
    }
});

var notifications = module.exports = mongoose.model('notifications', notificationsSchema);

module.exports.saveNotification = function(notificationObj, callback){
    //notifications.insert(notificationObj); won't work
    //notifications.save(notificationObj); won't work
    notifications.create(notificationObj); //work but created duplicated document
}

Any idea why insert and save doesn't work in my case? I tried create, it inserted 2 document instead of 1. That's strange.

Upvotes: 80

Views: 115605

Answers (4)

grumpyTofu
grumpyTofu

Reputation: 1115

TLDR: Use Create (save is expert-mode)

The main difference between using the create and save methods in Mongoose is that create is a convenience method that automatically calls new Model() and save() for you, while save is a method that is called on a Mongoose document instance.

When you call the create method on a Mongoose model, it creates a new instance of the model, sets the properties, and then saves the document to the database. This method is useful when you want to create a new document and insert it into the database in one step. This makes the creation an atomic transaction. Therefore, the save method leaves the potential to create inefficiencies/inconsistencies in your code.

On the other hand, the save method is called on an instance of a Mongoose document, after you have made changes to it. This method will validate the document and save the changes to the database.

Another difference is that create method can insert multiple documents at once, by passing an array of documents as parameter, while save is intended to be used on a single document.

So, if you want to create a new instance of a model and save it to the database in one step, you can use the create method. If you have an existing instance of a model that you want to save to the database, you should use the save method.

Also, if you have any validation or pre-save hook in your content schema, this will be triggered when using the create method.

Upvotes: 12

I.sh.
I.sh.

Reputation: 1993

I'm quoting Mongoose's Constructing Documents documentation:

const Tank = mongoose.model('Tank', yourSchema);

const small = new Tank({ size: 'small' });
small.save(function (err) {
  if (err) return handleError(err);
  // saved!
});

// or

Tank.create({ size: 'small' }, function (err, small) {
  if (err) return handleError(err);
  // saved!
});

// or, for inserting large batches of documents
Tank.insertMany([{ size: 'small' }], function(err) {

});

Upvotes: 4

Dulanjana_Bandara
Dulanjana_Bandara

Reputation: 107

You can either use save() or create().

save() can only be used on a new document of the model while create() can be used on the model. Below, I have given a simple example.

Tour Model

const mongoose = require("mongoose");

const tourSchema = new mongoose.Schema({
  name: {
    type: String,
    required: [true, "A tour must have a name"],
    unique: true,
  },
  rating: {
    type: Number,
    default:3.0,
  },
  price: {
    type: Number,
    required: [true, "A tour must have a price"],
  },
});

const Tour = mongoose.model("Tour", tourSchema);

module.exports = Tour;

Tour Controller

const Tour = require('../models/tourModel');

exports.createTour = async (req, res) => {
  // method 1
  const newTour = await Tour.create(req.body);

  // method 2
  const newTour = new Tour(req.body);
  await newTour.save();
}

Make sure to use either Method 1 or Method 2.

Upvotes: 10

Iceman
Iceman

Reputation: 6145

The .save() is an instance method of the model, while the .create() is called directly from the Model as a method call, being static in nature, and takes the object as a first parameter.

var mongoose = require('mongoose');

var notificationSchema = mongoose.Schema({
    "datetime" : {
        type: Date,
        default: Date.now
    },
    "ownerId":{
        type:String
    },
    "customerId" : {
        type:String
    },
    "title" : {
        type:String
    },
    "message" : {
        type:String
    }
});

var Notification = mongoose.model('Notification', notificationsSchema);


function saveNotification1(data) {
    var notification = new Notification(data);
    notification.save(function (err) {
        if (err) return handleError(err);
        // saved!
    })
}

function saveNotification2(data) {
    Notification.create(data, function (err, small) {
    if (err) return handleError(err);
    // saved!
    })
}

Export whatever functions you would want outside.

More at the Mongoose Docs, or consider reading the reference of the Model prototype in Mongoose.

Upvotes: 101

Related Questions