-
Type: Bug
-
Resolution: Fixed
-
Priority: Critical - P2
-
Affects Version/s: 4.0.5, 4.1.6
-
Component/s: Aggregation Framework
-
None
-
Fully Compatible
-
ALL
-
v4.0, v3.6, v3.4
-
Query 2019-02-25
Using the following documents:
db.test.insert({value:NumberDecimal("25")});
db.test.insert({value:NumberDecimal(25)});
Running aggregation operator $sqrt as below:
db.test.aggregate([{ "$addFields":{ "sqrt": {"$sqrt": "$value"}, "exp": {"$exp": "$value"}, } }])
Produces:
{ "_id": ObjectId("..."), "value": NumberDecimal("25"), "sqrt": NumberDecimal("72004899337.38587252416135146612616"), "exp": NumberDecimal("72004899337.38587252416135146612616") }, { "_id": ObjectId("..."), "value": NumberDecimal("25.0000000000000"), "sqrt": NumberDecimal("72004899337.38587252416135146612616"), "exp": NumberDecimal("72004899337.38587252416135146612616") }
Note that the output of the $sqrt is the same as the output of $exp.
Looking at the code, the method Decimal128::squareRoot is exactly the same as Decimal128::exponential :
Decimal128::squareRoot:
https://github.com/mongodb/mongo/blob/r4.1.6/src/mongo/platform/decimal128.cpp#L720
Decimal128::exponential:
https://github.com/mongodb/mongo/blob/r4.1.6/src/mongo/platform/decimal128.cpp#L627
A workaround is to convert the decimal to double first i.e. $toDouble, to bypass the squareRoot method call in expression: https://github.com/mongodb/mongo/blob/r4.1.6/src/mongo/db/pipeline/expression.cpp#L4091
For example:
db.test.aggregate([{ "$addFields":{ "sqrt": {"$sqrt": {"$toDouble":"$value"}}, "exp": {"$exp": "$value"}, } }])