3

I'm in a situation where I need to be able to run a direct mongodb query from inside of PHP, and am having troubles with the execute() function.

The following code will correctly execute and return a result from the database:

$m = new MongoClient();
$db = $m-><dbName>;
print_r($db->execute('db.<collection>.count()'));

However, if I replace count() with find() I get the following result:

Array
(
    [retval] => Array
        (
            [value] => DBQuery: <dbName>.<collection>-> undefined
        )

    [ok] => 1
)

Why does one of these queries work, and the other fail? And how can I overcome this issue? I've thought about writing something that will convert a MongoDB query into the necessary array format for the PHP Mongo library to work with, but that would be a lot of work that I don't want to go through.

This is the same problem that was brought up here: How to access MongoDB profile in PHP? - but no answers were given at that time.

This question: PHP MongoDB execute() locking collection utilizes the execute() method with find() and they say it works for them, but I'm not sure how.

Update:

So I'd updated mongo in pecl, but that didn't solve anything. However, I also did a YUM update, and that provided a separate package update for php-pecl-mongo-1.2.12-1.el6.x86_64 that brought me to 1.3.4-1.

Now, $db->execute('db.<collection>.find()) returns something...but not at all what I expect. Instead of returning a MongoCursor object instead an Array is returned, and while it has a retval field, there's no actual information in there from the query performed. It looks like this:

Array
(
    [retval] => Array
        (
            [_mongo] => Array
                (
                    [slaveOk] =>
                    [host] => EMBEDDED
                )

            [_db] => Array
                (
                    [_mongo] => Array
                        (
                            [slaveOk] =>
                            [host] => EMBEDDED
                        )

                    [_name] => test
                )

            [_collection] => Array
                (
                    [_mongo] => Array
                        (
                            [slaveOk] =>
                            [host] => EMBEDDED
                        )

                    [_db] => Array
                        (
                            [_mongo] => Array
                                (
                                    [slaveOk] =>
                                    [host] => EMBEDDED
                                )

                            [_name] => test
                        )

                    [_shortName] => hits
                    [_fullName] => test.hits
                )

            [_ns] => test.hits
            [_query] => Array
                (
                )

            [_fields] =>
            [_limit] => 0
            [_skip] => 0
            [_batchSize] => 0
            [_options] => 0
            [_cursor] =>
            [_numReturned] => 0
            [_special] =>
        )

    [ok] => 1
)

As you can see, there's not actually anything from the database there: how do I get to my actual rows?

Community
  • 1
  • 1
lightstrike
  • 954
  • 2
  • 15
  • 31
  • Are you using the latest version of the mongo driver for PHP? – Adrian Mar 21 '13 at 16:33
  • `find` requires `PECL mongo >=0.9.0`. Do you have it? – Andron Mar 21 '13 at 16:35
  • Yeah: pecl list yields mongo 1.3.4 (now 1.3.5 - just updated anyways, still same problem) – lightstrike Mar 21 '13 at 16:41
  • 1
    You will also find the answer here of interest: http://stackoverflow.com/questions/7700948/mongodb-error-executing-stored-javascript-function "The find() function returns a cursor, which can't be returned from JavaScript. The suggested workaround is to use toArray() to get an array return value." – Sammaye Mar 21 '13 at 19:14
  • This is nothing to do with the pecl version of the driver, by looking at the PHP doc page: http://php.net/manual/en/mongodb.execute.php it might be good to specify a return i.e.: `$db->execute('return db..find().toArray()')` – Sammaye Mar 21 '13 at 19:18
  • @Sammaye yeah, so it seems, but that toArray is not mentioned anywhere in the docs there – lightstrike Mar 21 '13 at 19:28
  • Might be good to take that up with mongodb-user google group, but then again this kind of usage is normally shunned and highly deterred – Sammaye Mar 21 '13 at 19:34

2 Answers2

1
$m = new MongoClient();
$db = $m-><dbName>;
print_r($db->execute('db.<collection>.toArray()'));

Suppose your databse name is test and collection name is foo .

print_r($m->test->execute('return db.foo.find().toArray()'));
Nanhe Kumar
  • 15,498
  • 5
  • 79
  • 71
1

I had the same problem, this is my solution using execute:

$m = new MongoClient();
$db = $m-><dbName>;
print_r($db->execute('return { count : db.<collection>.count() }'));

My result:

Array
(
    [retval] => Array
        (
            [count] => 10
        )

    [ok] => 1
)