我想使用PHP脚本中的MongoDB查询:
Bulk.find(<query>).upsert().update(<update>);
MongoDB操作的文档:http://docs.mongodb.org/manual/reference/method/Bulk.find.upsert/#Bulk.find.update
来自PHP的文档执行操作:http://php.net/manual/en/mongodb.execute.php(参见示例#3范围示例)
我正在尝试使用PHP文档中的示例3为我的应用程序执行批量操作。
但等效的代码不起作用。
我传递给MongoDB的JS函数通过PHP MongoCode对象进行upstart操作:(http://php.net/manual/en/class.mongocode.php)
$function="function(idClient,name){
bulk.find({idc:idClient,pid:partnerId}).upsert().update(
{
$setOnInsert: {idc:idClient,pid:partnerId,dateCreate:new Date()},
$set: {name:name,n:0},
});}";
$function=new MongoCode($function,array('partnerId'=>$partnerId));
我测试的3种变体:
使用var变体:
// 1
$db->execute(new MongoCode('var bulk = db.MyCollection.initializeUnorderedBulkOp();'));
while ([...])
{
[...]
// 2
$db->execute($function,array($idClient,$name));
}
// 3
$db->execute(new MongoCode('bulk.execute();'));
1返回:"exception:SyntaxError:Unexpected token var"
2返回:"exception:ReferenceError:未定义批量"
3返回:"exception:ReferenceError:未定义批量"
无var变量:
// 1
$db->execute(new MongoCode('var bulk = db.MyCollection.initializeUnorderedBulkOp();'));
while ([...])
{
[...]
// 2
$db->execute($function,array($idClient,$name));
}
// 3
$db->execute(new MongoCode('bulk.execute();'));
1返回:数组([…],"OK"=>1)
2在第一次出现时返回:数组([…],"OK"=>1)
第二次出现时2返回:"exception:ReferenceError:未定义批量"
3返回:"exception:ReferenceError:未定义批量"
没有var变量而没有while:
// 1
$db->execute(new MongoCode('var bulk = db.MyCollection.initializeUnorderedBulkOp();'));
//2
$db->execute($function,array($idClient,$name));
// 3
$db->execute(new MongoCode('bulk.execute();'));
1返回:数组([…],"OK"=>1)
2个返回:数组([…],"OK"=>1)
3个返回:数组([…],"OK"=>1)
第三种变体有效,但我想追加24万个文档,而且我通常不必为每个追加创建一个新的UnorderedBulkOp()。
我使用MongoDB 2.6.7和PHP 2.6.4。
有人知道我该怎么做吗?
Thnak you
这似乎是您在PHP-1393中的问题的重复,该问题是在PHP驱动程序项目上打开的。为了其他遇到这个问题的人的利益,我将重复最初的回答。
MongoDB::execute()
调用的eval
命令在多个调用之间不共享上下文。如果要使用服务器端JavaScript评估,则需要将整个脚本作为MongoCode对象传入,并调用该命令一次。
也就是说,在这里只使用MongoUpdateBatch和add()
方法要好得多,因为所有的操作都是更新。使用驱动程序来准备和执行写命令将比依赖服务器端JavaScript的效率高得多。
例如,我们可以使用驱动程序批API来追加100个文档,如:
$batch = new MongoUpdateBatch($collection, ['ordered' => false]);
for ($i = 0; $i < 100; $i++) {
$batch->add([
'q' => [ 'idc' => $i ],
'u' => [
'$setOnInsert' => [ 'idc' => $i ],
'$set' => [ 'name' => 'Test' ],
],
'upsert' => true,
]);
}
$batch->execute();
注意:1.xPHP驱动程序不提供您在MongoDB shell中找到的API,它允许您在同一批中混合插入、更新和删除操作。MongoWriteBatch(及其子类)允许您构建特定于操作的批,并让驱动程序处理将它们拆分为最佳数量的写命令。
展望未来,您在shell中找到的initializeUnorderedBulkOp()
和initializeOrderedBulkOp()
API(以及其他一些驱动程序)最终将被我们最近发布的CRUD API规范所取代。CRUD API规范定义了一个更简洁的接口,用于发布批量操作,而不需要流畅的API(请参见bulkWrite()
方法)。您可以在PHP驱动程序的下一个主要版本中看到这一点。