morebec / orkestra-postgresql-document-store
Orkestra 组件,允许轻松将 PostgreSQL 作为文档存储使用。
Requires
- php: >=7.4
- ext-json: *
- doctrine/dbal: ^3.0
- morebec/orkestra-datetime: ^2.5.6
- morebec/orkestra-enum: ^2.5.6
- morebec/orkestra-modeling: ^2.5.6
Requires (Dev)
- ext-dom: *
- friendsofphp/php-cs-fixer: ^2.16
- phpstan/phpstan: ^0.12.7
- phpunit/phpunit: ^9.5
- symfony/var-dumper: 5.*
README
使用 PostgreSQL 的 JSONB 功能实现的文档存储。它基于 doctrine/dbal
内部访问数据库。
安装
composer require morebec/orkestra-postgresql-document-store
使用方法
文档存储使用 doctrine/dbal
访问数据库。因此,它需要一个 DBAL 连接作为构造函数的依赖。它还依赖于来自 morebec/orkestra-date-time
组件的 ClockInterface
,以便访问当前日期和时间。
use Doctrine\DBAL\Configuration; use Doctrine\DBAL\DriverManager; use Morebec\Orkestra\DateTime\SystemClock; use Morebec\Orkestra\PostgreSqlDocumentStore\PostgreSqlDocumentStore; use Morebec\Orkestra\PostgreSqlDocumentStore\PostgreSqlDocumentStoreConfiguration; $connection = DriverManager::getConnection([ 'url' => '...' ], new Configuration()); $config = new PostgreSqlDocumentStoreConfiguration(); $clock = new SystemClock(); $store = new PostgreSqlDocumentStore($connection, $config, $clock);
第二个参数对应于 DocumentStore 的配置。此配置类可用于更改文档存储的行为。
插入文档
要将文档插入到集合中
/** @var Morebec\Orkestra\PostgreSqlDocumentStore\PostgreSqlDocumentStore $store */ $store->insertDocument('users', 'usr123456789', [ 'id' => 'usr123456789', 'username' => 'jane.doe', 'fullname' => 'Jane Doe', 'emailAddress' => 'jane.doe@email.com' ]);
如果集合不存在,它将被自动创建。
查找文档
可以使用文档存储的 findOneDocument
和 findManyDocuments
方法执行查找元素。这些方法接受一个表示 PostgreSQL JSON 查询的字符串或一个 Filter
,这是一个针对文档存储的查询构建器的简单 API
use Morebec\Orkestra\PostgreSqlDocumentStore\Filter\Filter; use Morebec\Orkestra\PostgreSqlDocumentStore\Filter\FilterOperator; $store->insertDocument('users', 'usr123456789', [ 'id' => 'usr123456789', 'username' => 'jane.doe', 'fullname' => 'Jane Doe', 'emailAddress' => 'jane.doe@email.com', 'preferredLanguage' => 'ENGLISH' ]); // Finds a document by its ID. $store->findOneDocument('users', Filter::findById('usr123456789')); // Finds a document by a single field: $store->findOneDocument('users', Filter::findByField('username', FilterOperator::EQUAL(), 'jane.doe')); // Finds a document by a multiple criteria $store->findOneDocument('users', Filter::where('username', FilterOperator::EQUAL(), 'jane.doe') ->or('preferredLanguage', FilterOperator::IS_NOT(), null) ); // You can also use strings to have greater control over the query: $store->findOneDocument('users', 'data->>fullname = \'Jane Doe\'');
如果您使用
Filter
查询构建器,值将自动使用预处理语句占位符进行转义。但是,如果您使用字符串进行查询,值将不会进行转义,您必须确保您不会引入潜在的 SQL 注入漏洞。
内部为每个创建的集合表添加了一个类型为
JSONB
的data
列。这就是为什么如果您正在执行字符串查询,您必须指定data
列。
为了获得更大的控制权,文档存储公开了一个
getConnection
方法,它返回一个DBAL
连接,您可以使用它来使用 doctrine 的查询构建器或原始连接执行更复杂的查询。
更新文档
要更新文档,请使用 updateDocument
方法。此方法不支持部分文档,因此会覆盖存储中的文档以使用提供的文档
use Morebec\Orkestra\PostgreSqlDocumentStore\PostgreSqlDocumentStore; /** @var $store PostgreSqlDocumentStore **/ $store->updateDocument('users', 'usr123456789', [ 'id' => 'usr123456789', 'username' => 'jane.doe', 'fullname' => 'Jane A. Doe', 'emailAddress' => 'new.jane.doe@email.com', 'preferredLanguage' => 'FRENCH' ]);
删除文档
删除文档可以按照以下方式进行
use Morebec\Orkestra\PostgreSqlDocumentStore\PostgreSqlDocumentStore; /** @var $store PostgreSqlDocumentStore **/ $store->removeDocument('users', 'usr123456789');
更改表名前缀。
为了更好地控制它管理的集合表,文档存储为它创建的任何表添加一个前缀。
此前缀可以在文档存储配置中配置
use Morebec\Orkestra\PostgreSqlDocumentStore\PostgreSqlDocumentStoreConfiguration; $config = new PostgreSqlDocumentStoreConfiguration(); $config->collectionPrefix = 'you_prefix_';
事务管理
如果您需要为操作使用事务,可以通过访问 DBAL 连接来实现
$connection = $store->getConnection(); $connection->transactional(static function() use ($store) { $store->insertDocument('users', 'usr123456789', [ 'id' => 'usr123456789', 'username' => 'jane.doe', 'fullname' => 'Jane Doe', 'emailAddress' => 'jane.doe@email.com', 'preferredLanguage' => 'ENGLISH' ]); $store->insertDocument('users', 'usrABCDEFGHI', [ 'id' => 'usrABCDEFGHI', 'username' => 'john.doe', 'fullname' => 'John Doe', 'emailAddress' => 'john.doe@email.com', 'preferredLanguage' => 'SPANISH' ]); });
测试
要运行测试,请执行以下命令
vendor/bin/phpunit tests/
需要有一个运行中的 PostgreSQL 实例,密码为空的 postgres
角色和名为 postgres
的数据库。为了轻松设置和运行,此项目的根目录中提供了一个 docker-compose
配置文件。
要运行它,请简单地执行以下命令
docker-compose up -d