Mongodb PHP - Integers with decimals

2020-02-14 06:48发布

问题:

This is a follow up to another post i made about inserting an integer into mongodb. I have this working just fine by using the (int) but now when it inserts the number into the db is strips everything after the decimal. So if i had 154.65 it would be inserted into the mongodb as 154 with nothing after the decimal.

My question is how do i get this to keep all numbers after the decimal? Also if anyone has a link to these sting/numeric functions i'd appreciate a reference. Thanks.

$number["xyz"]    = (int) $_POST["number"] ;
$collection->insert($number);

This inserts it as a integer but strips everything after the decimal. I tried you suggestion

$number["xyz"]    = floatval($_POST["number"]) ;
$collection->insert($number);

but this still strips off everything after the decimal. My though it i need something that looks like this so that it is in mongo format:

$number["xyz"]    = (dec) $_POST["number"] ;
$collection->insert($number);

回答1:

There is no natively supported decimal format. Your options are floating point (cast prior to saving it), integer (which results in the removal of decimals as you're seeing) or string (cast prior to saving it). The optimal choice depends on your functional requirements. For example, if it's a monetary value you do not want to use floats but store the value in cents as an integer (15465 in your example).



回答2:

I'll try to clear this up for you guys because this was boggling my mind for a bit when trying to sort prices in product category listings.

The way I was able to produce decimal numbers in mongo was in fact to store the values as float.

You can also insert as cents with int or MongoInt64 (divide by 100 afterwards to get back to dollars). Here is my insert/import code using the mongo php class.

$m = new Mongo();
$db = $m->selectDB("test");
$collection = new MongoCollection($db, 'numInt');
$collection2 = new MongoCollection($db, 'numFloat');
$collection3 = new MongoCollection($db, 'numLong');

$collection->insert(array('Integer' => (int)123.54));//I tried a decimal just to see...nope...gets cut off
$collection->insert(array('Integer' => (int)54321));
$collection->insert(array('Integer' => (int)12345));

$collection2->insert(array('Float' => (float)12354));
$collection2->insert(array('Float' => (float)54321));
$collection2->insert(array('Float' => (float)123.45));//*********This was stored as decimal in database results

$collection3->insert(array('Mongo64'=>new MongoInt64('54234.45')));//I tried a decimal just to see...nope...gets cut off
$collection3->insert(array('Mongo64'=>new MongoInt64('75432')));
$collection3->insert(array('Mongo64'=>new MongoInt64('12345')));


//results

//first example int and MongoInt64 (NumberLong in PHP) ***sorted ascending
echo "<strong>Integer Example</strong><br />
           --------------------<br />";

$cursor = $collection->find();
$cursor->sort(array('Integer'=>1));            
foreach($cursor as $obj){
   echo ($obj['Integer']/100)."<br />";
}

echo "<br />";
//second example float ***sorted ascending
echo "<strong>Float Example</strong><br />
              ----------------------------<br />";

$cursor2 = $collection2->find();
$cursor2->sort(array('Float'=>1)); 
foreach($cursor2 as $obj){
   echo ($obj['Float']/100)."<br />";
}

echo "<br />";
//third example float ***sorted ascending
echo "<strong>Number Long (MongoInt64) Example</strong><br />
              ------------------------------<br />";

$cursor3 = $collection3->find();
$cursor3->sort(array('Mongo64'=>1)); 
foreach($cursor3 as $obj){
   echo ($obj['Mongo64']/100)."<br />";
}

This is the output from the php code I posted above....

Integer Example
--------------------
1.23
123.45
543.21

Float Example
----------------------------
1.2345
123.54
543.21

Number Long (MongoInt64) Example
------------------------------
123.45
542.34
754.32

Here were the results of a find() for each of the collections in the mongo shell

> db.numInt.find()
{ "_id" : ObjectId("50a322508c85671a2b000000"), "Integer" : 123 }
{ "_id" : ObjectId("50a322508c85671a2b000001"), "Integer" : 54321 }
{ "_id" : ObjectId("50a322508c85671a2b000002"), "Integer" : 12345 }
> db.numFloat.find()
{ "_id" : ObjectId("50a322508c85671a2b000003"), "Float" : 12354 }
{ "_id" : ObjectId("50a322508c85671a2b000004"), "Float" : 54321 }
{ "_id" : ObjectId("50a322508c85671a2b000005"), "Float" : 123.45 }
> db.numLong.find()
{ "_id" : ObjectId("50a322508c85671a2b000006"), "Mongo64" : NumberLong(54234) }
{ "_id" : ObjectId("50a322508c85671a2b000007"), "Mongo64" : NumberLong(75432) }
{ "_id" : ObjectId("50a322508c85671a2b000008"), "Mongo64" : NumberLong(12345) }
>


回答3:

See what $_POST["number"]; is actually giving you by printing it out. I have a feeling that your problem lies in the input. All of these work as expected:

$collection->insert(array("test"=>"a","float"=>123.45));
$collection->insert(array("test"=>"b","float"=>floatval("123.45")));
$test = array("test"=>"c","float"=>123.45);
$collection->insert($test);

results in:

db.test.find();
{ "_id" : ObjectId("4f2036a6eabc88dd0e000006"), "test" : "a", "float" : 123.45 }
{ "_id" : ObjectId("4f2036a6eabc88dd0e000007"), "test" : "b", "float" : 123.45 }
{ "_id" : ObjectId("4f2036a6eabc88dd0e000008"), "test" : "c", "float" : 123.45 }

Adding some more examples for integers:

$collection->insert(array("test"=>"inta","int"=>new MongoInt32("12345")));
$collection->insert(array("test"=>"intb","int"=>new MongoInt64("123456789")));

results in (at least on my system):

{ "_id" : ObjectId("4f20431feabc88cf3500001b"), "test" : "inta", "int" : 12345 }
{ "_id" : ObjectId("4f20431feabc88cf3500001c"), "test" : "intb", "int" : NumberLong(123456789) }

So, you have to be somewhat careful if you want to store numbers as "real integers" in mongodb.

Update I was corrected by someone at 10gen in that PHP integers are usually stored as integers in mongo, even if the type in the shell shows Number. There is also a setting for the mongo PHP driver that allows you to specify this behavior "native_long". http://php.net/manual/en/mongo.configuration.php