PHP: Queries do not execute using eval if they have modifiers

258 views
Skip to first unread message

jp

unread,
May 7, 2011, 9:58:32 PM5/7/11
to mongodb-user
I have tried changing command modifier as suggested in discussion
(http://groups.google.com/group/mongodb-user/browse_thread/thread/
edca68ff57cee495), but nothing doing...

I am exploring js function for the first time and trying the simplest
of commands using eval and have discovered in PHP it seems querying
having modifiers do not work...I can copy the same command into shell
and fine, even remove modifier and works, but the following things do
not work:

$func =
"db.things.find(
{ '_id' : { \$in: [ 0, 1 ] } } ).count()";

$db->execute( $func );

Nor:

$func =
'db.things.find(
{ "_id" : { $in: [ 0, 1 ] } } ).count()';

$db->execute( $func );

Nor:

$func =
'db.things.find(
{ "_id" : { $in: [ 0, 1 ] } } ).count()';

$code = new MongoCode( $func );

$db->execute( $code );

Nor:

$response =
db->command(array('$eval' => $func));

I need to do extensive $in and $or queries on server-side but find
that PHP does not seem to be able to execute them properly. Any
ideas? Anyone else successful doing similar?

Cheers

Scott Hernandez

unread,
May 8, 2011, 1:14:31 AM5/8/11
to mongod...@googlegroups.com
Why would you be doing this? Just run those commands using php. Generally there is no reason to use db.eval for things your driver supports.

There is no performance benefit from doing server side js than just running your php script (on the server). It just reduces the network traffic.


--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.


jp

unread,
May 8, 2011, 2:51:11 AM5/8/11
to mongodb-user
The example is a very simplified one in order to show what is not
functioning...This discussion is not about whether doing such a thing
is a good idea. In fact example is intentionally trivial in order to
determine what is not working. My code is far more complex than the
example above. My problem is that the simplest example above is not
working so I have little hope for the rest of the complex logic to
function until this is understood and resolved.

I need to perform serve-side because I need a number of subqueries all
of which could be accessing 100's-1000 records against 100GB sampling
and I do not want to retrieve these documents back to the client in
order to execute 100's-1000 subsequent queries. Major waste of
network bandwidth and doing something procedurally that I know the
server can do optimally is better for performance.

My actual example uses $or of a number of $in clauses in order to
determine a list of things that I need to search for within another
very large collection. I might have 100 or more things in my initial
query that I need need to find within my other collection. Those 100
things EACH could be used within this other collection by 100's of
different documents, thus 100x100 records could be affected and I do
not want to bring this data back. Using server-side I can iterate the
first 100 and perform subsequent updates as needed using a server-side
function.

Thus I have something like db.things.find( {"complex conditions
here"} ).foreach( function( x) { "foreach x db.othercol.update( {},
{add to a number of subdoc arrays} ) " } )

Back to the issue at hand...The above is not working so it seems there
is an issue (most likely with the PHP driver). I was hoping to pose
the question in order to see if someone has had such experiences. It
may be the case I have stumbled upon a bug or maybe I am overlooking
something and have an error in my use of the drived.

Cheers

eli jones

unread,
May 8, 2011, 11:38:40 AM5/8/11
to mongodb-user
I'm able to do:

$mefunc = "db.mycollection.find({myprop:{\$in:[974258]}}).count()";
$result = $db->execute($mefunc);

And it works just fine for me. ("Works just fine" means I get an array
back with a 'retval' with the count in it.)

There are two explanations... either you're doing something wrong or
there's an issue with your server/driver combination.

For my own purposes, I'm using the PHP 1.1.3 driver and Mongo 1.8.1 on
64 bit Linux.

jp

unread,
May 8, 2011, 5:53:26 PM5/8/11
to mongodb-user
Thanks for trying this and confirming success on your end :)

Hearing confirmation from another I have gone back to see what the
differences are...

If you look at my examples above I have white space and returns in my
strings. This was from when these statements were far more complex
and were not human readable without. It looks like command modifiers
are not the problem, rather it is the return within the $func string
that causes the issue when evaled by PHP. Thus...

<?php

$conn = new Mongo();
$conn->connect();
$db = $conn->selectDB( "test" );

$func =
'db.things.find( { "_id" : { $in : [ 1, 2 ] } } ).count()';

$response =
$db->execute( $func );

var_dump($response);

?>

Produced:

array(2) {
["retval"]=>
float(2)
["ok"]=>
float(1)
}


While the following:

<?php

$conn = new Mongo();
$conn->connect();
$db = $conn->selectDB( "test" );

$func =
'db.things.find(
{ "_id" : { $in : [ 1, 2 ] } } ).count()';

$response =
$db->execute( $func );

var_dump($response);

?>

Failed and produces the following result:

array(2) {
["retval"]=>
NULL
["ok"]=>
float(1)
}

So the moral of this story seems to be that complex dynamic queries/
functions in PHP have issues with returns in their strings :(

Cheers

Eli Jones

unread,
May 9, 2011, 12:45:01 AM5/9/11
to mongod...@googlegroups.com
You probably just need to define your eval as a function.. like so:

$mefunc ='
function(){
    meVal = db.things.find(
                   { _id : { $in : [ 1, 2 ] } } ).count();
    return meVal;
}';

and then it should work.

jp

unread,
May 9, 2011, 8:38:43 PM5/9/11
to mongodb-user
@Eli: I think you are missing the point...Of the two last samples,
one works and the other does not. The only difference is that I have
a newline in one example and not the other.

The fact that one works the other does not means that the syntax that
I have is acceptable, other than the newline (return) that is in the
string. Also note that this is not what I am trying to do in my code
either, only a simplified example to demonstrate the problem I
discovered.

Personally I have moved on and worked around the issue but hopefully
those who might have similar problems will find this discussion
helpful. Also, I have submitted a bug and hopefully the driver will
not behave inconsistently in the near future.

Cheers

Eli Jones

unread,
May 10, 2011, 11:19:58 AM5/10/11
to mongod...@googlegroups.com
Hey.. if you don't want to declare the javascript as a literal function with a return value to make it work with newlines... that's your deal.  When I say "then it should work", I mean, then it will work.

I'm sure your workaround is fabulous.
Reply all
Reply to author
Forward
0 new messages