NilsH NilsH - 1 year ago 102
Node.js Question

Partial update of a subdocument with nodejs/mongoose

Is it possible to set multiple properties on a (sub)document in one go with Mongoose? An example of what I'm trying to do:

Let's say I have this schema:

var subSchema = new Schema({
someField: String,
someOtherField: String

var parentSchema = new Schema({
fieldOne: String,
subDocs: [subSchema]

Then I would like to do:

exports.updateMyDocument = function(req, res) {
var parentDoc = req.parentDoc; // The parent document. Set by parameter resolver.
var document = req.myDoc; // Sub document of parent. Set by parameter resolver.
var partialUpdate = req.body; // updated fields sent as json and parsed by body parser
// I know that the statement below doesn't work, it's just an example of what I would like to do.
// Updating only the fields supplied in "partialUpdate" on the document
document.update(partialUpdate); {
if(err) {

Normally, I could achieve this using the
operator, but my problem is that
in this example is a subdocument (embedded schema) of
. So when I tried to do

Parent.update({_id: parentDoc._id, "subDocs._id": document._id},
{$set: {"subDocs.$" : partialUpdate}},
function(err, numAffected) {});

it replaced the subdocument instance identified by
. Currently I have "solved" it by setting only fields manually, but I was hoping for a better way to do this.

Answer Source

Build up a $set object programmatically based on the fields of partialUpdate to update just those fields using dot notation:

var set = {};
for (var field in partialUpdate) {
  set['subDocs.$.' + field] = partialUpdate[field];
Parent.update({_id: parentDoc._id, "subDocs._id": document._id}, 
    {$set: set}, 
    function(err, numAffected) {});
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download