MongoDB更新嵌入式文档不起作用

时间:2016-07-10 03:17:57

标签: node.js mongodb

我试图更新嵌入式文档,但它无法正常工作。这就是文档的样子:

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

您可以看到评论字段是包含评论的嵌入式文档。我想更新特定的评论,所以我做了这样的查询(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()
    }
}) ...

当我运行此查询时,未显示任何错误,但未应用更新。我也试过了这个问题:

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

但也没有奏效。我错过了什么吗?我使用的是Mongo v3.2.7。

1 个答案:

答案 0 :(得分:2)

请尝试以下代码。我认为“ObjectId”(即案例)应该是问题所在。只需检查您如何定义对象ID并在您使用的两个地方保持一致(即发布_id和评论_id - >两个地方)。

  

ObjectID = require('mongodb')。ObjectID

以下代码对我来说很好。基本上,您的查询似乎是正确的。

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" : "newemail@gmail.com",
            "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));
    });

});