Mongodb 查找嵌套文档并将文档推入嵌套文档

Mongodb 查找嵌套文档并将文档推入嵌套文档,mongodb,mongoose,Mongodb,Mongoose,所以我今天开始学习mongoDB和moongoose。我有以下模式: { username: { type : String, required : true, unique: true, trim : true }, routines : { type: [ { _id : mongoose.Schema.Types.Object

所以我今天开始学习mongoDB和moongoose。我有以下模式:

{
    username: {
        type : String,
        required : true,
        unique: true,
        trim : true
    },
    routines : {
        type: [
            {   
                _id : mongoose.Schema.Types.ObjectId, 
                name : String, 
                todos : [
                    {
                        _id : mongoose.Schema.Types.ObjectId, 
                        todo : String, 
                        isCompleted : Boolean
                    }
                ]
            }
        ],
    }
}
例如:

{
   "username": "John",
   "routines": [
       {
          "_id" : 1234, //just for an example assume it to be as 1234
          "name" : "Trip plan",
          "todos" : [
             {
                "_id": 1213123,
                "todo": "book flight",
                "isCompleted" : "false"
             }....
          ]
       }......
    ]
} 
我想做的是,首先,我将使用用户名从集合中选择一个文档,然后在例程(对象数组)中,我想通过id选择一个特定的例程,该id将由用户在请求体中给出,现在在所选例程中,我想推入todos数组

对于上面的示例,假设选择用户名为john的文档,然后从例程数组中选择一个id为1234的对象,然后在其todo中添加一个todo

我花了将近一天的时间研究如何做到这一点,在做这件事的过程中,我学到了阵列过滤器、投影等概念。但还是不知道该怎么做。此外,我在Stack Overflow中读到了很多答案,但我无法从中获得多少


PS:我对MongoDB和mongoose非常陌生,我的问题可能非常愚蠢,并且可能不符合堆栈溢出标准,对此我深表歉意。

您的思路是正确的,您确实希望使用它来实现这一点

下面是一个简单的例子:

// the user you want.
let user = user;

await db.routines.updateOne(
    {
        username: user.username
    },
    {
        $addToSet: {
            "routines.$[elem].todos": newTodo
        }
    },
    {arrayFilters: [{'elem._id': "1234"}]}
);

@Gibbs我不能构造查询,我的意思是我应该使用findoneandupdate,然后我给出了第一个过滤器,这样我就可以选择正确的文档,但问题是,我还应该找到带有例程id的例程,在findoneandupdate中写在哪里?我可以清楚地理解你的答案,但由于某些原因,它不起作用。你能详细说明一下吗?更新失败了吗?你确定存在匹配的文档吗?是的,我确定存在匹配的文档,它没有给我任何错误,但它返回{“ok”:0,“n”:0,“nModified”:0}这是我的错,因为我写它时有语法错误。假设它是
$[elem]
,而不是
[$elem]
。我只是在我的本地计算机上运行它来确认。