使用PHP的MongoDB:使用PHP函数Execute插入Bulk.usert()


MongoDB with PHP : Bulk.upsert() insertion with PHP function Execute

我想使用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驱动程序的下一个主要版本中看到这一点。