2015-02-14 3 views
1

Я хочу использовать этот запрос MongoDB из PHP скрипта:MongoDB с PHP: Bulk.upsert() вставка с функцией PHP Execute

Bulk.find(<query>).upsert().update(<update>); 

Doc от операции MongoDB: http://docs.mongodb.org/manual/reference/method/Bulk.find.upsert/#Bulk.find.update

Doc от операция выполнения PHP: http://php.net/manual/en/mongodb.execute.php (см. пример №3).

Я пытаюсь использовать пример №. 3 из документа PHP, чтобы сделать массовое действие для моего приложения.

Но эквивалентный код не работает.

Функция JS Перехожу к MongoDB для операций upsert thrue Объекта РНР MongoCode: (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 варианте я testet:

С вариантом 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 возврат: "исключение: SyntaxError : Неожиданный вар маркер»

2 возвращается: "исключение: ReferenceError: объем не определен"

3 возвращает: "исключение: ReferenceError: объем не определен"

Без варианта вара:

// 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 в первых возвращений встречаемости: а rray ([...], "ОК" => 1)

2 во втором возвращается вхождение: "исключение: ReferenceError: объем не определен"

3 возвращает: «исключение: ReferenceError: объем не определенно»

без варианта вара без времени:

// 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)

3-я вариант работает, но я хочу для увеличения 240 000 документов, и я нормально не должен создавать новый UnorderedBulkOp() для каждого upsert.

Я использую MongoDB 2.6.7 с PHP 2.6.4.

Знает ли кто-нибудь, как я могу это сделать?

Thnak вы

+0

В оболочном модусе работают те же операции. – Alsatian

+1

, потому что каждый экземпляр mongocode находится в своем собственном экземпляре - они теперь знают друг о друге. – Tobias

ответ

3

Это, кажется, дубликат вашего вопроса в PHP-1393, который был открыт проект драйвера PHP. Повторюсь по оригинальному ответу в пользу кого-то еще, кто сталкивается с этим вопросом.


eval команда, которая MongoDB::execute() вызывающие, не разделяет контекста между несколькими вызовами. Если вы собираетесь использовать оценку JavaScript на стороне сервера, вам нужно передать весь ваш скрипт в качестве объекта MongoCode и вызвать команду один раз.

Сказали, что вам намного лучше, используя MongoUpdateBatch и метод add(), так как все ваши операции - это обновления. Использование драйвера для подготовки и выполнения команд записи будет гораздо более эффективным, если использовать серверный JavaScript.

В качестве примера, мы могли бы использовать водитель пакетного API для upsert 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 не предоставляет API вы найдете в MongoDB оболочке, позволяет вам смешивать операции вставки, обновления и удаления в той же партии. MongoWriteBatch (и его подклассы) позволяют вам создавать партии конкретных операций и иметь дескриптор драйвера, разделяющий их на оптимальное количество команд записи.

Идти вперед, initializeUnorderedBulkOp() и initializeOrderedBulkOp() API, который вы найдете в оболочке (и некоторых других драйверах), в конечном итоге будут заменены нашими недавно опубликованными CRUD API specification. Спецификация CRUD API определяет гораздо более сжатый интерфейс для выдачи массовых операций без , требующий бесплатного API (см. Метод bulkWrite()). Вы можете ожидать увидеть это в следующей основной версии драйвера PHP.

Смежные вопросы