ucs/data-extractor

UCS 数据提取组件

3.0.1 2017-10-12 19:26 UTC

README

数据提取原则

介绍

搜索是优秀网站的主要挑战之一。它可以通过不同的渠道实现,可能依赖于各种技术。例如,您可以使用带有筛选器的纯数据库搜索或Apache Solr或ElasticSearch等工具。

此外,在页面上显示项目列表与您通常必须根据非常具体的业务规则提取数据非常相似。这个过程称为数据提取,而这个组件是这个过程的基础。

数据提取的通用原则如下

  1. 构建基本查询
  2. 添加筛选器、排序和限制
  3. 执行查询
  4. 填充结果

在特定的筛选任务中可能会有例外,在某些情况下,您可能需要在查询执行后而不是执行前进行筛选。筛选数据通常通过表单收集。

筛选类型

有许多类型的筛选器

  • 文本精确/部分匹配
  • 多个/单个属性值
  • 选择
  • 范围
  • 正则表达式

此外,搜索过程可能包括或不包括相关实体,筛选器可能由逻辑表达式(AND/OR)组成。

基本上,当您有一个接受多个值的筛选器时,它们通过一个 OR 子句连接,而每个筛选器通过一个 AND 子句连接。

从一般考虑的角度来看,筛选器应该易于暴露,因为它们可以被认为是通用的且适用于任何筛选过程。它们仅依赖于显示的属性!

介绍

即使使用ORM,从数据库中提取数据也可能是一个复杂的过程。此外,有时能够使用一些用户定义的筛选器构建自定义和高效的查询可能很有用。筛选器可能很复杂且与连接的实体相关。

UCS 数据提取组件旨在简化此类筛选器的创建。此外,提取过程被标准化,以确保您的顶级代码可以(重新)用于不同的提取器(Doctrine、Propel、Solr...)。

提取数据最终是一个非常简单的过程,可以用以下几行代码总结(使用 doctrine 提取器)


<?php

// Configure the extraction process
$config = new DataExtractorConfiguration();
$config
    ->setDataClass('Acme\DemoBundle\Entity\User')
    ->setFirstResult(0) // Retrieve from the first result
    ->setMaxResults(30) // Retrieve 30 results max
    ->addFilter(new \UCS\Component\DataExtractor\Filter\LikeFilter('username', 'nicolas'))
    ->addFilter(new \UCS\Component\DataExtractor\Filter\LikeFilter('email', 'gmail'))
    ->addOrderBy(new \UCS\Component\DataExtractor\Model\OrderBy('username', 'ASC'));

// get the extractor handler form the factory
// The extractor can be a string of a registered extractor or an instance of a
// class that implements the DataExtractorInterface
$handler = $factory->createFromConfig(new \Acme\DemoComponent\Extractor\CustomExtractor, $config);
$resultSet = $handler->extract();

最终,结果集类似于分页器,包含您的结果和额外的数据库信息。通常,这个过程会导致两个查询

  1. 获取所有元素数量的计数
  2. 检索确切数量的所需元素

创建表单以显示筛选选项

大多数情况下,筛选器会呈现给您的最终用户,以便他们可以根据可用的选项相应地修改显示。UCS 数据提取组件内置了表单和机制,可让您快速准备。

表单可以配置为创建任何类型的筛选器,您只需在表单选项中提供它们的类型,以便它们可以正确渲染


<?php

// Create a form from this type within the Symfony FormFacotry
$form = $formFactory->createNamed('my_filters', 
    new \UCS\Component\DataExtractor\Form\DataExtractorConfigurationType(),
    array(
        'filterOptions' => array(
            'filters' => array(
                'foo' => array(
                    'type' => \UCS\Component\DataExtractor\Form\Filter\LikeFilterType(),
                    'filter_property' => 'foo'
                ),
                'bar' => array(
                    'type' => \UCS\Component\DataExtractor\Form\Filter\StringEqualsFilterType(),
                    'filter_property' => 'bar'
                ),
            )
        )
    ));

在过滤器表单选项中,不需要指定filter_property选项。如果没有指定,过滤器属性将被设置为表单中的过滤器名称。此选项表示对象中的最终属性路径。

例如,如果您有一个与Group实体通过多对多关系关联的User实体,您可能想要:“过滤出名称类似于'foo'的组的用户”。那么,属性路径将是:group.name,您将使用LikeFilter

创建DataExtractorType

配置您的提取器表单可能会有些过度,您可能只想做一次并(重新)在应用程序的不同位置使用您的配置。因此,UCS DataExtractor组件内置了一个系统,允许您以简单的类配置您的提取器表单。

例如,要创建上一节中展示的表单,我们将创建以下类


<?php

namespace Acme\DemoBundle\DataExtractor\Type;

/* Imports */
use UCS\Component\DataExtractor\DataExtractorTypeInterface;
use UCS\Component\DataExtractor\Form\Filter\LikeFilterType;
use UCS\Component\DataExtractor\Form\Filter\StringEqualsFilterType;

/**
 * Configure Filters and Extraction process for MyEntity
 */
class MyEntityExtractorType extends DataExtractorTypeInterface
{
    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'my_entity_extractor';
    }

    /**
     * {@inheritdoc}
     */
    public function getDataClass()
    {
        return 'Acme\DemoBundle\Entity\MyEntity';
    }

    /**
     * {@inheritdoc}
     */
    public function getExtractor()
    {
        // The return value here can be either a string or an instance
        // of a data extractor
        return 'doctrine_entity';
    }
    
    /**
     * {@inheritdoc}
     */
    public function buildExtractor(DataExtractorBuilderInterface $builder, array $options = array())
    {
        $builder->setFirstResult(0) // Retrieve from the first result
            ->setMaxResults(30) // Retrieve 30 results max
            ->addFilterType('foo', new LikeFilterType())
            ->addFilterType('bar', new StringEqualsFilterType());
    }

    /**
     * {@inheritdoc}
     */
    public function setExtractorOptions(OptionsResolver $resolver)
    {
        // Add options you want to give to DataExtractorTypeInterface::buildExtractor here
    }
}

过滤器表单类型可以在工厂中注册,并且可以像Symfony2表单一样按名称使用。

注册您的类型

UCS DataExtractor自带了一个系统,允许您注册您的类型并直接通过名称构建它们。

<?php

$registry = new \UCS\Component\DataExtractor\DataExtractorRegistry();
$factory = new \UCS\Component\DataExtractor\DataExtractorFactory($registry);

$factory->register(new \Acme\DemoBundle\DataExtractor\Type\MyEntityExtractorType);

一旦注册,您就可以从工厂获取DataExtractorHandler,并在几个步骤中提取您的实体。

<?php

$handler = $factory->create('my_entity_extractor');

// Bind the request data
$form = $handler->getForm();
$form->handleRequest($request);

// or ...
$handler->handleRequest($request);

// Finally retrieve the entities
$entities = $handler->extract();

DataExtractorHandler还提供了一个提交方法,该方法直接调用表单的提交方法。