C# driver - decimal values appear to convert to string - how to query?

4,405 views
Skip to first unread message

Stuart

unread,
Jan 23, 2011, 3:30:52 PM1/23/11
to mongodb-user
I have a decimal value on a POCO that is serialized into MongoDB using
the 'official' C# driver.

It appears that it is serialized as a string value, I guess because a
double doesn't have the accuracy.

However, I want to use this value in a query. Specifically, I want to
find all instances where the value is between a minimum and maximum
amount.

Can someone please explain how to do this?

Thanks,

Stuart

Robert Stam

unread,
Jan 23, 2011, 3:56:27 PM1/23/11
to mongodb-user
You are correct in assuming that a decimal is saved as a string
because double does not have sufficient accuracy.

You could have an additional property of type double that had the same
value (or as close to the same value as possible) as your decimal
column and query against that.

I don't think you can query against your string column directly
because it will be using alphabetical sort order.

Ken Egozi

unread,
Jan 23, 2011, 3:57:47 PM1/23/11
to mongod...@googlegroups.com
I do not believe the there is an equivalent to Decimal in mongoDB.

what you can do is to:
 use long, with the appropriate Units of Measure (if it's money, use cents, etc.)

you could also use zero-padded strings which will take more room, especially index-wise (am I correct here?) but is not limited to the size of long. 





--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.




--
Ken Egozi.
http://www.kenegozi.com/blog
http://www.delver.com
http://www.musicglue.com
http://www.castleproject.org
http://www.idcc.co.il - הכנס הקהילתי הראשון למפתחי דוטנט - בואו בהמוניכם

Sam Millman

unread,
Jan 23, 2011, 4:02:56 PM1/23/11
to mongod...@googlegroups.com
I think mongo can min-max over a string as well cant it? but then again that would give unpredicatable results for maths
Bow Chicka Bow Wow

Ken Egozi

unread,
Jan 23, 2011, 4:15:42 PM1/23/11
to mongod...@googlegroups.com
if you know the precision, then zero-pad it yourself.
e.g.

000289.30000
000289.32000
001289.32000

sort would work.

although as I said, for most possible ranges I'd use a 64 bit integer, standing for the smallest relevant unit of measure for the field (millimetres for engineering blueprints, metres street maps, etc)

MiddleTommy

unread,
Jan 24, 2011, 10:45:12 AM1/24/11
to mongodb-user
I just ran in to this problem as Silverlight prefers decimal vs
double. I dont need the precision of decimal but do not want to
rewrite some Math functions in silverlight. and in the past I found
that doubles would give me strange answers like (2.0 + 2.0) /
2.0=1.99999999... (but this was back in C# 2.0. I have not used them
much since) I prefer the decimal in real time but a double on storage.

So I wrote my own decimal serializer copying the source code. and
adding the conversion of decimal to double (for mongo storage) and
back.

Then I register it like so.
BsonSerializer.LookupSerializer(typeof(decimal));//to initialize
serializers so they dont overwrite MyDecimalSerializer
MyDecimalSerializer.RegisterSerializers();//copy of original
serializer

I wont post any other source code because mine only works with the
latest binary release and not the current source
If you want it it's available.

Robert Stam

unread,
Jan 24, 2011, 11:00:52 AM1/24/11
to mongodb-user
The C# driver has the general notion of being able to specify the
representation used to store a property (though not all possible
combinations are valid), so perhaps the following would be useful:

public class C {
// other fields
[BsonRepresentation(BsonType.Double)]
public decimal D;
}

NOTE: the serializer does not currently support this representation
for decimal, but it sounds useful. It would mean the value is
represented as a decimal in memory but as a double in the serialized
BSON document. It would also make queries against the field easier.
However, read the next paragraphs...

By default the serializer throws an OverflowException or a
TruncationException when converting between numeric types results in
loss of magnitude or precision, but you can override that as follows:

public class C {
// other fields
[BsonRepresentation(BsonType.Double, AllowTruncation=true)]
public decimal D;
}

Presumably AllowOverflow=true is not as useful as loss of magnitude is
a far bigger error than loss of precision. Even loss of precision
means that it is possible that you might not read back from the
database the EXACT same value you put in (which is why a string
representation is the default).
Reply all
Reply to author
Forward
0 new messages