cta-k12 / search-bundle
提供了一种快速将搜索、排序和过滤功能添加到Doctrine ORM实体中的方法
Requires
- php: ^7.1.3
Requires (Dev)
- doctrine/annotations: ^1.6
- phpunit/phpunit: ^7
- symfony/debug-bundle: ^4.1
- symfony/framework-bundle: ^4.1
- symfony/orm-pack: ^1.0
This package is not auto-updated.
Last update: 2024-10-03 15:55:32 UTC
README
为实体快速添加过滤、排序和文本搜索功能。目前,搜索设置远未达到高效或高性能,但它允许我们快速构建出满足政府业务需求的搜索工具,在这些需求中,我们需要搜索大量实体,而这些实体没有太多的记录。不过,希望这可以作为未来构建更好工具的起点。
要求
此包专门为使用Symfony 4和PHP 7而构建,并假设您的实体由Doctrine ORM管理。
入门
要安装此包,首先通过composer将其添加到您的项目中。
$ composer require cta/search-bundle
然后确保将搜索包添加到config/bundles.php
<?php return [ // ... CTA\SearchBundle\CTASearchBundle::class => ['all' => true], ];
使实体可搜索
此包添加了三种类型注释,您可以使用这些注释标记实体:Searchable、Filterable和Sortable。Searchable标记您可以使用不区分大小写的相似操作执行全文搜索的字段,Sortable标记可以在搜索期间排序的字段,而Filterable标记可以直接过滤的字段,只返回与过滤器完全匹配的结果。联合实体也可以通过在注释中添加字段数组将其属性标记为Searchable或Sortable。
此包还包括一个内置搜索方法的存储库类。要使用此存储库,您必须将实体设置为其存储库类,或者您需要将实体的存储库类扩展为CTA\SearchBundle\Repository\SearchableRepository
类。
<?php use CTA\SearchBundle\Annotation as Search; // Import the search bundle annotations // ... /** * @ORM/Entity(repositoryClass="CTA\SearchBundle\Repository\SearchableRepository") */ class MyEntity { /** * ... * This property can be filtered or sorted * * @Search\Filterable * @Search\Sortable */ private $id; /** * ... * This property can be searched on or sorted * * @Search\Searchable * @Search\Sortable */ private $name; /** * ... * This relation can have its name and description field searched * and its name and rank field sorted * * @Search\Searchable(fields={"name", "description"}) * @Search\Sortable(fields={"name", "rank"}) */ private $myOtherEntity; // ... }
运行搜索
一旦向实体添加了注释,并将其存储库设置为CTA\SearchBundle\Repository\SearchableRepository
或扩展其的存储库。您可以使用CTA\SearchBundle\Search\SearchableManager
创建一个搜索对象发送到存储库的搜索方法。搜索需要实体的完全限定类名以获取其可搜索属性信息,以及以下搜索参数集合
- 实体的完全限定类名,例如
App\Entity\MyEntity
- 要返回的结果数量(页面大小)
- 要返回的第一个结果(偏移量)
- 搜索过滤器,以数组形式表示,其中键是属性,值是要过滤的值。例如
['id' => 3]
将只获取具有id为3的实体。默认为[]
。 - 搜索文本字符串,默认为
''
。 - 搜索排序,再次以数组形式表示,其中键是属性,值是排序方向的
ASC
或DESC
。例如['name' => 'ASC', 'myOtherEntity.rank' => 'DESC']
将首先按名称升序排序,然后按关系的rank属性降序排序。默认为[]
。
示例
<?php use CTA\SearchBundle\Search\SearchableManager; use Doctrine\ORM\EntityManagerInterface; use App\Entity\MyEntity; class Searcher { private $searchableManager; public function __construct(SearchableManager $searchableManager, EntityManagerInterface $entityManager) { $this->searchableManager = $searchableManager; $this->entityManager = $entityManager; } public function searchStuff() { // Lets search for all the entities using the text search "this is a test" where page size is 20 // and we are trying to get the third page of results and sorting on myOtherEntity rank $search = $searchableManager->createSearch(MyEntity::class, 20, 40, [], 'this is a test', ['myOtherEntity' => 'ASC']); $results = $entityManager->getRepository(MyEntity::class)->search($search); // Get the total number of unpaginated results $totalCount = $results->getTotalCount(); // Get the entities $entities = $results->getResults(); } }
操作搜索查询
可搜索的存储库的搜索方法在开始分页结果之前将触发一个事件,以便允许操作基本搜索查询。该事件是CTA\SearchBundle\Event\PrepaginationSearchEvent
,它包含由搜索方法构建的查询构建器。为了在搜索过程中触发事件,请将事件分派器作为搜索方法的第二个参数添加$entityManager->getRepository(MyEntity::class)->search($search, $symfonyEventDispatcher)
,其中$symfonyEventDispatcher
是一个遵循Symfony的EventDispatcherInterface
的类。事件的名称将基于您实体的别名(例如,将驼峰命名替换为下划线命名,例如MyEntity将变为'my_entity',Foo将变为'foo')并附加字符串_search_prepagination
(例如,MyEntity将在my_entity_search_prepagination
下触发事件)。
示例事件订阅者
<?php namespace App\Subscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use CTA\SearchBundle\Event\PrepaginationSearchEvent; class MySubscriber implements EventSubscriberInterface { public static function getSubscribedEvents() { return [ 'my_entity_' . PrepaginationSearchEvent::NAME => 'onSearchPrepagination', ]; } public function onSearchPrepagination(PrepaginationSearchEvent $event) { // Get the alias being used by the query builder for the root entity $alias = $event->getAlias(); // Get the query builder from the search $queryBuilder = $event->getQueryBuilder(); // Manipulate $queryBuilder->andWhere($alias . '.id > 100'); } }
测试
要测试该包,首先添加开发依赖项
$ composer install --dev
然后运行PHPUnit
$ ./vendor/bin/phpunit