Home > Article > Backend Development > Bugs and Strategies for PHP Driver MongoDB Integer Issues_PHP Tutorial
The integer problem mentioned in this article is not actually a problem with MongoDB, but a problem with the PHP driver: MongoDB itself has two integer types, namely: 32-bit integer and 64-bit integer, but the old version of PHP Regardless of whether the operating system is 32-bit or 64-bit, the driver treats all integers as 32-bit integers, resulting in 64-bit integers being truncated. In order to solve this problem while maintaining compatibility as much as possible, the new version of the PHP driver has added the mongo.native-long option, in order to treat integers as 64-bit in 64-bit operating systems. Those who are interested can refer to: 64- bit integers in MongoDB.
So does the PHP driver really completely solve the integer problem? NO! There are still bugs when handling group operations:
To illustrate the problem, let’s first generate some test data:
ini_set('mongo.native_long', 1);
$instance = new Mongo();
$instance = $instance->selectCollection('test', 'test');
for ($i = 0; $i < 10; $i++) {
$instance->insert(array(
'group_id' => rand(1, 5),
'count' => rand(1, 5),
));
}
?>
Next let us use the group operation to group according to group_id and calculate the count in summary:
ini_set('mongo.native_long', 1);
$instance = new Mongo();
$instance = $instance->selectCollection('test', 'test');
$keys = array('group_id' => 1);
$initial = array('count' => 0);
$reduce = '
Function(obj, prev) {
prev.count += obj.count;
}
;
$result = $instance->group($keys, $initial, $reduce);
var_dump($result);
?>
The result is different from what was expected. Count did not accumulate, but became [object Object]. Currently, if group operations must be used, there are two methods to alleviate this problem:
ini_set('mongo.native_long', 0);
$initial = array('count' => (float)0);
These two methods are expedient measures that treat the symptoms rather than the root cause. Since there is a problem with the implementation of group in the current PHP driver, we will bypass it and use other methods to achieve the same function. This method is MapReduce:
ini_set('mongo.native_long', 1);
$instance = new Mongo();
$instance = $instance->selectDB('test');
$map = '
Function() {
emit(this.group_id, this.count);
}
;
$reduce = '
Function(key, values) {
var sum = 0;
for (var index in values) {
sum += values[index];
}
return sum;
}
;
$result = $instance->command(array(
'mapreduce' => 'test',
'map' => $map,
'reduce' => $reduce
));
$result = iterator_to_array($instance->{$result['result']}->find());
var_dump($result);
?>
It takes three steps to put the elephant in the refrigerator, but using MapReduce only requires two steps, Map and Reduce. Here is a PDF document that vividly illustrates the corresponding relationship between GROUP BY in MySQL and MapReduce in MongoDB: