bvtvd / mongo-db
Requires
- php: >=7.2
- hyperf/cache: ~1.1.0
- hyperf/command: ~1.1.0
- hyperf/config: ~1.1.0
- hyperf/contract: ~1.1.0
- hyperf/di: ~1.1.0
- hyperf/pool: ^1.1.0
- hyperf/task: ~1.1.0
- hyperf/utils: ~1.1.0
- mongodb/mongodb: ^1.5
- psr/container: ^1.0
Requires (Dev)
- hyperf/di: ~1.1.0
- dev-master
- v2.0.2
- v2.0.1
- v2.0.0.x-dev
- v1.0.38
- v1.0.37
- v1.0.36
- v1.0.35
- v1.0.34
- v1.0.33
- v1.0.32
- v1.0.31
- v1.0.30
- v1.0.29
- v1.0.28
- v1.0.27
- v1.0.26
- v1.0.25
- v1.0.24
- v1.0.23
- v1.0.22
- v1.0.21
- v1.0.20
- v1.0.19
- v1.0.18
- v1.0.17
- v1.0.16
- v1.0.15
- v1.0.14
- v1.0.13
- v1.0.12
- v1.0.11
- v1.0.10
- v1.0.9
- v1.0.8
- v1.0.7
- v1.0.6
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- dev-develop
This package is auto-updated.
Last update: 2024-12-17 12:11:12 UTC
README
默认使用mongodb提供的库来封装,官方git地址:https://github.com/mongodb/mongo-php-library
1、支持类似mysql orm的一些操作
2、支持迁移文件
3、只支持hyperf框架,由于swoole协程不支持mongodb,所以所有的方法都采用task进程来实现,该包已经封装好所有的方法都会投递到task进程进行操作,task进程建议开启多一点
4、该包默认使用了连接池
注意:
1、v1.0+版本只会维护不增加功能
2、开启v2.0分支,跟1.0有很大区别,因为hyperf采用了laravel的orm,所以我会参考laravel-mongodb来封装
3、使用v1.0+时,如果你开一百多个task进程处理,你的宿主机内存不大时,并发请求多,导致内存没有被释放,这时候你的宿主机可能会down机,所以建议开启swoole的task配置,task_max_request=2,这个配置的意思是task进程处理两次请求后会自动kill这个task进程,重新拉起一个新的task进程,这样就不会导致你的宿主机内存过大而导致服务器down机
v1.0+有个大bug,目前无法解决,实际是目前操作mongodb都没有丢到task处理,需要hyperf2.0才能解决,具体情况这个issue[hyperf/hyperf#1798]
这个bug目前我们在项目中如何解决,有两种方法:
1、在model里面新增一个getMethod方法,这个方法申请要丢到task处理
<?php
declare(strict_types=1);
namespace TmgAddon\WebQySession\Model;
use Hyperf\Task\Annotation\Task;
use Phper666\MongoDb\MongoDb;
class Test extends MongoDb
{
public $collectionName = 'test';
public static function collectionName()
{
return 'test';
}
/**
* @Task(timeout=20)
* @return array
*/
public function getMethod($method, ...$params)
{
return $this->{$method}(...$params);
}
}
// 调用,实际跟原有的findOne调用的参数是一致的,只不过第一个参数时申明要调用申明方法
$data = make(Test::class)->getMethod('findOne', ['name' => '1'], ['projection' => ['name' => 1]]);
2、在你使用Test这个模型的方法直接申明丢到Task处理,这个方式不是万能的,因为Task不能处理一些需要在协程下处理的东西,例如co或者协程http,所以只能是第一种和第二种方法结合使用
使用
1、拉取包
composer require phper666/mongo-db
2、发布配置
php bin/hyperf.php mongodb:publish --config
3、配置介绍
<?php
declare(strict_types=1);
return [
'default' => [
'uri_options' => [
'ssl' => true,
'username' => env('MONGODB_USERNAME', ''),
'password' => env('MONGODB_PASSWORD', ''),
// 'authMechanism' => env('MONGODB_AUTH_MECHANISM', 'SCRAM-SHA-256'),
//设置复制集,没有不设置
// 'replicaSet' => 'rs0',
],
'host' => env('MONGODB_HOST', '127.0.0.1'),
'port' => env('MONGODB_PORT', 27017),
'db' => env('MONGODB_DB', 'test'),
'driver_options' => [],
'migration' => [
'path' => BASE_PATH . '/migrations/mongodb', // 迁移文件的路径
],
'pool' => [
'min_connections' => 1,
'max_connections' => 100,
'connect_timeout' => 10.0,
'wait_timeout' => 3.0,
'heartbeat' => -1,
'max_idle_time' => (float)env('MONGODB_MAX_IDLE_TIME', 60),
],
],
];
4、生成迁移文件
php bin/hyperf.php mongodb:migration Test
上面的命令会自动生成一个迁移文件,会生成一个文件到配置文件指定的迁移目录中
5、迁移文件例子
<?php
declare(strict_types=1);
namespace Phper666\MongoDb\Example\Migrations;
use Phper666\MongoDb\MongoDbMigration;
class CreateTestCollection extends MongoDbMigration
{
/**
* 支持很多方法,请详细去看MongoDbMigration这个类
* @throws \Phper666\MongoDb\Exception\MongoDBException
*/
public function up()
{
$msg = [];
$msg[] = $this->createCollection('test'); // 创建一个表
$data = [
['dd' => 1, 'tt' => 2],
['dd' => 2, 'tt' => 4],
];
$msg[] = $this->insertMany('test', $data); // 插入多条数据
$msg[] = $this->createIndex('test', ['dd' => 1, 'tt' => 1]); // 在该表上创建索引
$msg[] = $this->createIndexes('test', [['dd' => 1], ['tt' => 1]]); // 在该表上批量创建索引
$msg[] = $this->dropCollection('test'); // 删除一个表
return $msg;
}
/**
* 迁移失败时会执行
* @throws \Phper666\MongoDb\Exception\MongoDBException
*/
public function down()
{
return 'error';
}
}
6、迁移命令
php bin/hyperf.php mongodb:migrate
上面这个命令会迁移你所有生成的文件,迁移文件路径在配置文件里面配置
7、开发使用
1、上面能像orm一样能进行迁移了,解决了升级的问题,下面我们来说一下开发时候怎么使用
2、在你的项目里面新建一个目录,该目录叫mongo(自行命名,类似orm的model)
3、比如我现在项目里面有一个库,叫test,test里面有两个collection,名字为co1,co2(你把它当成mysql的表一样)
4、我在mongo目录新建两个文件,叫Co1Mongo和Co2Mongo,都继承\Phper666\MongoDb\MongoDb
<?php
declare(strict_types=1);
namespace TmgAddons\WebQySession\Admin\Mongo;
use Phper666\MongoDb\MongoDb;
class TestMongo extends MongoDb
{
/**
* mongodb表
* @var null
*/
public $collectionName = 'co1';
}
5、查询co1中的一条数据
<?php
declare(strict_types=1);
namespace TmgAddons\WebQySession\Admin\Controller;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use TmgAddons\WebQySession\Admin\Mongo\Co1Mongo;
/**
* @Controller(prefix="/test")
* Class TestController
* @package TmgAddons\WebQySession\Admin\Controller
*/
class TestController
{
/**
* @Inject()
* @var Co1Mongo
*/
private $co1Mongo;
/**
* @GetMapping(path="")
* @return array
* @throws \Phper666\MongoDb\Exception\MongoDBException
*/
public function test()
{
return response_success($this->co1Mongo->findOne());
}
}
调用test方法时,就能查出co1表中的一条数据了,是不是很简单!
6、支持有多种方法,详细你可以到Phper666\MongoDb\MongoDb查看,或者你可以去看官方的php-mongodb文档,https://docs.mongodb.com/php-library/v1.5/reference/method/MongoDBCollection-createIndexes/
8、结束
如果你有使用的问题或者建议,欢迎你提一个isset,由于太匆忙,等我开发完现在的项目,我会重新优化和迭代这个包,如果开发中有遇到问题或者有更好的写法,我会迭代到这个包这里。
9、注意
如果你使用的是mongodb默认生成_id,那么更新和删除我默认已经帮你使用MongoDB\BSON\ObjectId进行了转换,所以你无需再转换,你直接把_id对应的字符串传进去就好了,比如要根据_id获取某条数据,$filter=['_id' => 'xxxxxx']即可。获取数据时,我也默认帮你把_id转成了字符串
10、遇到问题
1、因为我使用了hyperf框架,所以基本都是单例模式。我model里面使用\Phper666\MongoDb\MongoDb 的setCollectionName方法来切换表时,必须处理完逻辑后然后再切回原始的collectionName,否则你查询的会是你切换的表