mongoose的save、insert和create有什么区别?

77

如何使用Mongoose将文档(记录)插入MongoDB?

我的当前尝试:

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
}

有没有想法为什么我的插入和保存不起作用?我试过创建,但它插入了两个文档,而不是一个。这很奇怪。

2
当您多次发布同一问题时,它并没有帮助。http://stackoverflow.com/questions/38290506/mongoose-create-created-multiple-document ... - DAXaholic
2
@DAXaholic 你有关于我的问题的任何线索吗? - Maria Jane
@MariaJane,你能展示一下传递给 notificationObj 的对象的声明吗? - Iceman
@Iceman http://pastebin.com/6PcjYhag - Maria Jane
所以,create和save方法属于mongoose模型对象。你需要创建并保存它。我会发布一个答案。 - Iceman
@MariaJane,请看一下我的回答。 - Iceman
4个回答

101

.save()是模型的实例方法,而.create()则直接从Model中调用作为静态方法,并将对象作为第一个参数。

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!
    })
}

导出你想要在外部使用的任何函数。

更多信息请参见Mongoose文档,或考虑阅读Mongoose中Model原型的参考文献


坦克是从哪里来的? - Maria Jane
问题在于当我使用create时,会在数据库中插入2个文档,有任何想法为什么? - Maria Jane
2
你的回答很有帮助。这是我的错误。你很好地解释了保存和创建,但哪种方式是最好的插入方式? - Maria Jane
7
两者应该表现得等价。记住,对于 .save() 方法,对象必须是模型的实例。因此,你需要格外小心,但好的一面是你可以将它传递给其他函数并在不需要模型变量的情况下保存到任何地方。它更像一个自包含的实体。所以我更喜欢使用 .save() - Iceman
1
当前的Mongoose API中,documentmodel都没有insert。但是有一个insertMany,它本质上是一个验证器和批量输入。我在这里没有涉及它,因为那是一个更“高级”的用例 :)。 - Iceman
显示剩余3条评论

8

TLDR: 使用Create(保存是专家模式)

Mongoose中使用create和save方法的主要区别在于,create是一个方便的方法,它自动为您调用new Model()和save(),而save是在Mongoose文档实例上调用的方法。

当您在Mongoose模型上调用create方法时,它会创建模型的新实例,设置属性,然后将文档保存到数据库中。当您想要创建一个新文档并将其一次性插入到数据库中时,此方法非常有用。这使得创建成为原子事务。因此,save方法留下了在代码中创建低效/不一致性的潜力。

另一方面,save方法是在Mongoose文档实例上调用的,您可以在对其进行更改后调用该方法。此方法将验证文档并保存更改到数据库中。

另一个区别在于,create方法可以通过将文档数组作为参数传递来一次性插入多个文档,而save旨在用于单个文档。

因此,如果您想创建一个新的模型实例并将其一次性保存到数据库中,则可以使用create方法。如果您有一个现有的模型实例,想将其保存到数据库中,则应使用save方法。

此外,如果您的内容架构中有任何验证或预保存钩子,使用create方法时将触发它们。


7

你可以使用save()或者create()方法。

save()只能用于创建一个新的model文档,而create()可以直接用于model。下面给出了一个简单的示例。

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;

导游控制器

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();
}

请务必使用方法1或方法2。


2
每种方法的优缺点是什么? - Mick

2

我在引用Mongoose的构建文档文档:

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) {

});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接