wizbii / mongo-bundle
3.3.0
2024-09-17 08:39 UTC
Requires
- php: ^8.1
- ext-json: *
- ext-mongodb: *
- mongodb/mongodb: ^1.5
- psr/log: ^3.0
- symfony/config: ^6.4|^7
- symfony/console: ^6.4|^7
- symfony/dependency-injection: ^6.4|^7
- symfony/http-kernel: ^6.4|^7
- symfony/monolog-bundle: ^3.0
- symfony/stopwatch: ^6.4|^7
- symfony/yaml: ^6.4|^7
- wizbii/json-serializer: ^1.4
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.8
- phpstan/phpstan: ^1.7
- phpunit/phpunit: ^9.0
- symfony/framework-bundle: ^6.4|^7
README
目标
此包旨在帮助开发人员以优雅的方式与mongodb进行通信。它减轻了必须操作数组、依赖于像Doctrine ODM这样的重型包的负担。它基于一个MongoClient类,该类提供了大多数基本mongodb操作,但它比基础mongodb实现要容易使用得多。此类实现了一个MongoClientInterface,该接口也被另外两个实现所实现
- 一个InMemory实现,它被设计用于单元测试。大多数查询操作符和更新器都得到了支持。详细信息请见下文
- 一个LocalFile实现,它被设计用于功能测试。它与InMemory实现使用相同的LocalEngine,因此支持相同的查询操作符和更新器
安装
composer require wizbii/mongo-bundle
生产模式下的使用
首先,创建一个包含您的模型的对象。请注意,此对象必须实现https://gitlab.com/wizbii-open-source/json-serializer-bundle中解释的ArraySerializable接口
<?php
namespace App\Model;
use Wizbii\JsonSerializerBundle\ArraySerializable;
class SimpleObject implements ArraySerializable
{
private string $id;
private string $value;
public function __construct(string $id, string $value)
{
$this->id = $id;
$this->value = $value;
}
public function serialize(): array
{
return [
'_id' => $this->id,
'value' => $this->value,
];
}
public static function deserialize(array $contentAsArray)
{
return new self($contentAsArray['_id'], $contentAsArray['value']);
}
}
然后,创建一个需要从mongodb操作此对象的服务
<?php
namespace App\Repository;
use Wizbii\OpenSource\MongoBundle\MongoClientBuilderInterface;
use Wizbii\OpenSource\MongoBundle\MongoClientInterface;
use App\Model\SimpleObject;
class SimpleObjectRepository
{
/** @phpstan-var MongoClientInterface<SimpleObject> */
private MongoClientInterface $mongoClient;
/** @phpstan-param MongoClientBuilderInterface<SimpleObject> $mongoClientBuilder */
public function __construct(MongoClientBuilderInterface $mongoClientBuilder)
{
$this->mongoClient = $mongoClientBuilder->buildFor('test_database', 'simple_object_collection', SimpleObject::class);
}
public function readSimpleObject(string $simpleObjectId): SimpleObject
{
/** @var SimpleObject */
$simpleObject = $this->mongoClient->get($simpleObjectId);
return $simpleObject;
}
/** @return SimpleObject[] */
public function findSimpleObjectNamedRemi(int $rows = 10, int $offset = 0): array
{
return $this->mongoClient->findBy(['name' => 'Rémi'], $rows, $offset);
}
public function createSimpleObject(): string
{
$this->mongoClient->put(new SimpleObject('id-abcd', 'Rémi'));
}
}
当然,您可以使用以下方式调整mongo配置
<?php
namespace App\Repository;
use Wizbii\OpenSource\MongoBundle\MongoClientBuilderInterface;
use Wizbii\OpenSource\MongoBundle\MongoClientInterface;
use App\Model\SimpleObject;
class SimpleObjectRepository
{
/** @phpstan-var MongoClientInterface<SimpleObject> */
private MongoClientInterface $mongoClient;
/** @phpstan-param MongoClientBuilderInterface<SimpleObject> $mongoClientBuilder */
public function __construct(MongoClientBuilderInterface $mongoClientBuilder)
{
$this->mongoClient = $mongoClientBuilder
->overrideConfigurationFor('test_database', 'simple_object_collection', SimpleObject::class)
->setReadPreference('primary')
->setRetryWrites(true)
//->...
->end()->build();
}
}
开发模式下的使用
您的存储库代码没有改变:生产模式和开发模式下的代码相同。但当你执行单元测试时,用于MongoClientBuilderInterface构造函数参数的类将使用InMemory实现。
以下是一个为这样的存储库编写单元测试的示例
<?php
namespace App\Tests\Repository;
use App\Model\SimpleObject;
use App\Repository\SimpleObjectRepository;
use Tests\Wizbii\OpenSource\MongoBundle\MongoClientTestCase;
class SimpleObjectRepositoryTest extends MongoClientTestCase
{
public function test_it_can_create_and_retrieve_simple_objects()
{
$simpleObjectRepository = new SimpleObjectRepository($this->getMongoClientBuilder());
$simpleObjectRepository->createSimpleObject($this->getSimpleObject('remi', 'Rémi'));
$simpleObject = $simpleObjectRepository->readSimpleObject('remi');
$this->assertThat($simpleObject, $this->isInstanceOf(SimpleObject::class));
$this->assertThat($simpleObject->getValue(), $this->equalTo('Rémi'));
}
public function test_it_can_find_simple_objects_by_name()
{
$simpleObjectRepository = new SimpleObjectRepository($this->getMongoClientBuilder());
$simpleObjectRepository->create($this->getSimpleObject('remi-1', 'Rémi'));
$simpleObjectRepository->create($this->getSimpleObject('mark', 'Mark'));
$simpleObjectRepository->create($this->getSimpleObject('remi-2', 'Rémi'));
$simpleObjectRepository->create($this->getSimpleObject('remi-3', 'Rémi'));
$simpleObjects = $simpleObjectRepository->findSimpleObjectNamedRemi();
$this->assertThat($simpleObjects, $this->countOf(3));
$this->assertThat($simpleObjects[0]->getId(), $this->equalTo('remi-1'));
$this->assertThat($simpleObjects[1]->getId(), $this->equalTo('remi-2'));
$this->assertThat($simpleObjects[2]->getId(), $this->equalTo('remi-3'));
}
private function getSimpleObject(string $id, string $value): SimpleObject
{
return new SimpleObject($id, $value);
}
}
支持的Mongo功能
| 查询操作符 | 实际实现 | 本地引擎 | 注释 |
|---|---|---|---|
| $eq | OK | OK | |
| $gt | OK | OK | |
| $gte | OK | OK | |
| $in | OK | OK | |
| $lt | OK | OK | |
| $lte | OK | OK | |
| $ne | OK | OK | |
| $nin | OK | OK | |
| $and | OK | OK | |
| $not | OK | OK | |
| $nor | OK | OK | |
| $or | OK | OK | |
| $exists | OK | OK | |
| $type | OK | OK | 某些类型不受支持。有关详细信息,请参阅TypeFilter类 |
| $expr | OK | KO | |
| $jsonSchema | OK | KO | |
| $mod | OK | KO | |
| $regexp | OK | OK | |
| $text | OK | KO | |
| $where | OK | KO | |
| $geoIntersects | OK | KO | |
| $geoWithin | OK | KO | |
| $near | OK | KO | |
| $nearSphere | OK | KO | |
| $all | OK | OK | |
| $elemMatch | OK | OK | |
| $size | OK | OK | |
| $bitsAllClear | OK | KO | |
| $bitsAllSet | OK | KO | |
| $bitsAnyClear | OK | KO | |
| $bitsAnySet | OK | KO | |
| $comment | OK | OK |
| 更新器 | 实际实现 | 本地引擎 | 注释 |
|---|---|---|---|
| $currentDate | OK | KO | |
| $inc | OK | KO | |
| $min | OK | KO | |
| $max | OK | KO | |
| $mul | OK | KO | |
| $rename | OK | KO | |
| $set | OK | OK | |
| $setOnInsert | OK | KO | |
| $unset | OK | KO | |
| $addToSet | OK | KO | |
| $pop | OK | KO | |
| $pull | OK | KO | |
| $push | OK | KO | |
| $pushAll | OK | KO | |
| $each | OK | KO | |
| $position | OK | KO | |
| $slice | OK | KO | |
| $sort | OK | KO | |
| $bit | OK | KO |
贡献
- 分支存储库
- 进行更改
- 使用
composer dev:checks测试它们(它将运行测试、phpstan和cs:lint子命令) - 创建合并请求