Weird error with group() on floatApprox

206 views
Skip to first unread message

Josh Chia

unread,
Nov 11, 2011, 11:50:49 PM11/11/11
to mongodb-user
I'm getting a "group command failed" with "reduce invoke failed" that
I can't explain.

Part of my reduce function looks like this:

print('5 ' + JSON.stringify(stime));
print('5.1 ' + JSON.stringify(prev.lastAdd[idx].stime));
print('5.2 ' + (stime > prev.lastAdd[idx].stime));

The mongodb log looks like this near the end:

5 {"floatApprox":35413950464}
5.1 {"floatApprox":35412724948}
Fri Nov 11 23:27:43 [conn108] query shadow.$cmd ntoreturn:1 command:
{ group: { key: { sym: true }, cond: { stime: { $lte:
55135940818.0 } }, initial: { pos: 0.0, lastAdd: [ { stime: 0.0 },
{ stime: 0.0 } ], lastCancel: [ 0.0, 0.0 ], lastTrade: [ 0.0, 0.0 ] },
finalize: function (out) {
print("finalize");
...

So, there must have been an error with the print for '5.2 ...'.

Indeed, the error goes away when I compare the floatApprox property
instead of the stime itself. In the BSON object, stime is actually a
64-bit number.

What is floatApprox exactly? Can't I just compare stime normally like
a normal numbers?

Antoine Girbal

unread,
Nov 17, 2011, 1:16:14 PM11/17/11
to mongodb-user
The standard javascript only supports 1 type for numbers, which is a
double (64bit floating point).
There is no standard long.
So mongo represents a standard long as a NumberLong object which
contains a field "floatApprox" which is the float approximation of the
long value.
If the long cannot be precisely represented by a double (happens for
large numbers), it will actually store 2 more fields top & bottom.
Unfortunately the JS engine does not allow to override the operators,
so you must handle it as an object.
You can call toNumber() to get the double value, but if your number is
larger than an int make sure to check if top/bottom fields are set, in
which case value may not be exact.
Reply all
Reply to author
Forward
0 new messages