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

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 为我的应用程序执行批量操作。

但是等效代码不起作用。

我通过 PHP MongoCode 对象传递给 MongoDB 用于更新插入操作的 JS 函数:(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 returns : "exception: SyntaxError: Unexpected token var"

2 returns : "exception: ReferenceError: bulk is not defined"

3 returns : "exception: ReferenceError: bulk is not defined"

没有 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 returns : 数组([...],"OK"=>1)

2 第一次出现 returns : array([...],"OK"=>1)

2 第二次出现 returns : "exception: ReferenceError: bulk is not defined"

3 returns : "exception: ReferenceError: bulk is not defined"

没有 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 returns : 数组([...],"OK"=>1)

2 returns : 数组([...],"OK"=>1)

3 returns : 数组([...],"OK"=>1)

第三个变体有效,但是,我想更新 240 000 个文档,而且我通常不必为每个更新插入创建一个新的 UnorderedBulkOp()。

我正在使用 MongoDB 2.6.7 和 PHP 2.6.4.

有人知道我该怎么做吗?

谢谢你

这似乎与您在 PHP-1393 中的问题重复,该问题是在 PHP 驱动程序项目中打开的。为了遇到此问题的任何其他人的利益,我将通过原始回复重复。


MongoDB::execute() 调用的 eval 命令不会在多次调用之间共享上下文。如果您要使用服务器端 JavaScript 评估,则需要将整个脚本作为 MongoCode 对象传递并调用一次命令。

也就是说,您最好只在此处使用 MongoUpdateBatch and the 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.x PHP 驱动程序不提供您在 MongoDB shell 中找到的 API,它允许您混合插入,同一批更新和删除操作。 MongoWriteBatch(及其子 类)允许您构建特定于操作的批处理,并让驱动程序处理将它们拆分为最佳数量的写入命令。

展望未来,您在 shell(以及其他一些驱动程序)中找到的 initializeUnorderedBulkOp()initializeOrderedBulkOp() API 最终将被我们最近发布的 CRUD API specification。 CRUD API 规范定义了一个更简洁的接口来发出批量操作,而不需要 要求 流畅的 API(参见 bulkWrite() 方法)。您可以期待在 PHP 驱动程序的下一个主要版本中看到它。