mongodb method of getting a record at random
- 2020-06-07 05:29:34
- OfStack
Principle:
1. First query the total number of records in the table
2. The random offset is 0~ the total number of records -1
3. skip offset during query, and then get 1 record
Since my test environment PHP has been upgraded to 7.0 or above and the mongodb extension USES extensions that support php7.0 or above, many methods are different from php5.6. Therefore, the code must run above php7.0. If it is an php5.6 environment, you need to modify the code to run.
The code is as follows:
function.php
<?php
// The connection mongodb
function conn($host, $user, $passwd){
$server = 'mongodb://'.$user.':'.$passwd.'@'.$host;
try{
$conn = new MongoDB\Driver\Manager();
} catch (MongoDB\Driver\Exception\ConnectionException $e){
throw new ErrorException('Unable to connect to db server. Error:' . $e->getMessage(), 31);
}
return $conn;
}
// Insert data
function add($conn, $dbname, $collname, $data, $index){
// Create indexes
$cmd = array(
'createIndexes' => $collname,
'indexes' => array(
array(
'name' => 'index',
'key' => $index,
'ns' => $dbname.'.'.$collname
)
)
);
$command = new MongoDB\Driver\Command($cmd);
$conn->executeCommand($dbname, $command);
// Insert data
$bulk = new MongoDB\Driver\BulkWrite();
$inserted = 0;
if($data){
foreach($data as $k=>$v){
$bulk->insert($v);
}
$result = $conn->executeBulkWrite($dbname.'.'.$collname, $bulk);
$inserted = $result->getInsertedCount();
}
return $inserted;
}
// Gets the total number of records
function getCount($conn, $dbname, $collname){
$cmd = array(
'count' => $collname,
'query' => array()
);
$command = new MongoDB\Driver\Command($cmd);
$result = $conn->executeCommand($dbname, $command);
$response = current($result->toArray());
if($response->ok==1){
return $response->n;
}
return 0;
}
// Random access 1 records
function randOne($conn, $dbname, $collname){
// The total number of records
$total = getCount($conn, $dbname, $collname);
// Random drift
$skip = mt_rand(0, $total-1);
$filter = array();
$options = array('skip'=>$skip, 'limit'=>1);
$query = new MongoDB\Driver\Query($filter, $options);
$cursor = $conn->executeQuery($dbname.'.'.$collname, $query);
$result = array();
if($cursor){
foreach($cursor as $v){
$v = objectToArray($v);
unset($v['_id']);
$result[] = $v;
}
}
return $result? $result[0] : $result;
}
// Object to array
function objectToArray($obj){
$arr = is_object($obj) ? get_object_vars($obj) : $obj;
if(is_array($arr)){
return array_map(__FUNCTION__, $arr);
}else{
return $arr;
}
}
?>
demo.php
<?php
require('function.php');
// The connection mongodb
$conn = conn('localhost','testdb','root','123456');
// insert 50 Bar data record
$data = array();
// The index
$index = array('user'=>true);
for($i=0; $i<50; $i++){
$data[] = array(
'user' => 'test_user_'.str_pad($i, 4, '0', STR_PAD_LEFT)
);
}
$inserted = add($conn, 'testdb', 'user', $data, $index);
echo ' Successful insertion '.$inserted.' Number of test records <br><br>';
// Random access 1 records , smoke 5 time
echo ' Random access 1 Record, draw 5 time <br>';
$result = array();
for($i=0; $i<5; $i++){
$result[] = randOne($conn, 'testdb', 'user');
}
echo '<pre>';
print_r($result);
echo '</pre>';
?>
Output:
Successful insertion 50 Number of test records
Random access 1 Record, draw 5 time
Array
(
[0] => Array
(
[user] => test_user_0017
)
[1] => Array
(
[user] => test_user_0026
)
[2] => Array
(
[user] => test_user_0004
)
[3] => Array
(
[user] => test_user_0043
)
[4] => Array
(
[user] => test_user_0023
)
)
To test the php code, you first need to create testdb in mongodb and create the user and execute auth. The methods are as follows:
use testdb
db.createUser(
{
"user":"root",
"pwd":"123456",
"roles":[{"role" : "readWrite", "db":"testdb"}]
}
)
db.auth(
{
"user":"root",
"pwd":"123456"
}
)
Source download address: click to view
Thank you for reading, I hope to help you, thank you for your support to this site!