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!


Related articles: