通过Mongoose.js中的ObjectId选择和更新嵌套对象 [英] Selecting and updating a nested object by it's ObjectId in Mongoose.js

查看:125
本文介绍了通过Mongoose.js中的ObjectId选择和更新嵌套对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在MongoDB中使用Mongoose遇到了一些琐碎的事情.

I'm having trouble with something that thought would be trivial in MongoDB with Mongoose.

使用这样的简单模式

const UserSchema = new Schema({
groups: [
    {
        name: String,
        members: [
            {
                hasAccepted: {
                    type: Boolean
                }
            }
        ]
    }
]
});

当我创建新组时,每个成员对象都将获得一个_id属性.我只想通过其_id选择该成员并更新其hasAccepted属性.

When i create new groups, each member object gets an _id property of course. I simply want to select that member by its _id and update its hasAccepted property.

当我使用成员的_id运行查询时,我会为用户获取整个记录,这使得很难找到嵌套成员来对其进行更新.

When I run a query with the _id of the member, I get back the entire record for the user, which makes it difficult to find the nested member to update it.

如何将结果缩小为具有找到的ID的成员并更新其属性?

How can I trim the result down to just the member with the found ID and update its property?

我正在使用Mongo 3.6.2,并尝试了新的arrayFilters,但是没有运气.

I'm using Mongo 3.6.2 and have tried the new arrayFilters, but with no luck.

下面是我的代码(使用Node),该代码返回整个文档,但未更新任何内容.

My code (using Node) is below, which returns the whole document, but with nothing updated.

const query = {
    groups : {
        $elemMatch : { members : { $elemMatch : {_id : <id>} } }
    }
};

const update =  {$set: {'groups.$[].members.$[o].hasAccepted':true }};
const options = { new: true, arrayFilters:[{"o._id":<id>}] };

// Find the document
User.findOneAndUpdate(query, update, options, function(error, result) {
    if (error) {
        res.send(error);
    } else {
        res.send(result);
    }
});

这是我正在使用的测试数据库的全部数据.我正在测试的_id是第1组中成员的_id:5a753f168b5b7f0231ab0621

here's the full data from the test db i'm working with. The _id I've been testing with is one the for the member in Group 1: 5a753f168b5b7f0231ab0621

    [
{
    "_id": {
    "$oid": "5a7505452f93de2c90f49a20"
    },
    "groups": [
    {
        "name": "Group 2",
        "_id": {
        "$oid": "5a7543b8e254ab02cd728c42"
        },
        "members": [
        {
            "user": {
            "$oid": "5a7543b8e254ab02cd728c41"
            },
            "_id": {
            "$oid": "5a7543b8e254ab02cd728c43"
            },
            "hasAccepted": false
        }
        ]
    },
    {
        "name": "Group 1",
        "_id": {
        "$oid": "5a753f168b5b7f0231ab0620"
        },
        "members": [
        {
            "user": {
            "$oid": "5a753f168b5b7f0231ab061f"
            },
            "_id": {
            "$oid": "5a753f168b5b7f0231ab0621"
            },
            "hasAccepted": false
        }
        ]
    }
    ]
},
{
    "_id": {
    "$oid": "5a753f168b5b7f0231ab061f"
    },
    "groups": [],
},
{
    "_id": {
    "$oid": "5a7543b8e254ab02cd728c41"
    },
    "groups": [],

}
]

感谢您可以提供的任何帮助.

Thanks for any help you can offer.

推荐答案

好,所以事实证明,我需要更好地理解的东西是arrayFilters(那是,而且我需要将组名添加到我以前使用的数据中达到我需要更新的值.

OK, so it turns out the the thing I needed to understand better are arrayFilters (that, and I needed to add the group name into the data I used to get to the value I needed to updated.

最能帮助我理解arrayFilters的事情是将sql视为一种子查询,就像在SQL世界中使用的那样.一旦知道了这一点,便能够弄清楚如何编写更新.

The thing that helped me understand arrayFilters the best was to think of the as a sort of subquery, like is used in the SQL world. Once I got that, I was able to figure out how to write my update.

本文对于理解如何使用arrayFilters也非常有帮助:

This article was also very helpful in understanding how arrayFilters are used: http://thecodebarbarian.com/a-nodejs-perspective-on-mongodb-36-array-filters.html

这是对我有用的代码.请注意,您需要Mongo 3.6和Mongoose 5.0.0才能获得对arrayFilters的支持.

Here's the code that worked for me. Note that you need Mongo 3.6 and Mongoose 5.0.0 to get support for arrayFilters.

此外,您需要确保像这样需要Mongoose的ObjectId

Also, you need to be sure to require Mongoose's ObjectId like so

const ObjectId = require('mongoose').Types.ObjectId;

这是其余的工作代码:

const query = {
    groups : {
        $elemMatch : { members : { $elemMatch : {_id : new ObjectId("theideofmymemberobject"), hasAccepted : false} } }
    }
};

const update =  {$set: {'groups.$[group].members.$[member].hasAccepted':true } };
const options = { arrayFilters: [{ 'group.name': 'Group 3' },{'member._id': new ObjectId("theideofmymemberobject")}] };

// update the document
User.update(query, update, options, function(error, result) {
    if (error) {
        res.send(error);
    } else {
        res.send(result);
    }
});

这篇关于通过Mongoose.js中的ObjectId选择和更新嵌套对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆