modernator
modernator

Reputation: 4427

MongoDB updating embedded document isn't working

I'm trying to update embedded document, but it is not working. This is what documents look like:

{
    "_id" : ObjectId("577c71735d35de6371388efc"),
    "category" : "A",
    "title" : "Test",
    "content" : "Test",
    "tags" : "test",
    "comments" : [
        {
            "_id" : ObjectId("57811681010bd12923eda0ca"),
            "author" : "creator",
            "email" : "[email protected]",
            "text" : "helloworld!"
        },
        {
            "_id" : ObjectId("57811b17b667676126bde94e"),
            "author" : "creator",
            "email" : "[email protected]",
            "text" : "helloworld2!"
        }
    ],
    "createdAt" : ...,
    "updatedAt" : ...
}

you can see the comments field is embedded document that contains comments. I want to update specific comment, so I made query like this(node.js):

db.update('posts', {
    _id: new ObjectID(postId),    // ID of the post
    comments: {
        $elemMatch: {
            _id: new ObjectId(commentId)
        }
    }
}, {
    $set: {
        "comments.$.author": newComment.author,
        "comments.$.email": newComment.email,
        "comments.$.text": newComment.text,
        "comments.$.updatedAt": new Date()
    }
}) ...

when I run this query, no error was shown but update wasn't applied. I tried this query too:

{
    _id: new ObjectId(postId),
    "comments._id": new ObjectId(commentId)
}

but not worked either. Am I missing something? I'm using Mongo v3.2.7.

Upvotes: 0

Views: 370

Answers (1)

notionquest
notionquest

Reputation: 39226

Please try the below code. I think the "ObjectId" (i.e. case) should be the problem. Just check how you defined the object id and keep it consistent in the two places that you have used (i.e. posts _id and comments _id -> both places).

ObjectID = require('mongodb').ObjectID

The below code works fine for me. Basically, your query seems to be correct.

var Db = require('mongodb').Db, MongoClient = require('mongodb').MongoClient, Server = require('mongodb').Server, ReplSetServers = require('mongodb').ReplSetServers, ObjectID = require('mongodb').ObjectID, Binary = require('mongodb').Binary, GridStore = require('mongodb').GridStore, Grid = require('mongodb').Grid, Code = require('mongodb').Code, assert = require('assert');

var db = new Db('localhost', new Server('localhost', 27017));
db.open(function(err, db) {
    var collection = db.collection("posts");

    var postId = '577c71735d35de6371388efc';
    var commentId = '57811681010bd12923eda0ca';

    var query = {
        _id : new ObjectID(postId), 
        comments : {
            $elemMatch : {
                _id : new ObjectID(commentId)
            }
        }
    };

    collection.update(query, {
        $set : {
            "comments.$.author" : "new author",
            "comments.$.email" : "[email protected]",
            "comments.$.text" : "new email updated",
            "comments.$.updatedAt" : new Date()
        }
    }, {
        multi : false
    }, function(err, item) {        
        assert.equal(null, err);
        console.log("comments updated ..." + JSON.stringify(item));
    });

});

Upvotes: 2

Related Questions