Mongodb:读取文档/数组并立即删除它们

时间:2014-11-12 09:04:10

标签: php mongodb mongodb-query

技术背景:我正在使用tokumx(支持document level locking)和php。

文档结构是这样的

{
  "accounts": [
    {
      "username": "1",
    },
    {
      "username": "2",
    }
  ],
  "site": "test.com"
}

情况:

大多数情况下,我只需要“帐户”数组中的第一个x帐户

检索分钟这些第一个x帐户,应该从文档中的“accounts”数组中删除它们。

妥协我可以:

提取“帐户”。

  {
    "username" : "1",
    "site": "test.com"
  },

  {
    "username" : "2",
    "site": "test.com"
  }

或切换到MySql(最后一个选项)。


2 个答案:

答案 0 :(得分:2)

从结构中不太确定您想要实现的内容,但第一部分所需的操作是findAndModify()。所以在黑暗中刺伤(mogoshell,因为我不知道php驱动程序)

db.accounts.findAndModify({query: {"site": "test.com", "accounts.username":"2"},
                           update : {$pull: {"accounts" :{ "username" : "2"}})

要仅检索数组的第一个x元素,您可以在查询的投影部分中使用$slice运算符,例如

db.accounts.find({},{ accounts : { $slice: 5 }})

或在findAndModify中添加

fields: { accounts : { $slice: 5 }}

答案 1 :(得分:2)

这几乎是一个评论,但这是一个很长的评论,更多的解释和给出的例子。个人不熟悉tokumx(因为我从来没有使用它),但是MongoDB本身有办法做到这一点,而且它是.findAndModify()方法。

在这种情况下,您基本上是“更新”文档或“删除”,但您可以选择在返回的结果中看到“预先修改”或“修改后”的表单。

因此,要使用数组,您可以这样调用:

 $doc = $collection->findAndModify(
     array(),                                       # Something representing the "query"
     array( 
         '$pull' => array(                          # Basicallly the update
             'accounts' => array( 'username' => 1 ) 
         )
     ),
     null,                                          # optional projected fields
     array(                                         # this is the "options"
         "new" => FALSE,                            # which is the default
     )
 );

对于一份简单的文件:

 $doc = $collection->findAndModify(
     array( 'username' => 1 ),             
     array(),                                       # update, doesn't matter
     null,
     array( "remove" => TRUE )
 );    

注意到您的评论,您可以使用$push运算符足够有趣地删除数组的第一个n元素。有$slice修饰符执行此操作:

 $doc = $collection->findAndModify(
     array(),                                       # Something representing the "query"
     array( 
         '$push' => array(                          # Basicallly the update
             'accounts' => array(
                 '$each' => array(),                # But blank
                 '$slice' => lengthOfArrayMinusNElements                
             )
         )
     ),
     null,                                          # optional projected fields
     array(                                         # this is the "options"
         "new" => FALSE,                            # which is the default
     )
 );

不是“超级”原子,因为你需要知道数组“有多长”,但它可以完成。我知道这似乎很奇怪,但你基本上是在向阵列添加“无”但限制它的长度并通过$slice删除元素。两种形式,一种用于投影,另一种是更新修饰符,如图所示。