cta-k12/search-bundle

提供了一种快速将搜索、排序和过滤功能添加到Doctrine ORM实体中的方法

安装: 45

依赖者: 0

建议者: 0

安全性: 0

星标: 0

关注者: 3

分支: 0

开放问题: 4

类型:symfony-bundle

v1.0.4 2019-05-02 17:49 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创建一个搜索对象发送到存储库的搜索方法。搜索需要实体的完全限定类名以获取其可搜索属性信息,以及以下搜索参数集合

  1. 实体的完全限定类名,例如 App\Entity\MyEntity
  2. 要返回的结果数量(页面大小)
  3. 要返回的第一个结果(偏移量)
  4. 搜索过滤器,以数组形式表示,其中键是属性,值是要过滤的值。例如 ['id' => 3] 将只获取具有id为3的实体。默认为 []
  5. 搜索文本字符串,默认为 ''
  6. 搜索排序,再次以数组形式表示,其中键是属性,值是排序方向的ASCDESC。例如 ['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