douzou8074 2011-06-06 01: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 02: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.

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

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部