PHP Velho Oeste 2024

MongoDB::execute

(PECL mongo >=0.9.3)

MongoDB::executeJavaScript コードをデータベースサーバー上で実行する [非推奨]

説明

public MongoDB::execute ( mixed $code [, array $args = array() ] ) : array
警告

このメソッドが実行する » eval コマンドは、 MongoDB 3.0+ では非推奨となりました。

Mongo データベースサーバーは JavaScript エンジンを持っています。 このメソッドを使うと、任意の JavaScript をデータベース上で実行することができます。 大量のコレクションの操作を軽量に行ったり、 結果に対する何らかの処理をデータベース側で行うことでクライアント側への送信量を減らしたり といった際に有用です。

データベース内での JavaScript の実行時には書き込みロックを取得します。 つまり、他の操作をブロックするということです。長いスクリプトを実行する前にはこのことを考慮しましょう。

これは、データベースコマンド » eval のラッパーで、次のコードと同じ意味です。

<?php

public function execute($code$args) {
    return 
$this->command(array('eval' => $code'args' => $args));
}

?>

MongoDB は、ひとつの文を一行に書くと return 文があるものとみなします。 これは、あまり直感的でない振る舞いのもととなります。 たとえば、これは "foo" を返します。

<?php

$db
->execute('"foo";');

?>

しかし、これらはどちらも NULL を返します。

<?php

$db
->execute('"bar"; "foo";'); // 複数の文

$db->execute('db.foo.count(
);'
); // 複数行

?>

この驚くべき振る舞いを回避するには、何を返すのかを MongoDB に決めさせるのではなく return する値を明示しておけばよいでしょう。 先ほどの例では、このように書き換えることができます。

<?php

$db
->execute('"bar"; return "foo";');

$db->execute('return db.foo.count(
);'
);

?>

これで、最初の文は "foo" を返して 二番目の文は "foo" コレクションの数を返すようになります。

パラメータ

code

実行したい MongoCode あるいは文字列。

args

code に渡す引数。

返り値

評価した結果を返します。

例1 単純な MongoDB::execute() の例

<?php

$response 
$db->execute("function() { return 'Hello, world!'; }");
echo 
$response['retval'];

?>

上の例の出力は、 たとえば以下のようになります。


Hello, world!

例2 パラメータつきの MongoDB::execute() の例

オプションのパラメータ配列を JavaScript の関数に渡します。

<?php

$response 
$db->execute("function(greeting, name) { return greeting+', '+name+'!'; }", array("Good bye""Joe"));
echo 
$response['retval'];

?>

上の例の出力は、 たとえば以下のようになります。


Good bye, Joe!

例3 スコープの例

文字列のかわりに MongoCode オブジェクトを最初のパラメータに使うと、 JavaScript を実行するスコープを渡すことができます。

<?php

$func 

    
"function(greeting, name) { ".
        
"return greeting+', '+name+', says '+greeter;".
    
"}";
$scope = array("greeter" => "Fred");

$code = new MongoCode($func$scope);

$response $db->execute($code, array("Goodbye""Joe"));
echo 
$response['retval'];

?>

上の例の出力は、 たとえば以下のようになります。


Goodbye, Joe, says Fred

参考

変更履歴

バージョン 説明
1.7.0 このメソッドは非推奨になりました。内部で使っている » eval コマンドが、MongoDB 3.0 以降で非推奨になったためです。

add a note add a note

User Contributed Notes 2 notes

up
4
Nanhe Kumar
10 years ago
$m = new MongoClient();
        $db = $m->test;
      
        $inset = "db.getCollection('foo').insert({'name':'nanhe','age':30});";
        $response = $db->execute($inset);
        print_r($response); //Array ( [retval] => [ok] => 1 )
      
        $response = $m->test->execute("db.getCollection('foo').insert({'name':'happy','age':18});");
        print_r($response); //Array ( [retval] => [ok] => 1 )
       
        $response = $m->test->execute("db.foo.insert({'name':'prince','age':16});");
        print_r($response); //Array ( [retval] => [ok] => 1 )
       
        $response= $m->test->execute("return db.foo.count();");
        print_r($response); //Array ( [retval] => 3 [ok] => 1 )
       
        $response= $m->test->execute("return db.foo.findOne();");
        print_r($response); //Array ( [retval] => Array ( [_id] => MongoId Object ( [$id] => 5287ccbe60e2eac9a0e2f1c6 ) [name] => nanhe [age] => 30 ) [ok] => 1 )
       
        /*
         * If you want use find function then use toArray because The find() function returns a cursor, which can't be returned from JavaScript.
         */
        $response= $m->test->execute("return db.foo.find().toArray();");
        print_r($response); //[$id] => 5287cd2260e2eac9a0e2f1ca ) [name] => happy [age] => 18 ) [2] => Array ( [_id] => MongoId Object ( [$id] => 5287cd2260e2eac9a0e2f1cb ) [name] => prince [age] => 16 ) [3] => Array ( [_id] => MongoId Object ( [$id] => 5287cdea60e2eac9a0e2f1cc ) [name] => nanhe [age] => 30 ) [4] => Array ( [_id] => MongoId Object ( [$id] => 5287cdea60e2eac9a0e2f1cd ) [name] => happy [age] => 18 ) [5] => Array ( [_id] => MongoId Object ( [$id] => 5287cdea60e2eac9a0e2f1ce ) [name] => prince [age] => 16 ) ) [ok] => 1 )
      
        $response= $m->test->execute("return db.foo.find({'name':'nanhe'}).toArray();");
        print_r($response); //Array ( [retval] => Array ( [0] => Array ( [_id] => MongoId Object ( [$id] => 5287ce9b60e2eac9a0e2f1d2 ) [name] => nanhe [age] => 30 ) ) [ok] => 1 )
        // $id value will be different in your case
up
-1
nodkz at mail ru
11 years ago
In 1.7.2, a nolock option was added to eval. To use nolock you have to use the command interface directly:

db.runCommand({$eval: function() {return 42;}, nolock: true})

or with args

db.runCommand({$eval: function(x,y) {return x*y;}, args: [6,7], nolock: true})
To Top