dongrong5189 2014-11-13 10:56
浏览 71

在mongodb php中更新嵌套文档中的字段

I use MongoDB with PHP driver, so for convenience I will write the query with this syntax, I would like to find a more elegant solution that I found today for the following problem.

I have this collection "Story" with nested document:

Collection Story:

{  
   "_id":"Story1",
   "title":null,
   "slug":null,
   "sections":[  
      {  
         "id_section":"S1",
         "index":0,
         "type":"0",
         "elements":[  
            {  
               "id_element":"001",
               "text":"img",
               "layout":1
            }
         ]
      },
      {  
         "id_section":"S2",
         "index":0,
         "type":"0",
         "elements":[  
            {  
               "id_element":"001",
               "text":"hello world",
               "layout":1
            },
            {  
               "id_element":"002",
               "text":"default text",
               "layout":1
            },
            {  
               "id_element":"003",
               "text":"hello world 3",
               "layout":"2"
            }
         ]
      }
   ]
}

Assuming you want to change the value of the element with id_element => 002 present in section with id_section => S2 of Story with _id => Story1

The solution I've found now is to find the "position" of element 002 and do the following

1]

$r=$m->db->plot->findOne(array("_id" => 'Story1',
                                        "sections.id_section"=>'S2'),
                                        array('_id'=>false,'sections.$.elements'=>true));

2]

foreach($r['sections'][0]['elements'] as $key=>$value){
    if($value['id_element']=='002'){
        $position=$key;
        break;
    }

3]

$m->db->story->update(array('_id'=>'Story1','sections.id_section'=>'S2','sections.elements.id_element'=>'002'),
                array('$set'=>array('sections.$.elements.'.$position.'.text'=>'NEW TEXT')),
                array('w'=>1));

I repeat that I do not think an elegant solution, and I noticed that it is a common problem.

Thank you for your help S.

  • 写回答

1条回答 默认 最新

  • dqluw20882 2014-11-13 15:21
    关注

    You can't use $ to match multiple levels of nested arrays. This is why it's not a good idea to nest arrays in MongoDB if you anticipate searching on properties anywhere deeper than the top level array. The alternatives for a fixed document structure are to know which positions in all but one of the arrays you want to update at (or to retrieve the document and find out the indexes, as you are doing) or to retrieve the document, update it in the client, and reinsert it.

    The other option is to rethink how the data is modeled as documents in MongoDB so that nested arrays don't happen/ In your case, a story is a collection of sections which are collections of elements. Instead of making a story document, you could have a story be represented by multiple section documents. The section documents would share some common field value to indicate they belong to the same story. The above update would then be possible as an update on one section document using the $ positional operator to match and update the correct element.

    评论

报告相同问题?

悬赏问题

  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?