php7安装mongodb的扩展。
宝塔面板环境下php7.3默认安装了pecl扩展包, 安装的php7.4版本是默认不带pecl扩展包的。需要手动安装
php版本 < 7的时候 yum install php-pear 就可以
但是7.4 版本的不行,
$ wget http://pear.php.net/go-pear.phar
$ php go-pear.phar
安排完成后 pecl install mongodb 安装扩展
最后在php.ini 中添加 extension=mongodb.so 重启php后完成
在phpinfo中可以看到
构建一个操作类
我使用的是 hyperf2.0框架 基于 Task 模式 模式构建了 操作类
<?php
declare(strict_types=1);
namespace App\Task;
use Hyperf\Task\Annotation\Task;
use MongoDB\Driver\BulkWrite;
use MongoDB\Driver\Manager;
use MongoDB\Driver\Query;
use MongoDB\Driver\Command;
use MongoDB\Driver\WriteConcern;
use MongoDB\BSON\UTCDateTime;
class MongoTask
{
/**
* @var Manager
*/
public $manager;
/**
* @Task
*/
public function insert(string $table, array $document,$type='count')
{
$document['time']=new UTCDateTime();
$writeConcern = new WriteConcern(WriteConcern::MAJORITY, 1000);
$bulk = new BulkWrite();
$_id=$bulk->insert($document);
$result = $this->manager()->executeBulkWrite(env('MONGODB_DB').'.'.$table, $bulk, $writeConcern);
if($type=='count'){
return $result->getUpsertedCount();
}elseif ($type=='_id'){
return $_id;
}
}
/**
* @Task
*/
public function query(string $table='', array $filter = [], array $options = [],$type='query')
{
if($table){
$table=env('MONGODB_DB').'.'.$table;
}else{
$table=env('MONGODB_DB');
}
switch ($type){
case 'query'; /*普通结果集查询*/
$query = new Query($filter, $options);
$cursor = $this->manager()->executeQuery($table, $query);
return $cursor->toArray();
case 'command'; /*命令*/
$command = new Command($filter);
return $this->manager()->executeCommand($table, $command)->toArray();
case 'update'; /*命令*/
return $this->update($table,$filter,$options);
default:
return false;
}
}
/**
* @Task
*/
public function update(string $db, array $where = [], $update = [], $upsert = false)
{
$writeConcern = new WriteConcern(WriteConcern::MAJORITY, 1000);
$bulk = new BulkWrite();
$bulk->update($where, ['$set' => $update], ['multi' => true, 'upsert' => $upsert]);
$result = $this->manager()->executeBulkWrite($db, $bulk,$writeConcern);
$m = $result->getModifiedCount();
$u = $result->getUpsertedCount();
$res = $m>$u ? $m:$u;
if($res>0){
return 1;
}else{
return 0;
}
}
protected function manager()
{
if ($this->manager instanceof Manager) {
return $this->manager;
}
$uri = 'mongodb://'.env('MONGODB_USER').':'.env('MONGODB_PASS').'@'.env('MONGODB_HOST').':'.env('MONGODB_PORT').'/'.env('MONGODB_DB');
return $this->manager = new Manager($uri, []);
}
}
这个类中 manager方法连接数据库
insert 方法使用 $this->manager()->executeBulkWrite() 实现插入功能;
insert 方法参数 $document 就是一个行记录的数组,$table 就是集合名称,$type 可以决定返回值 是插入的个数还是最后一个插入成功的主键 _id;
这个类中 query 方法我封装了 查询 原生命令 和 update 三种操作。
查询
$options=['projection' => ['_id' => 0,'user'=>1],'sort' => ['_id' => -1],'limit'=>$limit,'skip'=>$start];
参数 projection 映射 类似mysql中的 select 就是要显示哪个字段。0表示不显示 1代表显示 如果没有1 则其余的字段都会显示。
参数 sort 是排序 -1 desc 1 asc 多个字段也是可以的,limit skip和mysql中功能一样
最后细说 $filter参数
$filter['_id']=new \MongoDB\BSON\ObjectId("60779eeb99cc037490518d33");
MongoDB的主键 _id是一个对象,不能直接使用字符搜索 必须需要 ObjectId 转换成对象.
$filter['user_id']=1001 这是最普通的等于搜索
$filter['time']=1618656124 //如果你存储时间是用的时间戳
$filter['time']="2021-04-17 18:42:03" //如果你存储时间是用的字符
$filter['time']=new \MongoDB\BSON\UTCDateTime($time*1000)
//$time 是一个时间戳
insert 方法中 获取当前时间戳对应的时间对象 $document['time']=new UTCDateTime();
$val=['$regex'=>"^a.*z$",'$options'=>'i'];
这个是正则模糊匹配, 能支持三种参数, ^a 以a开始, .* 任意字符, z$ 以z结束。
$options 必须要全小写 对应参数 i或者$i 都可以,代表大小写敏感。 这个参数很多网站上 都是 $Options=>'$i' 大小写,坑了不少人。
$filter['time']=['$gte'=>new UTCDateTime($time0*1000),'$lte'=>new UTCDateTime($time1*1000)]; 这个就相当于 mysql的 BETWEEN AND 包含边界的范围。
其中
(>) 大于 - $gt (>=) 大于等于 - $gte
(<) 小于 - $lt (<= ) 小于等于 - $lte
这些就是最基本的查询
$filter['type']=['$in'=>[1,2,3]] 类似mysql in
$filter['type']=['$nin'=>[1,2,3]] 类似mysql not in
$filter['type']=null 类似mysql is_null
$filter['type']=['$ne'=>null] 类似mysql not is_null
$filter['type']='' 空字符
$filter['type']=['$ne'=>''] 非空字符
$filter['type']=['$exists'=>true] 字段存在
$filter['type']=['$exists'=>false] 字段不存在
$filter['result']=['$type'=>"int"] 字段类型是int
$filter['result']=['$not'=>['$type'=>"string"]] 字段类型不是 string
double array timestamp bool object undefined null 关于mongodb支持的字段类型可以网上搜索
Command 命令
搜索一个库下集合
$cmd=['listCollections' => 1,'filter'=>['name'=>['$regex'=>'^user_log_']],'nameOnly'=>true];
$model->query('',$cmd,[],'command');
$cmd中 'listCollections' => 1 代表要查询库下面啊的集合 filter 是过滤条件 nameOnly 是忽略账号权限。
这个不是针对某个集合的操作 是针对当前数据库的操作。query参数第一个可以留空 我封装的方法会自动识别当前db,你也可以传入某个db。
统计一个集合下的数据量 类似mysql 的 count
$cmd=["count" => $table,"query" =>$filter];
$model->query('',$cmd,[],'command');
$cmd中 count指定某个集合 query 是对集合进行过滤 $filter和搜索中的使用方法一样。
update 操作
$model->query($table,$filter,$arr,'update');
这个方法中 参数 $filter 和查询一样。
$arr=['type'=>5,'$inc'=>['num'=>1]]; type字段设置成5,num 字段自增1 如果 -1 就是自减
mongodb的基本操作就这么多了
还有聚合类操作。下一节会继续细说。
防止误删除啊a