REQUEST: runCommand

174 views
Skip to first unread message

tom

unread,
Jan 2, 2012, 12:52:42 AM1/2/12
to luam...@googlegroups.com
Adding runCommand would enable luamongo to make important aggregate querys like distinct, group etc.

shell example: db.runCommand({distinct: 'country', key: 'name', query: ''})

moreover, the new upcoming aggregation framework (2.1)  is running via runCommand too.

http://www.mongodb.org/display/DOCS/Aggregation+Framework+-+Expression+Reference

db.runCommand(
{ aggregate : "article", pipeline : [
{ $group : {
_id : "$author",
docsPerAuthor : { $sum : 1 } , /* add one to "docsPerAuthor" for every document by this (_id) author */
viewsPerAuthor : { $sum : "$pageViews" } /* sum the pageViews for every document by this (_id) author */
}}
]});










Evan

unread,
Jan 2, 2012, 12:55:56 PM1/2/12
to luamongo
Here is a paste of an implementation of this. I don't have a mongodb/
luamongo development setup right now so I can't test it.

https://gist.github.com/1540828

Also for getLastError:
https://gist.github.com/1540945

-Evan

On Jan 2, 12:52 am, tom <tombon2...@gmail.com> wrote:
> Adding runCommand would enable luamongo to make important aggregate querys
> like distinct, group etc.
>
> shell example: db.runCommand({distinct: 'country', key: 'name', query: ''})
>
> moreover, the new upcoming aggregation framework (2.1)  is running via
> runCommand too.
>
> http://www.mongodb.org/display/DOCS/Aggregation+Framework+-+Expressio...

tombo...@gmail.com

unread,
Jan 2, 2012, 5:56:41 PM1/2/12
to luam...@googlegroups.com
thanks for the reply and new code evan,

just added the run_command into mongo_dbclient.cpp.
get an error during make.
mongo_dbclient.cpp:716: error: ‘luaL_tointeger’ was not declared in this
scope

haven't found luaL_tointeger nor a macro in lauxlib.h.
(box is ubuntu 10.04x64 desktop. Lua 5.1)

compiles without error when I change
-> int options = luaL_tointeger(L, 4);
to
-> int options = lua_tointeger(L, 4);


RESULTS:
local jquery = "{distinct: 'country', key: 'short', query: ''}"
res,err = mdb:run_command("test", jquery)

is delivering a correct nested (stats, values) result-table with
distinct countries. great!

a more compley query: (SQL -> SELECT m_country_ref, COUNT(*) FROM test
WHERE m_country_ref >= 100 GROUP BY m_country_ref)

local jquery = "{group : {ns : 'country' , cond : {m_country_ref: {$gt:
100}}, key : {m_country_ref : 1}, initial : {count: 0}, $reduce :
function(obj,prev) {prev.count++}}}"

is crashing with as JSON parsing error.

Both queries are running as unmodified string direct via mongo shell
command without errors.

------------------------------------------------------------------------------------------------------

http://www.mongodb.org/display/DOCS/Aggregation

EXAMPLE:

> db.addresses.insert({"zip-code": 10010})
> db.addresses.insert({"zip-code": 10010})
> db.addresses.insert({"zip-code": 99701})


DISTINCT: -> db.runCommand( { distinct: 'addresses', key: 'zip-code' } )

{
"values" : [
10010,
99701
],
"stats" : {
"n" : 3,
"nscanned" : 3,
"nscannedObjects" : 3,
"timems" : 0,
"cursor" : "BasicCursor"
},
"ok" : 1
}

GROUP: ->

db.addresses.group( { key: {'zip-code': true}, cond: {}, reduce:
function(obj,prev) {prev.count ++;}, initial: {count: 0} });


[
{
"zip-code" : 10010,
"count" : 2
},
{
"zip-code" : 99701,
"count" : 1
}
]

or via $cmd

> db.$cmd.findOne( {group : { ns: 'addresses' , key: {'zip-code':
true}, cond: {}, $reduce: function(obj,prev) {prev.count ++;}, initial:
{count: 0} }});
{
"retval" : [
{
"zip-code" : 10010,
"count" : 2
},
{
"zip-code" : 99701,
"count" : 1
}
],
"count" : 3,
"keys" : 2,
"ok" : 1
}

OR

> db.runCommand( {group : { ns: 'addresses' , key: {'zip-code': true},
cond: {}, $reduce: function(obj,prev) {prev.count ++;}, initial: {count:
0} }});
{
"retval" : [
{
"zip-code" : 10010,
"count" : 2
},
{
"zip-code" : 99701,
"count" : 1
}
],
"count" : 3,
"keys" : 2,
"ok" : 1
}


--------------------------------------------------------------------------------

get_last_error is getting me this error during compiling.

-> mongo_dbclient.cpp:762: error: ‘struct std::string’ has no member
named ‘cstr’

unfortunatly I can't help in this, since I am not a C/C++ coder.
I would like to help in testing (with big datasets mapreduce etc.) and
later some parts of documentation/examples when needed.

best
tom


Evan

unread,
Jan 2, 2012, 6:09:09 PM1/2/12
to luamongo
lua_tointeger is the proper call. Thanks for fixing and testing it.

The "cstr" in get_last_error should be "c_str"

[Sorry, I typed these into a pastebin and didn't run them through a
compiler.]

When you say "a more complex query .. is crashing with as JSON parsing
error", do you literally mean a crash/segfault or is it a Lua error?
Can you paste the output?

Thanks for the sample set. I'll try to get a luamongo development
setup next weekend.

-Evan



On Jan 2, 5:56 pm, "tombon2...@gmail.com" <tombon2...@gmail.com>
wrote:

tombo...@gmail.com

unread,
Jan 2, 2012, 6:32:50 PM1/2/12
to luam...@googlegroups.com

changed to c_str but getting now:
mongo_dbclient.cpp:761: error: no matching function for call to
‘mongo::DBClientBase::getLastError(bool&, bool&, int&, int&)’

/mongo-cxx-driver-latest/mongo/client/dbclient.h:475: note: candidates
are: std::string mongo::DBClientWithCommands::getLastError()
make: *** [mongo_dbclient.o] Fehler 1

Query-Error-Message:


Assertion: 10340:Failure parsing JSON string near: group : {
0x7f18902ac9f9 0x7f1890298267 0x7f1890285151 0x4089d1 0x412289 0x408e9d
0x408547 0x4085c2 0x405c31 0x40441a 0x404f43 0x4089d1 0x408e54 0x408547
0x4085c2 0x405bd7 0x404351 0x7f1890561c4d 0x404149
/usr/local/lib/lua/5.1/mongo.so(_ZN5mongo11msgassertedEiPKc+0x119)
[0x7f18902ac9f9]
/usr/local/lib/lua/5.1/mongo.so(_ZN5mongo8fromjsonEPKcPi+0x5f7)
[0x7f1890298267]
/usr/local/lib/lua/5.1/mongo.so(+0x57151) [0x7f1890285151]
lua() [0x4089d1]
lua() [0x412289]
lua() [0x408e9d]
lua() [0x408547]
lua() [0x4085c2]
lua(lua_pcall+0x51) [0x405c31]
lua() [0x40441a]
lua() [0x404f43]
lua() [0x4089d1]
lua() [0x408e54]
lua() [0x408547]
lua() [0x4085c2]
lua(lua_cpcall+0x27) [0x405bd7]
lua(main+0x41) [0x404351]
/lib/libc.so.6(__libc_start_main+0xfd) [0x7f1890561c4d]
lua() [0x404149]
false Error calling mongo.Connection.run_command: Failure parsing JSON
string near: group : {

best
tom

Evan

unread,
Jan 2, 2012, 6:46:28 PM1/2/12
to luamongo
OK, I see the problem with getLastError... the tip of the mongodb on
github is newer than what you and I have installed (I have 1.8.2).

Here's a new paste which should be compatible (and adds another
method):
https://gist.github.com/1540945

Thanks for the parsin error. Segfaults shouldn't happen in a
scripting interface, but this may be outside of our control (would
need to be fixed in mongo). I'll be able to verify better later.

-Evan

On Jan 2, 6:32 pm, "tombon2...@gmail.com" <tombon2...@gmail.com>
wrote:

tombo...@gmail.com

unread,
Jan 2, 2012, 6:57:39 PM1/2/12
to luam...@googlegroups.com
ok, will check the JSON string also for some modification by try on
error. sometimes is it nessesary to change the order correctly, wrap
even fieldnames or add inline tags etc. mongo is like a diva in this.

just a quick notice.

running a real distinct query against 6.681.816 documents
direct via mongo shell takes 4.342 msec. and 3.936 msec. via luamongo.
nice! that's really fast.

thanks for this speedy binding evan...


tombo...@gmail.com

unread,
Jan 2, 2012, 7:09:54 PM1/2/12
to luam...@googlegroups.com

great, built without problems and returning what expected.

str = db:get_last_error()

print (type(str)) -> string
print(str) -> ""

tbl = db:get_last_error_detailed()

print(tbl) -> table: 0xd3b920

pairs(tbl) ->

ok 1
connectionId 70
err NULL
n 0

tom

Evan

unread,
Jan 2, 2012, 7:34:18 PM1/2/12
to luamongo
Something you could also try is to pass a Lua table rather than JSON
string. In each case, the values are converted to BSON objects. But
one is done by mongo C++ API's JSON handler and the other is by
luamongo.

Here's the Lua for that:
local query = {
group = {
ns = 'country',
cond = { m_country_ref = { ['$gt'] = 100 } },
key = { m_country_ref = 1 },
initial = { count = 0 },
['$reduce'] = 'function(obj,prev) {prev.count++}'
}
}
-- I'm not sure if the function part is OK or if it needs to be some
other BSON type (code_w_s?)

Also note that there is the mongo.tojson and mongo.jfromjson
functions. I'm not sure if that can be helpful or not.

Good luck!


On Jan 2, 6:57 pm, "tombon2...@gmail.com" <tombon2...@gmail.com>
wrote:

tombo...@gmail.com

unread,
Jan 2, 2012, 8:57:56 PM1/2/12
to luam...@googlegroups.com

wow, it's running!
converting to a lua table made it.
this was very important, now let the dataflow begin ;-)

with a solid runCommand mongodb will combine the traditional
RDBMS strenght with noSQl advantages. very nice.

tomorrow I will download the current nightly built mongodb 2.1
which shall contain the new aggregate framework for testing.

additional I will check the mapreduce function again with lua tables
instead JSON and report what happened. a quick test for the eval
function could be interesting for server side routines also.

thx a lot evan, I own you a little more than a beer ;-)

Evan

unread,
Jan 2, 2012, 9:23:17 PM1/2/12
to luamongo
Excellent! Thanks for the testing. Once I get my environment up, I
will make a commit and ask Moai to pull it.

Cheers,
Evan


On Jan 2, 8:57 pm, "tombon2...@gmail.com" <tombon2...@gmail.com>
wrote:
Reply all
Reply to author
Forward
0 new messages