Как мне обновить / сохранить документ в Mongoose? - PullRequest
313 голосов
/ 01 сентября 2011

Возможно, пришло время, возможно, я тону в редких документациях и не могу обернуться вокруг концепции обновления в Mongoose:)

Вот сделка:

У меня естьсхема и модель контакта (сокращенные свойства):

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

Я получаю запрос от клиента, содержащий необходимые мне поля, и использую свою модель таким образом:

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

А теперь мырешить проблему:

  1. Если я позвоню contact.save(function(err){...}) Я получу сообщение об ошибке, если контакт с таким же номером телефона уже существует (как и ожидалось - уникальный)
  2. Я могу 'Вызовите update() для контакта, так как этот метод не существует в документе
  3. Если я вызову обновление для модели:
    Contact.update({phone:request.phone}, contact, {upsert: true}, function(err{...})
    Я попаду в бесконечный цикл некоторых видов,поскольку реализация обновления Mongoose явно не хочет использовать объект в качестве второго параметра.
  4. Если я делаю то же самое, но во втором параметре я передаю ассоциативный массив свойств запроса {status: request.status, phone: request.phone ...}, это работает - нотогда я не имеюпривязанность к конкретному контакту и не может выяснить его свойства createdAt и updatedAt.

Итак, в конце концов, после всего, что я пытался: учитывая документ contact, как мне его обновитьесли он существует, или добавить его, если его нет?

Спасибо за ваше время.

Ответы [ 23 ]

0 голосов
/ 17 апреля 2017

на основе того, что написал Мартин Куздович выше.Я использую следующее для обновления с помощью mongoose и глубокого слияния объектов json.Наряду с функцией model.save () в mongoose это позволяет mongoose выполнять полную проверку, даже если она основана на других значениях в json.для этого требуется пакет Deepmerge https://www.npmjs.com/package/deepmerge. Но это очень легкий пакет.

var merge = require('deepmerge');

app.put('url', (req, res) => {

    const modelId = req.body.model_id;

    MyModel.findById(modelId).then((model) => {
        return Object.assign(model, merge(model.toObject(), req.body));
    }).then((model) => {
        return model.save();
    }).then((updatedModel) => {
        res.json({
            msg: 'model updated',
            updatedModel
        });
    }).catch((err) => {
        res.send(err);
    });
});
0 голосов
/ 23 сентября 2013

После прочтения постов выше, я решил использовать этот код:

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

, если r равно нулю, мы создаем новый элемент.В противном случае используйте upsert в обновлении, потому что обновление не создает новый элемент.

0 голосов
/ 18 марта 2014

Этот 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...