假设有一个数组被定义为子文档。
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() ] )
如何指定标准以匹配我列出的那些条件?
答案 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}}})
}