简体   繁体   English

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

[英]With MongoDB, how do I update an object within in array with an object from a variable?

I have an object assigned to a variable, such as: 我有一个分配给变量的对象,例如:

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

The following does not work, and honestly I am unsure of what I'm missing: 以下内容无效,说实话,我不确定自己所缺少的内容:

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

What I really want to do, as I want to reuse this method and not repeat myself later is: 我真正想做的是,因为我想重用此方法,以后不再重复说明:

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

That doesn't work either. 那也不行。 I referenced this post: Update array element by id with mongo query 我引用了这篇文章: 用mongo query通过id更新数组元素

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

But my query is not working. 但是我的查询无法正常工作。 Am I missing something elementary here? 我在这里缺少基本的东西吗?

--- Edit --- -编辑-

Here is the result when I query based on the parent document 这是我根据父文档进行查询时的结果

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"
}

I'm passing data to the server, such as... Method.call("UpdateCommand", id, child); 我正在将数据传递到服务器,例如... Method.call(“ UpdateCommand”,id,child);

The variable id is the parent id of the document, and the child is the object I mentioned. 变量ID是文档的父ID,子ID是我提到的对象。

I use child._id.toString() to generate the matching ObjectId("..."); 我使用child._id.toString()生成匹配的ObjectId(“ ...”);

So more specifically: 因此,更具体地说:

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

Yet this doesn't work. 但这行不通。 I'm thinking something is off with my selector, but I can use findOne() with the same method and it does return the proper document, and using $elemMatch returns the specified child item in the array. 我想我的选择器有问题,但是我可以使用具有相同方法的findOne()并返回正确的文档,并使用$ elemMatch返回数组中指定的子项。

Anything I might be missing? 我可能会缺少任何东西吗? I've ran all the values through console.log to make sure I'm getting them, and I am. 我已经通过console.log运行了所有的值,以确保我正在获取它们,并且是。

So what you are saying is that you have a document like this: 因此,您的意思是您有一个像这样的文档:

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

Or something similar, but at least with an array of children like that. 或类似的东西,但至少有很多这样的孩子。 As long as you are happy to update "all" if the elements in the "child" entry with the values in your variable object then there is nothing wrong with this: 只要您乐于用变量对象中的值更新“所有”项,那么“孩子”条目中的元素就不会有任何问题:

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

And that will replace the entire element in position. 这样就可以替换整个元素。

If you are worried about replacing the entire content where you might have something like this: 如果您担心要替换整个内容,则可能会有以下内容:

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

Then you can process the keys of the object to construct your $set statement: 然后,您可以处理对象的键以构造$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
);

Which will process the update in place but does not overwrite the "created" field that was not supplied. 它将处理就地更新,但不会覆盖未提供的“创建”字段。

Also note your quotes '' around the ObjectId value there, but I'm hoping that is just a typo, otherwise you need to eval() the string to get a valid object. 还要注意那里的ObjectId值周围的引号'' ,但我希望这只是一个错字,否则您需要eval()字符串才能获得有效的对象。

The single array elements here are just and example. 这里的单个数组元素只是一个例子。 It is the positional $ operator syntax with the matching element in the query that matters here. 与查询中的匹配元素相关的位置$运算符语法在这里很重要。 There is no difference for a single array element or hundreds. 单个数组元素或数百个数组元素没有区别。 Just as long as you are only updating one element of the array. 只要您只更新数组的一个元素即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM