简体   繁体   English

如何在mongo中构造查询以更新嵌套数组文档?

[英]How to construct query to update nested array document in mongo?

I am having following document in mongo, 我在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") 
  }

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. 我有主要的documnet id: _ id ”:ObjectId(“ 506e9e54a4e8f51423679428”)菜单ID“ _id”:ObjectId(“ 506e9e54a4e8f51423679428”)以及项目ID “ _id”:ObjectId(“ 507e9f07a4e8f5142367942f”)

I have tried using the following query: 我尝试使用以下查询:

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

but its not working... 但它不起作用...

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 . 位置运算符无法在您要使其使用的级别数上起作用( https://jira.mongodb.org/browse/SERVER-831?focusedCommentId=22438&page=com.atlassian.jira.plugin.system带有menus.$.items.$.name .issuetabpanels%3Acomment-tabpanel ),即使这样做,MongoDB查询解析器也不会知道从update find的其他$是什么。

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). 判断何时应单独执行查询的一种好方法是认为每个菜单听起来像一个单独的实体(或关系数据库中的表),因此您可能应该将这些实体(或关系模型中的表)分别更新为父实体(表)。

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. 在客户端滚动浏览其菜单,然后将该特定菜单$set为您在客户端构建的整个项目。

Edit 编辑

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: 我想象这个工作客户端的方式是(以伪代码,因为我的Java有点生锈)是通过以活动记录方式首先获取该文档的:

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

This is of course just one way of doing it and this way uses the activen record paradigm which I personally like. 当然,这只是一种实现方式,并且这种方式使用了我个人喜欢的activen记录范例。 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. 按照这种想法,您可以将查找结果与您需要在文档上进行修改的所有其他内容结合起来,在客户端进行构建,然后将其作为一个查询发送到数据库。

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

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