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.

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

报告相同问题?

悬赏问题

  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值