Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the MongoDB CPAN distribution.

Maintainer(s)' notes

Please don't report bugs here. Please use the MongoDB Perl driver issue tracker instead.

Report information
The Basics
Id: 62680
Status: rejected
Priority: 0/
Queue: MongoDB

People
Owner: Nobody in particular
Requestors: bitcard [...] ew.ewheeler.org
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: 0.39
Fixed in: (no value)



Subject: Numbers may arrive as parameters to MongoDB as Strings, or vice-versa!
Numbers in Perl may arrive as parameters to MongoDB as Strings. Without normalization, this can cause the appearance of lost data or data duplication. While this might be a feature, you may consider documenting this behavior as an option. ======= Code To Reproduce Bug on 0.39 ======== use MongoDB; use MongoDB::Connection; use strict; print "MongoDB Version: $MongoDB::VERSION\n"; my $m = MongoDB::Connection->new; my $db = $m->test_db; my $c = $db->test_collection; # Integers $c->insert( { x => 123 } ); my $ret = $c->find_one( { x => '123' } ); print "can NOT find '123' because it was stored as an integer\n" if (!defined($ret)); $ret = $c->find_one( { x => 123 } ); print "CAN find 123 because it was stored as an integer\n" if ( defined($ret)); # Floats $c->insert( { x => 123.45 } ); $ret = $c->find_one( { x => '123.45' } ); print "can NOT find '123.45' because it was stored as a float\n" if (!defined($ret)); $ret = $c->find_one( { x => 123.45 } ); print "CAN find 123.45 because it was stored as a float\n" if ( defined($ret)); ====== Output ====== MongoDB Version: 0.39 can NOT find '123' because it was stored as an integer CAN find 123 because it was stored as an integer can NOT find '123.45' because it was stored as a float CAN find 123.45 because it was stored as a float ====== Perl Versions ====== Tested using Perl v5.10.1 as distributed by Ubuntu 10.04 Same result when using ActivePerl v5.12.2 ====== Possible Solutions ===== 1. Force all values to cast as a string: $string = '' . $x 2. Create MongoDB::Number-like datatype objects for explicit typing into the MongoDB. (If you do this, #1 should be default, IMO) 3. Attempt to guess the data type and cast it appropriately when storing it in MongoDB. (this could be slow) 4. Do something amazing that only the great insight of the maintainer would know of, that would resolve this for every possible use of the perl MongoDB module! Thank you for your help! -Eric
Show quoted text
> While this might be a feature, you may consider documenting this > behavior as an option.
Good idea, I've added a section to the documentation on this. It is a feature and cannot be changed. Show quoted text
> 1. Force all values to cast as a string: > $string = '' . $x
MongoDB will then treat all numbers as strings, making things like range queries behave strangely. Also, strings take up more space than numbers. Show quoted text
> 2. Create MongoDB::Number-like datatype objects for explicit typing into > the MongoDB. (If you do this, #1 should be default, IMO)
You can use int or bigint. Show quoted text
> 3. Attempt to guess the data type and cast it appropriately when storing > it in MongoDB. (this could be slow)
You might want to check out some of the ODMs, they often enforce type safety for you. Show quoted text
> 4. Do something amazing that only the great insight of the maintainer > would know of, that would resolve this for every possible use of the > perl MongoDB module!
Sadly, no, MongoDB is just different in this respect from SQL dbs. MongoDB is more picky about types. On Wed Nov 03 17:02:35 2010, theg33kb0y wrote: Show quoted text
> Numbers in Perl may arrive as parameters to MongoDB as Strings. Without > normalization, this can cause the appearance of lost data or data > duplication. > > While this might be a feature, you may consider documenting this > behavior as an option. > > > ======= Code To Reproduce Bug on 0.39 ======== > use MongoDB; > use MongoDB::Connection; > use strict; > print "MongoDB Version: $MongoDB::VERSION\n"; > > my $m = MongoDB::Connection->new; > my $db = $m->test_db; > my $c = $db->test_collection; > > # Integers > $c->insert( { x => 123 } ); > my $ret = $c->find_one( { x => '123' } ); > print "can NOT find '123' because it was stored as an integer\n" if > (!defined($ret)); > > $ret = $c->find_one( { x => 123 } ); > print "CAN find 123 because it was stored as an integer\n" if ( > defined($ret)); > > # Floats > $c->insert( { x => 123.45 } ); > $ret = $c->find_one( { x => '123.45' } ); > print "can NOT find '123.45' because it was stored as a float\n" if > (!defined($ret)); > > $ret = $c->find_one( { x => 123.45 } ); > print "CAN find 123.45 because it was stored as a float\n" if ( > defined($ret)); > > > ====== Output ====== > MongoDB Version: 0.39 > can NOT find '123' because it was stored as an integer > CAN find 123 because it was stored as an integer > can NOT find '123.45' because it was stored as a float > CAN find 123.45 because it was stored as a float > > ====== Perl Versions ====== > Tested using Perl v5.10.1 as distributed by Ubuntu 10.04 > Same result when using ActivePerl v5.12.2 > > ====== Possible Solutions ===== > 1. Force all values to cast as a string: > $string = '' . $x > > 2. Create MongoDB::Number-like datatype objects for explicit typing into > the MongoDB. (If you do this, #1 should be default, IMO) > > 3. Attempt to guess the data type and cast it appropriately when storing > it in MongoDB. (this could be slow) > > 4. Do something amazing that only the great insight of the maintainer > would know of, that would resolve this for every possible use of the > perl MongoDB module! > > Thank you for your help! > > -Eric