English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Метод случайного выбора одной записи в MongoDB

The implementation principle is as follows

    1. First query the total number of records in the table

    2. Randomly get the offset from 0 to total number of records - 1

    3. When querying, use the skip offset to get 1 record

Since my test environment php has been upgraded to 7.0 and above, the mongodb extension uses an extension that supports php7.0 and above, many methods are different from php5.6. Therefore, the code must be run on php7.0 and above. If it is a php5.6 environment, the code needs to be modified to run.

代码如下:

function.php

<?php
// 连接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;
}
// Вставка данных
function add($conn, $dbname, $collname, $data, $index){
 // Создание индекса
 $cmd = array(
  'createIndexes' => $collname,
  'indexes' => array(
   array(
    'name' => 'index',
    'key' => $index,
    'ns' => $dbname.'.'.$collname
   )
  )
 );
 $command = new MongoDB\Driver\Command($cmd);
 $conn->executeCommand($dbname, $command);
 // Вставка данных
 $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;
}
// Получение общего количества записей
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;
}
// Случайное получение одной записи
function randOne($conn, $dbname, $collname){
 // Общее количество записей
 $total = getCount($conn, $dbname, $collname);
 // Случайное смещение
 $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;
}
// 对象转为数组
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');
// 连接mongodb
$conn = conn('localhost','testdb','root','123456');
// 插入50条数据记录
$data = array();
// 索引
$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 '成功插入'.$inserted.'条测试记录数<br><br>';
// 随机获取一条记录,抽5次
echo '随机获取一条记录,抽5次<br>';
$result = array();
for($i=0; $i<5; $i++){
 $result[] = randOne($conn, 'testdb', 'user');
}
echo '<pre>';
print_r($result);
echo '</pre>';
?>

Вывод:

Успешно вставлено 50 тестовых записей

Случайно получить одну запись, вытащить 5 раз

Массив
(
 [0] => Массив
  (
   [user] => test_user_0017
  )
 [1] => Массив
  (
   [user] => test_user_0026
  )
 [2] => Массив
  (
   [user] => test_user_0004
  )
 [3] => Массив
  (
   [user] => test_user_0043
  )
 [4] => Массив
  (
   [user] => test_user_0023
  )
)

Для тестирования php кода, сначала нужно создать testdb в mongodb, создать пользователя и выполнить auth.

Методы такие:

use testdb
db.createUser( 
 { 
  "user":"root", 
  "pwd":"123456", 
  "roles":[{"role" : "readWrite", "db":"testdb"}] 
 } 
) 
db.auth( 
 { 
  "user":"root", 
  "pwd":"123456" 
 } 
) 

Обобщение

Это все содержимое этой статьи, я надеюсь, что содержимое этой статьи поможет вам в изучении или работе, если у вас есть вопросы, пожалуйста, оставляйте комментарии для обсуждения, спасибо за поддержку呐喊 руководства.

Заявление: содержимое этой статьи предоставлено из Интернета, авторские права принадлежат их владельцам, материалы предоставлены пользователями Интернета по их собственной инициативе, этот сайт не имеет права собственности, не был редактирован вручную и не несет ответственности за связанные с этим юридические последствия. Если вы обнаружите подозрительное содержимое, пожалуйста, отправьте письмо по адресу: notice#oldtoolbag.com (при отправке письма замените # на @) для жалоб,并提供 соответствующие доказательства. При обнаружении доказательств, этот сайт немедленно удалит подозреваемое в侵权 содержимое.

Давай, посмотри!