joacub/elastic-search

一个帮助集成 elastic search 的模块

0.0.2 2013-09-18 16:23 UTC

README

Build Status Scrutinizer Quality Score Code Coverage

这是一个相当简单的模块,可以帮助您确保您的 elastic search 索引与数据库保持同步。

您希望...

  • 您希望有一个用于更新/删除映射的工具
  • 您希望保持 elastic search 与 ORM 保持同步
  • 您希望有一个服务,提供简单的接口来搜索和返回 doctrine 实体

步骤 1,设置映射

首先,将文件 config/MCNElasticSearch.global.php 复制到您的 config/autoload/ 目录。类型数组是一个关联数组,名称 => 映射信息。对于映射中的所有选项,请检查 MCNElasticSearch\Options\TypeMappingOptions。目前仅提供基本选项,但欢迎提交 PR!

示例配置

return [
    'MCNElasticSearch' => [
        'metadata' => [

            /**
             * List of object mappings
             */
            'objects' => [
                'Company\Entity\CompanyEntity' => [
                    'hydrator' => 'company',
                    'type'     => 'companies',
                    'index'    => 'example',
                ]
            ],

            /**
             * List of types E.g "SQL Tables"
             */
            'types' => [
                'companies' => [
                    'index'      => 'example',
                    'source'     => ['enabled' => false],
                    'properties' => [
                        'id'      => ['type' => 'integer'],
                        'name'    => ['type' => 'string'],
                        'address' => [
                            'type'       => 'object',
                            'properties' => [

                                'id'   => ['type' => 'integer'],
                                'type' => ['type' => 'string', 'not_analyzed' => true],

                                'street'         => ['type' => 'string'],
                                'zipcode'        => ['type' => 'integer'],
                                'country'        => ['type' => 'string'],
                                'coordinates'    => ['type' => 'geo_point'],
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
];

现在,您已经设置了映射,我们需要将其运行在我们的 elastic search 上 php public/index.php es mapping create。如果您想删除它,请使用 php public/index.php es mapping delete

步骤 2,设置同步器

现在我们需要实现同步器,这是非常简单的!

class ElasticSearchSynchronizer extends \MCNElasticSearch\Listener\AbstractDoctrineORMSynchronizer
{
    /**
     * Check that an object is of the proper instance
     *
     * @param mixed $object
     *
     * @return bool
     */
    public function isValid($object)
    {
        return $object instanceof CompanyEntity;
    }
}

您还需要设置一个工厂,并传递 MCNElasticSearch\Service\DocumentService 的实例,但希望将来可以移除这一点!

现在我们需要告诉 doctrine 将事件发布到您的同步器。因此,在您的 doctrine 配置中,您需要添加:

    'eventmanager' => [
        'orm_default' => [
            'subscribers' => [
                ElasticSearchSynchronizer::class
            ]
        ]
    ],

步骤 3,执行搜索

现在我将继续上一个示例,并从我的使用 PhlyRestfully 编写的 API 中取一段代码,对公司的类型进行搜索,按距离排序,并过滤掉所有超过 1000km 的公司。

class CompanyResource implements ListenerAggregateInterface
{
    use ListenerAggregateTrait;

    /**
     * @var \Company\Service\CompanyServiceInterface
     */
    protected $companyService;

    /**
     * @var \MCNElasticSearch\Service\SearchServiceInterface
     */
    protected $searchService;

    /**
     * @param CompanyServiceInterface $companyService
     * @param SearchServiceInterface $searchService
     */
    public function __construct(CompanyServiceInterface $companyService, SearchServiceInterface $searchService)
    {
        $this->searchService  = $searchService;
        $this->companyService = $companyService;
    }

    /**
     * Attach one or more listeners
     *
     * Implementors may add an optional $priority argument; the EventManager
     * implementation will pass this to the aggregate.
     *
     * @param EventManagerInterface $events
     *
     * @return void
     */
    public function attach(EventManagerInterface $events)
    {
        $this->listeners[] = $events->attach('fetchAll', [$this, 'fetchAll']);
    }

    /**
     * @param ResourceEvent $event
     * @return \PhlyRestfully\ApiProblem|\Zend\Paginator\Paginator
     */
    public function fetchAll(ResourceEvent $event)
    {
        $coordinates =       $event->getQueryParam('coordinates');
        $maxDistance = (int) $event->getQueryParam('distance', 1000);

        $sort = [
            '_geo_distance' => [
                'companies.address.coordinates' => $coordinates,
                'unit'  => 'km',
                'order' => 'asc'
            ]
        ];

        $geoDistanceFilter = new GeoDistance('companies.address.coordinates', $coordinates, $maxDistance . 'km');

        $query = new Query();
        $query->addSort($sort);
        $query->setFilter($geoDistanceFilter);

        return $this->searchService->search(CompanyEntity::class, $query, SearchServiceInterface::HYDRATE_DOCTRINE_OBJECT);
    }
}

步骤 4,哈利路亚时刻

盈利!