0

I came across an odd occurrence while using mongodb + their java driver. When I do a grouping query the datatype for the key changes from an int to a double.

(ie. I am grouping on a key for 'hours', which is stored as an int within all the objects, but the key changes into a double type in the results I get back).

It isn't a huge issue...but it is weird that it would just arbitrarily change the datatype of a key-value pair like that. Has anyone else had this come up? is this normal behaviour?

Thanks,

p.s. Doing a regular .find() query returns correct datatype, fyi.

Edit: Some example code:

import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.QueryOperators;

public class MongoTestQueries {

private static final String TESTDBNAME = "badgerbadgerbadger";
private static final String TESTCOLNAME = "mushroom";
private static final Long TESTMAX = 50L;

private static final String KEY1 = "a";
private static final String KEY2 = "snake";
private static final String KEY3 = "plane";

/**
 * This starts running it.
 * 
 * @param args
 *            the arguments.
 */
public static void main(final String[] args) {
//You'll need to write your own code here for connecting to db as you see fit.
    MongoConnection mc = new MongoConnection("someserver.com", TESTDBNAME);
    mc.setCurCol(TESTCOLNAME);
    mc.getCurCol().drop();
    mc.setCurCol(TESTCOLNAME);


    DBCollection col = mc.getCurCol();

    populateCollection(col);
    System.out.println(col.count() + " inserted into db.");

    regGroupSearch(col);

}

private static void populateCollection(DBCollection col) {
    for (Long l = 0L; l < TESTMAX; l++) {
        col.insert(new BasicDBObject(KEY1, new Integer(l.intValue())).append(KEY2,
                Math.random()).append(KEY3, (TESTMAX - l) + "a string"));
    }
}

private static void regGroupSearch(final DBCollection col) {
    System.out.println("Group Search:");
    DBObject key = new BasicDBObject(KEY1, true).append(KEY3, true);
    DBObject cond = new BasicDBObject().append(KEY1, new BasicDBObject(QueryOperators.GT, 4.0));
    DBObject initial = new BasicDBObject("count", 0).append("sum", 0);
    String reduce = "function(obj,prev){prev.sum+=obj." + KEY2 + ",prev.count+=1}";
    String finalize = "function(obj){obj.ave = obj.sum/obj.count}";
    DBObject groupResult = col.group(key, cond, initial, reduce, finalize);
    printDBObject(groupResult);
    System.out.println("Done.");
}

private static void printDBObject(final DBObject toPrint) {
    for (String k : toPrint.keySet()) {
        System.out.println(k + ": " + toPrint.get(k));
    }
}

}

CasualT
  • 4,869
  • 1
  • 31
  • 53
  • This question has been answered before on SO: [Long accumulator instead of Double in MongoDB group() function](http://stackoverflow.com/questions/9314300/long-accumulator-instead-of-double-in-mongodb-group-function). The TL;DR scoop: "group() actually runs map/reduce which is JavaScript, and in JavaScript the default number type is a double". – Stennie Aug 11 '12 at 05:39
  • this isn't an accumulated value, this is one of the group-by keys. (also, when I use longs instead of ints, this problem goes away...ie. they stay as non-floating point) – CasualT Aug 12 '12 at 02:25
  • So ints in the "group by" key get converted to doubles, but longs remain longs? Still suspect a side effect of a trip through JavaScript M/R evaluation .. but since JS only has one numeric type, would have guessed the longs to also end up as doubles. Helpful if you can post a gist/pastebin with sample docs + M/R to reproduce so we're testing the same case. – Stennie Aug 12 '12 at 06:19
  • added in test code, there is a line where it has "new Integer()", remove that and replace it with just the straight l value to see it not change. :) – CasualT Aug 12 '12 at 20:10
  • Haven't had a chance to try out your code yet .. will try it out and update ;) – Stennie Aug 17 '12 at 06:43
  • Point of clarification: the `group()` command is implemented in JavaScript as at MongoDB 2.0, but it is *not* a Map/Reduce. The naming of the `reduce()` function perhaps confuses this. Source reference on github: [/src/mongo/db/commands/group.cpp](https://github.com/mongodb/mongo/blob/master/src/mongo/db/commands/group.cpp). – Stennie Aug 22 '12 at 00:28

0 Answers0