Làm cách nào để cập nhật / upert một tài liệu trong Mongoose?


367

Có lẽ đã đến lúc, có lẽ đó là tôi chìm đắm trong tài liệu thưa thớt và không thể che giấu khái niệm cập nhật trong Mongoose :)

Đây là thỏa thuận:

Tôi có một lược đồ và mô hình liên hệ (thuộc tính rút gọn):

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

Tôi nhận được yêu cầu từ khách hàng, chứa các trường tôi cần và sử dụng mô hình của tôi như vậy:

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

Và bây giờ chúng ta đạt được vấn đề:

  1. Nếu tôi gọi, contact.save(function(err){...})tôi sẽ nhận được lỗi nếu liên hệ có cùng số điện thoại đã tồn tại (như mong đợi - duy nhất)
  2. Tôi không thể gọi update()liên lạc, vì phương pháp đó không tồn tại trên một tài liệu
  3. Nếu tôi gọi cập nhật trên mô hình:
    Contact.update({phone:request.phone}, contact, {upsert: true}, function(err{...})
    Tôi nhận được một vòng lặp vô hạn của một số loại, vì việc triển khai cập nhật Mongoose rõ ràng không muốn một đối tượng là tham số thứ hai.
  4. Nếu tôi làm tương tự, nhưng trong tham số thứ hai, tôi chuyển một mảng kết hợp của các thuộc tính yêu cầu, {status: request.status, phone: request.phone ...}nó hoạt động - nhưng sau đó tôi không có tham chiếu đến liên hệ cụ thể và không thể tìm ra thuộc tính createdAtupdatedAtthuộc tính của nó .

Vì vậy, điểm mấu chốt, sau tất cả những gì tôi đã thử: đưa ra một tài liệu contact, làm cách nào để cập nhật nó nếu nó tồn tại hoặc thêm nó nếu nó không có?

Cảm ơn vì đã dành thời gian cho tôi.


Những gì về hooking trong precho save?
Shamoon

Câu trả lời:


427

Mongoose hiện hỗ trợ điều này một cách tự nhiên với findOneAndUpdate (gọi MongoDB findAndModify ).

Tùy chọn upsert = true tạo đối tượng nếu nó không tồn tại. giá trị mặc định là 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.');
});

Trong các phiên bản cũ, Mongoose không hỗ trợ các hook này bằng phương thức này:

  • mặc định
  • setters
  • người xác nhận
  • phần mềm trung gian

17
Đây phải là câu trả lời cập nhật. Hầu hết những người khác sử dụng hai cuộc gọi hoặc (tôi tin) rơi trở lại trình điều khiển mongodb bản địa.
huggie

10
vấn đề với findOneAndUpdate là việc lưu trước sẽ không được thực thi.
a77icu5

2
Nghe có vẻ như một lỗi trong Mongoose hoặc MongoDB?
Pascalius

8
Từ các tài liệu: "... khi sử dụng trình trợ giúp findAndModify, những điều sau đây không được áp dụng: mặc định, setters, trình xác nhận, phần mềm trung gian" mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate
kellen

2
@JamieHutber Điều này không được đặt theo mặc định, đây là một thuộc tính tùy chỉnh
Pascalius

194

Tôi chỉ đốt cháy được 3 tiếng đồng hồ để cố gắng giải quyết vấn đề tương tự. Cụ thể, tôi muốn "thay thế" toàn bộ tài liệu nếu nó tồn tại hoặc chèn nó vào tài liệu khác. Đây là giải pháp:

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

// Convert the Model instance to a simple object using Model's 'toObject' function
// to prevent weirdness like infinite looping...
var upsertData = contact.toObject();

// Delete the _id property, otherwise Mongo will return a "Mod on _id not allowed" error
delete upsertData._id;

// Do the upsert, which works like this: If no Contact document exists with 
// _id = contact.id, then create a new doc using upsertData.
// Otherwise, update the existing doc with upsertData
Contact.update({_id: contact.id}, upsertData, {upsert: true}, function(err{...});

Tôi đã tạo một vấn đề trên trang dự án Mongoose yêu cầu thông tin về điều này được thêm vào tài liệu.


1
Tài liệu có vẻ nghèo tại thời điểm này. Có một số tài liệu API (tìm kiếm "cập nhật" trên trang. Trông như thế này: MyModel.update({ age: { $gt: 18 } }, { oldEnough: true }, fn);MyModel.update({ name: 'Tobi' }, { ferret: true }, { multi: true }, fn);
CpILL

đối với tài liệu trường hợp không được tìm thấy, _id nào được sử dụng? Mongoose tạo ra nó hay cái được truy vấn?
Haider

91

Bạn đã thân với

Contact.update({phone:request.phone}, contact, {upsert: true}, function(err){...})

nhưng tham số thứ hai của bạn phải là một đối tượng với toán tử sửa đổi chẳng hạn

Contact.update({phone:request.phone}, {$set: { phone: request.phone }}, {upsert: true}, function(err){...})

15
Tôi không nghĩ rằng bạn cần có {$set: ... }một phần ở đây là hình thức tự động nó đọc sách của tôi
CpILL 15/03/2016

5
Vâng, mongoose nói rằng nó biến mọi thứ thành $ set
Grantwparks

1
Điều này hợp lệ tại thời điểm viết bài, tôi không sử dụng MongoDB nữa nên tôi không thể nói về những thay đổi trong những tháng gần đây: D
chrixian

5
Không sử dụng $ set có thể là một thói quen xấu nếu bạn thỉnh thoảng vẫn sử dụng trình điều khiển gốc.
UpTheCux

Bạn có thể sử dụng $ set và $ setOnInsert để chỉ đặt một số trường nhất định trong trường hợp chèn
justin.m.chase

73

Chà, tôi đã đợi đủ lâu và không có câu trả lời. Cuối cùng đã từ bỏ toàn bộ cách tiếp cận cập nhật / upert và đi với:

ContactSchema.findOne({phone: request.phone}, function(err, contact) {
    if(!err) {
        if(!contact) {
            contact = new ContactSchema();
            contact.phone = request.phone;
        }
        contact.status = request.status;
        contact.save(function(err) {
            if(!err) {
                console.log("contact " + contact.phone + " created at " + contact.createdAt + " updated at " + contact.updatedAt);
            }
            else {
                console.log("Error: could not save contact " + contact.phone);
            }
        });
    }
});

Nó có hoạt động không? Vâng. Tôi có hạnh phúc với điều này? Chắc là không. 2 cuộc gọi DB thay vì một.
Hy vọng rằng một triển khai Mongoose trong tương lai sẽ đưa ra một Model.upsertchức năng.


2
Ví dụ này sử dụng giao diện được thêm vào trong MongoDB 2.2 để chỉ định các tùy chọn đa và nâng cấp trong một biểu mẫu tài liệu. .. bao gồm :: /includes/fact-upsert-multi-options.rst Tài liệu nêu rõ điều này, không biết phải đi đâu từ đây.
Donald Derek

1
Mặc dù điều này sẽ hoạt động, nhưng bạn hiện đang chạy 2 thao tác (tìm, cập nhật) khi chỉ cần 1 (upsert). @chrixian chỉ ra cách chính xác để làm điều này.
tôn trọng TheCode

12
Điều đáng chú ý rằng đây là câu trả lời duy nhất cho phép trình xác nhận của Mongoose khởi động. Theo tài liệu , xác thực không xảy ra nếu bạn gọi cập nhật.
Tom Spencer

@fiznool có vẻ như bạn có thể chuyển thủ công tùy chọn runValidators: truetrong quá trình cập nhật: cập nhật tài liệu (tuy nhiên, trình xác nhận cập nhật chỉ chạy trên $set$unsethoạt động)
Danny

Xem câu trả lời của tôi dựa trên câu hỏi này nếu bạn cần .upsert()có sẵn trên tất cả các mô hình. stackoverflow.com/a/50208331/1586406
spondbob

24

Giải pháp rất thanh lịch bạn có thể đạt được bằng cách sử dụng chuỗi Lời hứa:

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

    const modelId = req.body.model_id;
    const newName = req.body.name;

    MyModel.findById(modelId).then((model) => {
        return Object.assign(model, {name: newName});
    }).then((model) => {
        return model.save();
    }).then((updatedModel) => {
        res.json({
            msg: 'model updated',
            updatedModel
        });
    }).catch((err) => {
        res.send(err);
    });
});

Tại sao điều này không được nêu lên? Có vẻ như là một giải pháp tuyệt vời và rất thanh lịch
MadOgre

Giải pháp tuyệt vời, thực sự khiến tôi suy nghĩ lại về cách tôi tiếp cận lời hứa.
lux

4
Thậm chí thanh lịch hơn sẽ được viết lại (model) => { return model.save(); }như model => model.save(), và cũng (err) => { res.send(err); }như err => res.send(err);)
Jeremy Thille

1
Tôi có thể lấy thêm thông tin ở đâu?
V0LT3RR4

17

Tôi là người duy trì Mongoose. Cách hiện đại hơn để nâng cấp tài liệu là sử dụng Model.updateOne()hàm .

await Contact.updateOne({
    phone: request.phone
}, { status: request.status }, { upsert: true });

Nếu bạn cần tài liệu nâng cấp, bạn có thể sử dụng Model.findOneAndUpdate()

const doc = await Contact.findOneAndUpdate({
    phone: request.phone
}, { status: request.status }, { upsert: true });

Điểm đáng chú ý là bạn cần đặt các thuộc tính duy nhất trong filtertham số đến updateOne()hoặc findOneAndUpdate()và các thuộc tính khác trong updatetham số.

Đây là một hướng dẫn về nâng cấp tài liệu với Mongoose .


15

Tôi đã tạo một tài khoản StackOverflow CHỈ để trả lời câu hỏi này. Sau khi vô vọng tìm kiếm các interwebs, tôi chỉ tự viết một cái gì đó. Đây là cách tôi đã làm để nó có thể được áp dụng cho bất kỳ mô hình cầy mangut nào. Nhập hàm này hoặc thêm trực tiếp vào mã của bạn nơi bạn đang thực hiện cập nhật.

function upsertObject (src, dest) {

  function recursiveFunc (src, dest) {
    _.forOwn(src, function (value, key) {
      if(_.isObject(value) && _.keys(value).length !== 0) {
        dest[key] = dest[key] || {};
        recursiveFunc(src[key], dest[key])
      } else if (_.isArray(src) && !_.isObject(src[key])) {
          dest.set(key, value);
      } else {
        dest[key] = value;
      }
    });
  }

  recursiveFunc(src, dest);

  return dest;
}

Sau đó, để nâng cấp một tài liệu cầy mangut làm như sau,

YourModel.upsert = function (id, newData, callBack) {
  this.findById(id, function (err, oldData) {
    if(err) {
      callBack(err);
    } else {
      upsertObject(newData, oldData).save(callBack);
    }
  });
};

Giải pháp này có thể yêu cầu 2 cuộc gọi DB tuy nhiên bạn có được lợi ích của,

  • Xác thực lược đồ đối với mô hình của bạn vì bạn đang sử dụng .save ()
  • Bạn có thể nâng cấp các đối tượng được lồng sâu mà không cần liệt kê thủ công trong lệnh gọi cập nhật của mình, vì vậy nếu mô hình của bạn thay đổi, bạn không phải lo lắng về việc cập nhật mã của mình

Chỉ cần nhớ rằng đối tượng đích sẽ luôn ghi đè nguồn ngay cả khi nguồn có giá trị hiện có

Ngoài ra, đối với mảng, nếu đối tượng hiện tại có mảng dài hơn mảng thay thế thì các giá trị ở cuối mảng cũ sẽ vẫn còn. Một cách dễ dàng để nâng cấp toàn bộ mảng là đặt mảng cũ thành một mảng trống trước upert nếu đó là những gì bạn đang dự định làm.

CẬP NHẬT - 16/1/2016 Tôi đã thêm một điều kiện bổ sung nếu có một mảng các giá trị nguyên thủy, Mongoose không nhận ra mảng được cập nhật mà không sử dụng chức năng "set".


2
+1 để tạo acc chỉ cho việc này: P Ước gì tôi có thể cung cấp +1 khác chỉ bằng cách sử dụng .save (), becaunse findOneAndUpate () khiến chúng tôi không thể sử dụng trình xác thực và các công cụ trước, đăng, v.v. Cảm ơn, tôi cũng sẽ kiểm tra điều này
1576978

Xin lỗi, nhưng nó không hoạt động ở đây :( Tôi đã vượt quá kích thước ngăn xếp cuộc gọi
user1576978 7/07/2015

Phiên bản nào của lodash bạn đang sử dụng? Tôi đang sử dụng phiên bản lodash 2.4.1 Cảm ơn!
Aaron Mast

Ngoài ra, làm thế nào phức tạp của các đối tượng bạn đang nâng cấp? Nếu chúng quá lớn, quy trình nút có thể không thể xử lý số lượng cuộc gọi đệ quy cần thiết để hợp nhất các đối tượng.
Aaron Mast

Tôi đã sử dụng điều này, nhưng phải thêm if(_.isObject(value) && _.keys(value).length !== 0) {vào điều kiện bảo vệ để ngăn chặn tràn ngăn xếp. Ở đây, có vẻ như chuyển đổi các giá trị phi đối tượng thành các đối tượng trong lệnh keysgọi để bảo vệ đệ quy luôn luôn đúng. Có lẽ có một cách tốt hơn, nhưng nó gần như làm việc với tôi bây giờ ...
Richard G

12

Tôi cần cập nhật / nâng cấp một tài liệu thành một bộ sưu tập, điều tôi đã làm là tạo ra một đối tượng mới theo nghĩa đen như sau:

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

được tạo từ dữ liệu mà tôi nhận được từ một nơi khác trong cơ sở dữ liệu của mình và sau đó gọi cập nhật trên Model

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

đây là thông số mà tôi nhận được sau khi chạy tập lệnh lần đầu tiên:

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

Và đây là đầu ra khi tôi chạy tập lệnh lần thứ hai:

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

Tôi đang sử dụng cầy mangut phiên bản 3.6.16


10
app.put('url', function(req, res) {

        // use our bear model to find the bear we want
        Bear.findById(req.params.bear_id, function(err, bear) {

            if (err)
                res.send(err);

            bear.name = req.body.name;  // update the bears info

            // save the bear
            bear.save(function(err) {
                if (err)
                    res.send(err);

                res.json({ message: 'Bear updated!' });
            });

        });
    });

Dưới đây là một cách tiếp cận tốt hơn để giải quyết phương pháp cập nhật trong mongoose, bạn có thể kiểm tra Scotch.io để biết thêm chi tiết. Điều này chắc chắn làm việc cho tôi !!!


5
Thật sai lầm khi nghĩ rằng điều này thực hiện tương tự như cập nhật của MongoDB. Nó không phải là nguyên tử.
Valentin Waeselynck

1
Tôi muốn sao lưu câu trả lời @ValentinWaeselynck. Mã của Scotch sạch - nhưng bạn đang tìm nạp tài liệu và sau đó cập nhật. Ở giữa quá trình đó, tài liệu có thể được thay đổi.
Nick Pineda

8

Có một lỗi được giới thiệu trong 2.6 và cũng ảnh hưởng đến 2.7

Upert được sử dụng để hoạt động chính xác trên 2.4

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

Hãy xem, nó chứa một số thông tin quan trọng

CẬP NHẬT:

Nó không có nghĩa là upsert không hoạt động. Đây là một ví dụ hay về cách sử dụng nó:

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

7

Bạn chỉ có thể cập nhật bản ghi với điều này và nhận được dữ liệu cập nhật để đáp ứng

router.patch('/:id', (req, res, next) => {
    const id = req.params.id;
    Product.findByIdAndUpdate(id, req.body, {
            new: true
        },
        function(err, model) {
            if (!err) {
                res.status(201).json({
                    data: model
                });
            } else {
                res.status(500).json({
                    message: "not found any relative data"
                })
            }
        });
});

6

Điều này làm việc cho tôi.

app.put('/student/:id', (req, res) => {
    Student.findByIdAndUpdate(req.params.id, req.body, (err, user) => {
        if (err) {
            return res
                .status(500)
                .send({error: "unsuccessful"})
        };
        res.send({success: "success"});
    });

});


Cảm ơn. Đây là cái cuối cùng đã làm việc cho tôi!
Luis Febro

4

Đây là cách đơn giản nhất để tạo / cập nhật đồng thời gọi phần mềm trung gian và trình xác nhận.

Contact.findOne({ phone: request.phone }, (err, doc) => {
    const contact = (doc) ? doc.set(request) : new Contact(request);

    contact.save((saveErr, savedContact) => {
        if (saveErr) throw saveErr;
        console.log(savedContact);
    });
})

3

Đối với bất kỳ ai đến đây vẫn đang tìm kiếm một giải pháp tốt cho "nâng cấp" với hỗ trợ móc, đây là những gì tôi đã thử nghiệm và làm việc. Nó vẫn yêu cầu 2 cuộc gọi DB nhưng ổn định hơn nhiều so với bất kỳ cuộc gọi nào tôi đã thử trong một cuộc gọi.

// Create or update a Person by unique email.
// @param person - a new or existing Person
function savePerson(person, done) {
  var fieldsToUpdate = ['name', 'phone', 'address'];

  Person.findOne({
    email: person.email
  }, function(err, toUpdate) {
    if (err) {
      done(err);
    }

    if (toUpdate) {
      // Mongoose object have extra properties, we can either omit those props
      // or specify which ones we want to update.  I chose to update the ones I know exist
      // to avoid breaking things if Mongoose objects change in the future.
      _.merge(toUpdate, _.pick(person, fieldsToUpdate));
    } else {      
      toUpdate = person;
    }

    toUpdate.save(function(err, updated, numberAffected) {
      if (err) {
        done(err);
      }

      done(null, updated, numberAffected);
    });
  });
}

3

Nếu có sẵn máy phát điện, nó sẽ trở nên dễ dàng hơn nữa:

var query = {'username':this.req.user.username};
this.req.newData.username = this.req.user.username;
this.body = yield MyModel.findOneAndUpdate(query, this.req.newData).exec();

3

Không có giải pháp khác làm việc cho tôi. Tôi đang sử dụng một yêu cầu bài đăng và cập nhật dữ liệu nếu tìm thấy người khác chèn nó, đồng thời _id được gửi với cơ quan yêu cầu cần phải xóa.

router.post('/user/createOrUpdate', function(req,res){
    var request_data = req.body;
    var userModel = new User(request_data);
    var upsertData = userModel.toObject();
    delete upsertData._id;

    var currentUserId;
    if (request_data._id || request_data._id !== '') {
        currentUserId = new mongoose.mongo.ObjectId(request_data._id);
    } else {
        currentUserId = new mongoose.mongo.ObjectId();
    }

    User.update({_id: currentUserId}, upsertData, {upsert: true},
        function (err) {
            if (err) throw err;
        }
    );
    res.redirect('/home');

});

2
//Here is my code to it... work like ninj

router.param('contractor', function(req, res, next, id) {
  var query = Contractors.findById(id);

  query.exec(function (err, contractor){
    if (err) { return next(err); }
    if (!contractor) { return next(new Error("can't find contractor")); }

    req.contractor = contractor;
    return next();
  });
});

router.get('/contractors/:contractor/save', function(req, res, next) {

    contractor = req.contractor ;
    contractor.update({'_id':contractor._id},{upsert: true},function(err,contractor){
       if(err){ 
            res.json(err);
            return next(); 
            }
    return res.json(contractor); 
  });
});


--

2
User.findByIdAndUpdate(req.param('userId'), req.body, (err, user) => {
    if(err) return res.json(err);

    res.json({ success: true });
});

Mặc dù đoạn mã này có thể giải quyết vấn đề, nhưng nó không giải thích tại sao hoặc làm thế nào để trả lời câu hỏi. Vui lòng bao gồm một lời giải thích cho mã của bạn , vì điều đó thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn. Flaggers / người đánh giá: Đối với các câu trả lời chỉ có mã như câu trả lời này, downvote, đừng xóa!
Patrick

2

Theo câu trả lời của Travelling Tech Guy , điều này thật tuyệt vời, chúng ta có thể tạo một plugin và đính kèm nó vào cầy mangut sau khi chúng ta khởi tạo nó để nó .upsert()có sẵn trên tất cả các mô hình.

plugins.js

export default (schema, options) => {
  schema.statics.upsert = async function(query, data) {
    let record = await this.findOne(query)
    if (!record) {
      record = new this(data)
    } else {
      Object.keys(data).forEach(k => {
        record[k] = data[k]
      })
    }
    return await record.save()
  }
}

db.js

import mongoose from 'mongoose'

import Plugins from './plugins'

mongoose.connect({ ... })
mongoose.plugin(Plugins)

export default mongoose

Sau đó, bạn có thể làm một cái gì đó như User.upsert({ _id: 1 }, { foo: 'bar' })hoặc YouModel.upsert({ bar: 'foo' }, { value: 1 })bất cứ khi nào bạn muốn.


2

Tôi mới trở lại vấn đề này sau một thời gian và quyết định xuất bản một plugin dựa trên câu trả lời của Aaron Mast.

https://www.npmjs.com/package/mongoose-recursive-upsert

Sử dụng nó như một plugin mongoose. Nó thiết lập một phương thức tĩnh sẽ hợp nhất đệ quy đối tượng được truyền vào.

Model.upsert({unique: 'value'}, updateObject});

0

Bản sao này hoạt động với tôi với Node - mẹo là _id bị tước trình bao bọc ObjectID khi được gửi và trả lại từ máy khách và do đó, điều này cần được thay thế để cập nhật (khi không có _id được cung cấp, lưu sẽ hoàn nguyên để chèn và thêm một).

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

0

để xây dựng dựa trên những gì Martin Kuzdowicz đã đăng ở trên. Tôi sử dụng như sau để thực hiện cập nhật bằng cách sử dụng mongoose và hợp nhất sâu các đối tượng json. Cùng với hàm model.save () trong mongoose, điều này cho phép mongoose thực hiện xác nhận đầy đủ ngay cả một giá trị phụ thuộc vào các giá trị khác trong json. nó không yêu cầu gói deepmerge https://www.npmjs.com/package/deepmerge . Nhưng đó là một gói trọng lượng rất nhẹ.

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

1
Tôi nên thận trọng với việc sử dụng nguyên trạng req.body, trước khi thử nghiệm tiêm NoQuery (xem owasp.org/index.php/Testing_for_NoQuery_injection ).
Du lịch Tech Guy

1
@TravelingTechGuy Cảm ơn sự thận trọng Tôi vẫn chưa quen với Node và Mongoose. Không phải mô hình cầy mangut của tôi với trình xác nhận có đủ để bắt một nỗ lực tiêm không? trong mô hình.save ()
Chris Deleo

-5

Sau khi đọc các bài viết ở trên, tôi quyết định sử dụng mã này:

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

Nếu r là null, chúng tôi tạo mục mới. Mặt khác, sử dụng upsert trong bản cập nhật vì bản cập nhật không tạo ra mục mới.


Nếu đó là hai cuộc gọi đến Mongo, thì nó không thực sự khó chịu phải không?
huggie
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.