0

currently I'm working on a project in JAVA, and I need to run the Javascript Mongo queries through JAVA, and I figured I can do something like that using db.eval() in java. Problem is I have the following Javascript query for Mongo, and I have no idea how can I pass the whole Script to the db.eval() method. Any idea ? please let me know. thank you

    var red = function(doc, out) {
    out.count_order++;
    out.sum_qty += doc.quantity;
    out.sum_base_price += doc.extendedprice;
    out.sum_disc_price += doc.extendedprice * (1 - doc.discount);
    out.sum_charge += doc.extendedprice * (1 - doc.discount) * (1 + doc.tax);
    out.avg_disc += doc.discount 
    };
    var avg = function(out) {
    out.avg_qty = out.sum_qty / out.count_order;
    out.avg_price = out.sum_base_price / out.count_order;
    out.avg_disc = out.avg_disc / out.count_order 
    };
    db.deals.group( {
    key : { RETURNFLAG : true, LINESTATUS : true},
    cond : { "SHIPDATE" : {$lte: new Date(1998, 8, 1)}},
    initial: { count_order : 0, sum_qty : 0, sum_base_price : 0, sum_disc_price : 0,
    sum_charge : 0, avg_disc : 0},
    reduce : red,
    finalize : avg
    });
mu is too short
  • 426,620
  • 70
  • 833
  • 800
diba6122
  • 31
  • 1
  • 7
  • 2
    why do you need to pass this as a script? why not use the mongodb java driver and do these as normal queries/commands/etc? – Asya Kamsky Apr 26 '13 at 15:05
  • To add, I don't think the JS engine will give you any benefits here, in fact it might (probably) will give more disadvantages – Sammaye Apr 26 '13 at 15:15
  • Actually I'm working on TPC-H benchmark and I'm trying to compare the query response time, and network latency for raw queries with different DBMS, which MongoDB is one of them, and these raw queries are defined by the Benchmark, and I don't know how to convert them in way to use MongoDB java driver instead. When I try simple javascript queries in db.eval() it is able to run them, but when I tried with the whole script i got exceptions. – diba6122 Apr 26 '13 at 15:29
  • 1
    Also I don't have that much time to convert all these raw queries into Mongodb Java driver format, since I have 27 complex queries,and I have to get results as soon as possible. – diba6122 Apr 26 '13 at 15:38

1 Answers1

0

Looks like you are trying to do a mapreduce and the Java driver abstracts that process and complicates things, but I think the core of your question is how to 1) store js functions and 2) run them in Java

I will address 2) first via an example (I modified you function to return "out" since I think this would otherwise need to be handled differently for mapreduce operations with the driver):

String fnc = "function(doc, out) {" +
    "out.count_order++;"+
    "out.sum_qty += doc.quantity;"+
    "out.sum_base_price += doc.extendedprice;"+
    "out.sum_disc_price += doc.extendedprice * (1 - doc.discount);"+
    "out.sum_charge += doc.extendedprice * (1 - doc.discount) * (1 + doc.tax);"+
    "out.avg_disc += doc.discount; "+
    "return out;" +
    "};";

   BasicDBObject doc = BasicDBObject("_id","doc");
   BasicDBObject out = BasicDBObject("_id","out");

System.out.println(
   (new MongoClient()).getDB('test').eval(fnc,doc,out)
);

WRT 1) (saving functions)... you can save functions in the server in collections. But I have not yet been able to get the Java Driver to find them. In the mongoshell, you can do this (this example comes from Call stored function in mongodb):

system.js.save({
_id: "echoFunction",
value: function (x) {
    return 'echo: ' + x;
 }
})

And run that in the shell with

db.eval("echoFunction('test')")
Rondo
  • 3,458
  • 28
  • 26