使用MongoDB,如何使用变量中的对象更新数组中的对象?

时间:2014-10-05 02:50:43

标签: javascript mongodb mongodb-query

我有一个分配给变量的对象,例如:

var child = {
    { 
        _id: 'ObjectID("16e7f7baa05c3a9d751363")',
        title: 'Testing',
        sort: 3,
        active: true 
    }

以下不起作用,老实说,我不确定我错过了什么:

db.category.update(
    { _id: "thisistheparentdocumentsid", "children._id": child._id },
    {
        $set: {
            "children.$.title": child.title,
            "children.$.active": child.active,
            "children.$.sort": child.sort
        }
    }
);

我真正想要做的是,因为我想重复使用这种方法而不再重复自己:

db.category.update(
    { _id: "thisistheparentdocumentsid", "children._id": child._id },
    {
        $set: {
            "children" : child
        }
    }
);

这也不起作用。我引用了这篇文章:Update array element by id with mongo query

以及:http://docs.mongodb.org/manual/reference/operator/update/positional/

但我的查询无效。我在这里错过了一些基本的东西吗?

---编辑---

以下是基于父文档查询的结果

db.category.findOne({ "_id" : "9dYgKdfFczgiRcNouij"});
{
        "title" : "ParentTest",
        "active" : true,
        "children" : [
                {
                        "_id" : ObjectId("680d55c6995ef6f0748278c2"),
                        "title" : "ChildTest",
                        "active" : true
                                            },
                {
                        "_id" : ObjectId("2b4469c1a4c8e086942a1233"),
                        "title" : "ChildTest2"
                        "active" : true
                }
        ],
        "_id" : "9dYgKdfFczgiRcNouij"
}

我将数据传递到服务器,例如...... Method.call(" UpdateCommand",id,child);

变量id是文档的父ID,子项是我提到的对象。

我使用child._id.toString()生成匹配的ObjectId(" ...");

更具体地说:

db.category.update(
        { _id: id, "children._id": child._id.toString() },
        {
            $set: {
                "children.$.title": child.title,
                "children.$.active": child.active,
                "children.$.sort": child.sort,
                "children.$.uppercase": child.title.toUpperCase()
            }
        }
    );

然而这并不奏效。我用我的选择器来思考某些事情,但是我可以使用相同的方法使用findOne()并返回正确的文档,并使用$ elemMatch返回数组中指定的子项。

我可能遗失的任何东西?我通过console.log运行了所有值,以确保我得到它们,而我是。

1 个答案:

答案 0 :(得分:1)

所以你说的是你有这样的文件:

{
    "_id": ObjectId("5430b55d214047b8ee55d40b"),
    "children": [
        { 
            "_id": ObjectID("16e7f7baa05c3a9d751363"),
            "title": "Testing",
            "sort": 2,
            "active": false 
        }
    }
}

或类似的东西,但至少有一系列像这样的孩子。只要您乐意更新“all”,如果“child”条目中的元素包含变量对象中的值,那么这没有任何问题:

db.category.update(
    { "_id": ObjectId("5430b55d214047b8ee55d40b"), "children._id": child._id },
    { "$set": { "children.$": child }
)

这将取代整个元素。

如果您担心替换可能包含以下内容的整个内容:

{
    "_id": ObjectId("5430b55d214047b8ee55d40b"),
    "children": [
        { 
            "_id": ObjectID("16e7f7baa05c3a9d751363"),
            "title": "Testing",
            "sort": 2,
            "active": false,
            "created": ISODate("2014-10-03T03:09:20.609Z")
        }
    }
}

然后,您可以处理对象的键以构建 $set 语句:

var update = { "$set": {} };

for ( var k in child ) {
    if ( k != "_id" )
        update["$set"]["children.$."+k] = child[k];
}

db.category.update(
    { "_id": ObjectId("5430b55d214047b8ee55d40b"), "children._id": child._id },
    update
);

将处理更新,但不会覆盖未提供的“已创建”字段。

另请注意''附近ObjectId值的引号eval(),但我希望这只是一个拼写错误,否则您需要{{1}}字符串才能获得有效对象。

这里的单个数组元素只是一个例子。它是positional $运算符语法,查询中的匹配元素在此处很重要。单个数组元素或数百个元素没有区别。只要您只更新数组的一个元素。