如何在Mongoose中更新/更新文档?

本文翻译自:How do I update/upsert a document in Mongoose?

Perhaps it's the time, perhaps it's me drowning in sparse documentation and not being able to wrap my head around the concept of updating in Mongoose :) 也许是时候了,也许是我淹没在稀疏的文档中,无法将自己的头围在Mongoose中的更新概念上:)

Here's the deal: 这是交易:

I have a contact schema and model (shortened properties): 我有一个联系模式和模型(缩短的属性):

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

var mongooseTypes = require("mongoose-types"),
    useTimestamps = mongooseTypes.useTimestamps;


var ContactSchema = new Schema({
    phone: {
        type: String,
        index: {
            unique: true,
            dropDups: true
        }
    },
    status: {
        type: String,
        lowercase: true,
        trim: true,
        default: 'on'
    }
});
ContactSchema.plugin(useTimestamps);
var Contact = mongoose.model('Contact', ContactSchema);

I receive a request from the client, containing the fields I need and use my model thusly: 我从客户端收到一个包含我需要的字段的请求,并因此使用我的模型:

mongoose.connect(connectionString);
var contact = new Contact({
    phone: request.phone,
    status: request.status
});

And now we reach the problem: 现在我们解决了这个问题:

  1. If I call contact.save(function(err){...}) I'll receive an error if the contact with the same phone number already exists (as expected - unique) 如果我致电contact.save(function(err){...})如果具有相同电话号码的联系人已经存在(如预期-唯一),我将收到一条错误消息
  2. I can't call update() on contact, since that method does not exist on a document 我无法在联系人上调用update() ,因为该方法在文档中不存在
  3. If I call update on the model: 如果我调用模型更新:
    Contact.update({phone:request.phone}, contact, {upsert: true}, function(err{...})
    I get into an infinite loop of some sorts, since the Mongoose update implementation clearly doesn't want an object as the second parameter. 我进入某种无限循环,因为Mongoose更新实现显然不希望将对象作为第二个参数。
  4. If I do the same, but in the second parameter I pass an associative array of the request properties {status: request.status, phone: request.phone ...} it works - but then I have no reference to the specific contact and cannot find out its createdAt and updatedAt properties. 如果我做同样的事情,但是在第二个参数中,我传递了一个请求属性的关联数组{status: request.status, phone: request.phone ...}它可以工作-但是我没有引用特定的联系人,并且无法找出其createdAtupdatedAt性能。

So the bottom line, after all I tried: given a document contact , how do I update it if it exists, or add it if it doesn't? 因此,在尝试了所有操作之后,最重要的是:给定一个文档contact ,如果存在它,如何更新它;如果不存在,如何添加它?

Thanks for your time. 谢谢你的时间。


#1楼

参考:https://stackoom.com/question/UUVK/如何在Mongoose中更新-更新文档


#2楼

After reading the posts above, I decided to use this code: 阅读以上内容后,我决定使用此代码:

    itemModel.findOne({'pid':obj.pid},function(e,r){
        if(r!=null)
        {
             itemModel.update({'pid':obj.pid},obj,{upsert:true},cb);
        }
        else
        {
            var item=new itemModel(obj);
            item.save(cb);
        }
    });

if r is null, we create new item. 如果r为null,则创建新项目。 Otherwise, use upsert in update because update does not create new item. 否则,请在更新中使用upsert,因为更新不会创建新项目。


#3楼

I needed to update/upsert a document into one collection, what I did was to create a new object literal like this: 我需要将文档更新/更新到一个集合中,我要做的是创建一个像这样的新对象文字:

notificationObject = {
    user_id: user.user_id,
    feed: {
        feed_id: feed.feed_id,
        channel_id: feed.channel_id,
        feed_title: ''
    }
};

composed from data that I get from somewhere else in my database and then call update on the Model 由我从数据库其他地方获取的数据组成,然后在模型上调用update

Notification.update(notificationObject, notificationObject, {upsert: true}, function(err, num, n){
    if(err){
        throw err;
    }
    console.log(num, n);
});

this is the ouput that I get after running the script for the first time: 这是我第一次运行脚本后得到的输出:

1 { updatedExisting: false,
    upserted: 5289267a861b659b6a00c638,
    n: 1,
    connectionId: 11,
    err: null,
    ok: 1 }

And this is the output when I run the script for the second time: 这是我第二次运行脚本时的输出:

1 { updatedExisting: true, n: 1, connectionId: 18, err: null, ok: 1 }

I'm using mongoose version 3.6.16 我正在使用猫鼬版本3.6.16


#4楼

This coffeescript works for me with Node - the trick is that the _id get's stripped of its ObjectID wrapper when sent and returned from the client and so this needs to be replaced for updates (when no _id is provided, save will revert to insert and add one). 这个coffeescript对Node来说对我有用-诀窍是_id get从客户端发送和返回时剥去了它的ObjectID包装器,因此需要替换以进行更新(当未提供_id时,保存将恢复为插入和添加一)。

app.post '/new', (req, res) ->
    # post data becomes .query
    data = req.query
    coll = db.collection 'restos'
    data._id = ObjectID(data._id) if data._id

    coll.save data, {safe:true}, (err, result) ->
        console.log("error: "+err) if err
        return res.send 500, err if err

        console.log(result)
        return res.send 200, JSON.stringify result

#5楼

There is a bug introduced in 2.6, and affects to 2.7 as well 2.6中引入了一个错误,该错误也影响到2.7

The upsert used to work correctly on 2.4 该upsert在2.4上正常工作

https://groups.google.com/forum/#!topic/mongodb-user/UcKvx4p4hnY https://jira.mongodb.org/browse/SERVER-13843 https://groups.google.com/forum/#!topic/mongodb-user/UcKvx4p4hnY https://jira.mongodb.org/browse/SERVER-13843

Take a look, it contains some important info 看一下,其中包含一些重要信息

UPDATED: 更新:

It doesnt mean upsert does not work. 这并不意味着upsert不起作用。 Here is a nice example of how to use it: 这是一个很好的用法示例:

User.findByIdAndUpdate(userId, {online: true, $setOnInsert: {username: username, friends: []}}, {upsert: true})
    .populate('friends')
    .exec(function (err, user) {
        if (err) throw err;
        console.log(user);

        // Emit load event

        socket.emit('load', user);
    });

#6楼

Mongoose now supports this natively with findOneAndUpdate (calls MongoDB findAndModify ). Mongoose现在通过findOneAndUpdate原生支持此功能 (调用MongoDB findAndModify )。

The upsert = true option creates the object if it doesn't exist. 如果不存在upsert = true选项,则会创建该对象。 defaults to false . 默认为false

var query = {'username': req.user.username};
req.newData.username = req.user.username;

MyModel.findOneAndUpdate(query, req.newData, {upsert: true}, function(err, doc) {
    if (err) return res.send(500, {error: err});
    return res.send('Succesfully saved.');
});

In older versions Mongoose does not support these hooks with this method: 在较旧的版本中,Mongoose不支持使用以下方法的这些钩子:

  • defaults 默认值
  • setters 二传手
  • validators 验证者
  • middleware 中间件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值