如何在mongo中构造查询以更新嵌套数组文档? [英] How to construct query to update nested array document in mongo?

查看:87
本文介绍了如何在mongo中构造查询以更新嵌套数组文档?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在mongo中有以下文档,

I am having following document in mongo,

  {
   "_id" : ObjectId("506e9e54a4e8f51423679428"),
   "description" : "ffffffffffffffff", 
   "menus" : [  
                {   
                  "_id" : ObjectId("506e9e5aa4e8f51423679429"),     
                   "description" : "ffffffffffffffffffff",  
                      "items" : [
                               {    
                              "name" : "xcvxc",     
                              "description" : "vxvxcvxc",   
                              "text" : "vxcvxcvx",  
                              "menuKey" : "0",  
                               "onSelect" : "1",    
                              "_id" : ObjectId("506e9f07a4e8f5142367942f") 
                              } ,
                              {     
                              "name" : "abcd",  
                              "description" : "qqq",    
                              "text" : "qqq",   
                              "menuKey" : "0",  
                               "onSelect" : "3",    
                              "_id" : ObjectId("507e9f07a4e8f5142367942f") 
                              }
                             ] 
                 },
                 {  
                    "_id" : ObjectId("506e9e5aa4e8f51423679429"),   
                    "description" : "rrrrr",    
                     "items" : [    {   
                                 "name" : "xcc",    
                                 "description" : "vx",  
                                 "text" : "vxc",    
                                 "menuKey" : "0",   
                                "onSelect" : "2",   
                              "_id" : ObjectId("506e9f07a4e8f5142367942f") 
                         } ]
                } 
            ]
   } 

现在,我要更新以下文档:

Now , i want to update the following document :

 {  
     "name" : "abcd",   
    "description" : "qqq",  
    "text" : "qqq",     
    "menuKey" : "0",    
        "onSelect" : "3",   
    "_id" : ObjectId("507e9f07a4e8f5142367942f") 
  }

我有主要的文档ID:"_ id":ObjectId("506e9e54a4e8f51423679428")菜单ID "_id":ObjectId("506e9e54a4e8f51423679428")以及要更新的项目ID "_ id":ObjectId("507e9f07a4e8f5142367942f").

I am having main documnet id: "_id" : ObjectId("506e9e54a4e8f51423679428") and menus id "_id" : ObjectId("506e9e54a4e8f51423679428") as well as items id "_id" : ObjectId("507e9f07a4e8f5142367942f") which is to be updated.

我尝试使用以下查询:

db.collection.update({ "_id" : { "$oid" : "506e9e54a4e8f51423679428"} , "menus._id" : { "$oid" : "506e9e5aa4e8f51423679429"}},{ "$set" : { "menus.$.items" : { "_id" : { "$oid" : "506e9f07a4e8f5142367942f"}} , "menus.$.items.$.name" : "xcvxc66666", ...}},false,false);

但它不起作用...

推荐答案

位置运算符无法在您试图使其使用的层数上起作用(

The positional operator does not work on the number of levels you are trying to get it to work on ( https://jira.mongodb.org/browse/SERVER-831?focusedCommentId=22438&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel ) with menus.$.items.$.name and even if it did MongoDB query parser would have no idea what the other $ is from the find of the update.

您将需要从架构中取出项目,分别进行更新,然后再更新根文档.

You will need to pull out the items from the schema, update that seprately and then update the root document.

判断何时应单独执行查询的一种好方法是认为每个菜单听起来像一个单独的实体(或关系数据库中的表),因此您可能应该努力更新这些实体(或关系模型中的表) )分别添加到父实体(表).

One good way of judging when queries should be done separately is to think that each menu sounds like a separate entity (or table in a relational database) as such you should probably work on updating those entites (or tables in a relational model) separately to the parent entity (table).

因此,首先您将获得主要的根文档.滚动浏览客户端的菜单,然后$set将该特定菜单滚动到您在客户端构建的整个项目.

So first you would get out the main root document. Scroll across it's menus in client side and then $set that particular menu to the entire item you build on client side.

我想象这个工作客户端的方式是(因为我的Java有点生锈,所以使用伪代码)是通过首先以活动记录的方式获取该文档的方式:

The way I imagine this work client side is (in pseudo code since my Java is a little rusty) by first getting that document in an active record fashion:

doc = db.col.find({ "_id" : { "$oid" : "506e9e54a4e8f51423679428"} , 
    "menus._id" : { "$oid" : "506e9e5aa4e8f51423679429"}});

然后,您将遍历分配值的文档:

Then you would iterate through the document assigning your values:

foreach(doc.menus as menu_key => menu){
    foreach(menu['items'] as key => item){
        if(item._id ==  { "$oid" : "506e9f07a4e8f5142367942f"}){
            doc.menus[menu_key][key][name] = "xcvxc66666"
        }
    }
}

然后在提交所有更改后简单保存文档:

And then simple save the doc after all changes are commited:

db.col.save(doc);

这当然只是一种实现方式,并且这种方式使用了我个人喜欢的activen记录范例.按照这种想法,您可以将查找结果与您需要在文档上进行修改的所有其他内容结合起来,在客户端进行构建,然后将其作为一个查询发送到数据库中.

This is of course just one way of doing it and this way uses the activen record paradigm which I personally like. In this idea you would combine the find with everything else you need to modify on the document, building it up client side and then sending it all down as one single query to your DB.

这篇关于如何在mongo中构造查询以更新嵌套数组文档?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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