1

I'm testing the MongoDB Java API and I wanted to do a mapReduce. I implemented it as follow :

String map = "function() { " +
    "emit(this.ts, this.1_bid);}";

String reduce = "function(key, values) {" +
    "return Array.sum(values);}";

MapReduceCommand cmd = new MapReduceCommand(collection, map, reduce, null, MapReduceCommand.OutputType.INLINE, null);
MapReduceOutput out = collection.mapReduce(cmd);

for (DBObject o : out.results()) {
    System.out.println(o.toString());
}

But when I execute it I have the following exception stack :

[tick_engine] 16:51:53.600 ERROR [MongoTickDataReader] Failed to read data from mongoDB
com.mongodb.CommandFailureException: { "serverUsed" : "/127.0.0.1:27017" , "errmsg" : "exception: SyntaxError: Unexpected token ILLEGAL" , "code" : 16722 , "ok" : 0.0}
    at com.mongodb.CommandResult.getException(CommandResult.java:71) ~[mongo-2.11.1.jar:na]
    at com.mongodb.CommandResult.throwOnError(CommandResult.java:110) ~[mongo-2.11.1.jar:na]
    at com.mongodb.DBCollection.mapReduce(DBCollection.java:1265) ~[mongo-2.11.1.jar:na]
    at com.smarttrade.tickEngine.in.MongoTickDataReader.mapReduce(MongoTickDataReader.java:321) ~[classes/:na]
    at com.smarttrade.tickEngine.in.MongoTickDataReader.readData(MongoTickDataReader.java:157) ~[classes/:na]
    at com.smarttrade.tick.engine.TickEngine.onMarketDataRequest(TickEngine.java:203) [classes/:na]
    at com.smarttrade.tick.sttp.TickMarketDataRequestCommand.execute(TickMarketDataRequestCommand.java:62) [classes/:na]
    at com.smarttrade.st.commands.Command.process(Command.java:140) [src/:na]
    at com.smarttrade.st.server.STTPInvoker$1.process(STTPInvoker.java:385) [src/:na]
    at com.smarttrade.st.server.STTPInvoker$1.process(STTPInvoker.java:1) [src/:na]
    at com.smarttrade.util.concurrent.queue.MultiSessionsBlockingQueue$SimpleSession.run(MultiSessionsBlockingQueue.java:122) [src/:na]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_51]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_51]
    at java.lang.Thread.run(Thread.java:744) [na:1.7.0_51]

2 Answers 2

1

The problem seems to be with the attribute name that you have defined - 1_bid

I created sample documents to test your map-reduce -

{ "_id" : ObjectId("533ef7d0e1687dd644410d88"), "ts" : "TSKEY", "1_bid" : 200 }
{ "_id" : ObjectId("533ef7d3e1687dd644410d89"), "ts" : "TSKEY", "1_bid" : 300 }
{ "_id" : ObjectId("533ef7d5e1687dd644410d8a"), "ts" : "TSKEY", "1_bid" : 400 }
{ "_id" : ObjectId("533ef7dce1687dd644410d8b"), "ts" : "TSKEY2", "1_bid" : 800 }
{ "_id" : ObjectId("533ef7dfe1687dd644410d8c"), "ts" : "TSKEY2", "1_bid" : 300 }

I ran following map-reduce command -

db.sample4.mapReduce(function() { emit(this.ts, this.1_bid);},function(key, values) {return Array.sum(values);})

The error that I got is SyntaxError: missing ) after argument list (shell):1

I realized, that the function, that mapper is executing, is a JavaScript function and in Javascript, you cannot have a variable that starts with a number. Hence you get a syntax error. I then created new set of documents -

{ "_id" : ObjectId("533eff29e1687dd644410d8d"), "ts" : "TSKEY", "bid_1" : 200 }
{ "_id" : ObjectId("533eff2de1687dd644410d8e"), "ts" : "TSKEY", "bid_1" : 300 }
{ "_id" : ObjectId("533eff34e1687dd644410d8f"), "ts" : "TSKEY", "bid_1" : 400 }
{ "_id" : ObjectId("533eff7fe1687dd644410d92"), "ts" : "TSKEY2", "bid_1" : 800 }
{ "_id" : ObjectId("533eff85e1687dd644410d93"), "ts" : "TSKEY2", "bid_1" : 300 }

and then modified the mapper to use "bid_1" and ran the following command -

db.sample4.mapReduce(function() { emit(this.ts, this.bid_1);},function(key, values) {return Array.sum(values);},"pivot")

The output was - { "result" : "pivot", "timeMillis" : 61, "counts" : { "input" : 12, "emit" : 12, "reduce" : 2, "output" : 2 }, "ok" : 1, }

db.pivot.find()
{ "_id" : "TSKEY", "value" : 900 }
{ "_id" : "TSKEY2", "value" : 1100 }

I tested this in Java using the same program that you have pasted and just changed the attribute name to "bid_1" and it worked

Sign up to request clarification or add additional context in comments.

Comments

0

To prevent syntax errors on field names, you can also write the map function this way :

function() {
  emit(this["ts"], this["1_bid"]);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.