douzou8074 2011-06-06 09:11
浏览 41
已采纳

在mongoDB中更新多个嵌入式文档

I need to update multiple embedded docs in mongo using PHP. My layout looks like this:

{
  _id: id,
  visits : {
        visitID: 12
        categories: [{
              catagory_id: 1,
              name: somename,
              count: 11,
              duration: 122
              },
              {
              catagory_id: 1,
              name: some other name,
              count: 11,
              duration: 122
              },
              {
              catagory_id: 2,
              name: yet another name,
              count: 11,
              duration: 122
              }]
   }
}

The document can have more than one visit too.

Now i want to update 2 categories, one with id=1 and name=somename and the other with id=1 and name=some_new_name. Both of them should inc "count" by 1 and "duration" by 45.

First document exists, but second does not.

Im thinking of having a function like this:

function updateCategory($id, $visitID,$category_name,$category_id) {

    $this->profiles->update(
            array(
                '_id' => $id, 
                'visits.visitID' => $visitID,
                'visits.categories.name' => $category_name,
                'visits.categories.id' => $category_id,
            ), 
            array(
                '$inc' =>   array(
                            'visits.categories.$.count' => 1,
                            'visits.categories.$.duration' =>45,
                        ),
            ), 
            array("upsert" => true)
    );  
}   

But with this i need to call the function for each category i will update. Is there any way to do this in one call?

EDIT:

Changed the layout a bit and made "categories" an object instead of array. Then used a combination of "category_id" and "category_name" as property name. Like:

categories: {
              1_somename : {
                  count: 11,
                  duration: 122
              },
              1_some other name : {
                  count: 11,
                  duration: 122
              },
              2_yet another name : {
                  count: 11,
                  duration: 122
              },
}

Then with upsert and something like

$inc: {
 "visits.$.categories.1_somename.d": 100,
 "visits.$.categories.2_yet another name.c": 1
}

i can update several "objects" at a time..

  • 写回答

1条回答 默认 最新

  • dswmmvrg40957 2011-06-06 10:27
    关注

    Mongodb currently not supporting arrays multiple levels deep updating (jira)

    So following code will not work:

    '$inc' =>      array( 
       'visits.categories.$.count' => 1, 
       'visits.categories.$.duration' => 123, 
     ),
    

    So there is some solutions around this:

    1.Load document => update => save (possible concurrency issues)
    2.Reorganize your documents structure like this(and update using one positional operator):

    {
      _id: id,
      visits : [{
            visitID: 12
      }],
      categories: [{
                  catagory_id: 1,
                  name: somename,
                  count: 11,
                  duration: 122,
                  visitID: 12
                  }]
       }
    }
    

    3.Wait for multiple positional operators support (planning in 2.1 version of mongodb).
    4.Reorganize your documents structure somehow else, in order to avoid multiple level arrays nesting.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器
  • ¥15 如何用Labview在myRIO上做LCD显示?(语言-开发语言)