如何在update语句中调用mongodb服务器函数

时间:2014-06-10 00:08:39

标签: mongodb-php

假设有一个数组被定义为子文档。

User
 first_name:"blah",
 last_name: "blah",
 scores [{score: 12},
         {score: 13},
         {score: 9},
         {score: 14}]

假设我想在update语句中循环遍历此子数组,并检查是否需要添加新分数。新得分可以是8或16,如果它的8则不应该添加任何东西,但是如果它的16应该被添加到列表的末尾。 反正有没有定义javascript服务器端功能并在更新语句中使用它,还是有其他方法做这样的事情?操作必须是原子的重要的事情。

使用php驱动程序

public bool|array MongoCollection::update ( array $criteria , array $new_object [, array $options = array() ] )

如何指定标准以匹配我列出的那些条件?

1 个答案:

答案 0 :(得分:0)

您可以创建服务器端javascript函数,但是mongo do not recommend this的创建者:

  

如果可能,我们不建议使用服务器端存储的功能。

如果您需要具有复杂逻辑的原子性,一种方法是在使用文档之前锁定文档。您可以使用findAndModify function实现此目的。这样做的基本要点是,您可以像往常一样尝试find您的文档,并使用locked = false的附加条件。此函数的修改部分将设置locked = true

db.people.findAndModify({
    query: { name: "Andy", locked: false },
    update: { locked: true },
});

您现在可以“原子地”使用该文档。当您将更改写回数据库时,可以设置locked = false。确保将块包裹在try/catch/finally中并确保文档在finally块中解锁。

请注意,如果您的操作非常简单(只需要在列表中添加字段),那么单独使用findAndModify更新文档字段可能足以满足您的需求。

编辑:如果您真的想使用服务器端功能,请参考PHP mongo documentation中的示例:

$response = $db->execute("function(x) { return x;}", array("input param"));

以下是如何将函数保留以供以后使用(通过mongo shell)

db.system.js.save(
               { _id: "echoFunction",
                 value : function(x) { return x; }
               }
             )

稍后在PHP中:

$response = $db->execute("echoFunction( 'test' )");
var_dump($response);

<强> EDIT2 : 您的更新功能比我最初理解的要容易得多。您只需要以下内容:

$db->update(
    array("first_name" => "blah"), 
    array(
        "$push" => array(
            "scores" => array("score" => 16)
        )
    )
);

Edit2:从函数内部访问您的集合

function push_score(id, score) {
  //your logic here
  //...
  db.your_collection.update({_id: ObjectId(id), $push: {scores: {score: score}}})
}