doopcompany/doop-elasticsearch-bundle

用于在 Sulu 中允许使用具有映射属性的具体 Elasticsearch 索引的小型包

1.0.0 2022-05-16 11:52 UTC

This package is auto-updated.

Last update: 2024-09-16 16:29:02 UTC


README

用于在 Sulu 中允许使用具有映射属性的具体 Elasticsearch 索引的小型包

安装

使用 composer 安装包

$ composer require doopcompany/doop-elasticsearch-bundle

config/bundles.php 中注册插件

<?php

return [
    // ...
    Doop\ElasticsearchBundle\DoopElasticsearchBundle::class => ['all' => true],
];

配置

在您的 config/packages 目录中添加一个 doop_elasticsearch.yaml 文件

# EXAMPLE:
doop_elasticsearch:
  indices:
      my_index:
        body:
          settings:
            number_of_shards: 2
            number_of_replicas: 1
          mappings:
            properties:
              date:
                type: date
              geo_point:
                type: geo_point

这将允许包默认创建一个具有一些映射属性的索引。这些将自动使用 MassiveSearchBundle 上的钩子创建。可以通过向您的 doop_elasticsearch 配置中添加以下内容来禁用此行为

doop_elasticsearch:
  massive_search_hooks_enabled: false

索引文档

由于 massive search 包不允许您自己配置索引和映射,因此引入了此包。您仍然可以使用 massive search 触发的事件在自定义索引中索引文档。例如,使用事件订阅者

<?php

namespace App\EventListener;

use Elasticsearch\Client;
use Elasticsearch\Common\Exceptions\Missing404Exception;
use Massive\Bundle\SearchBundle\Search\Event\PreDeindexEvent;
use Massive\Bundle\SearchBundle\Search\Event\PreIndexEvent;
use Massive\Bundle\SearchBundle\Search\SearchEvents;
use Sulu\Bundle\ArticleBundle\Document\ArticleDocument;
use Sulu\Bundle\SearchBundle\Search\Document;
use Sulu\Component\DocumentManager\DocumentManagerInterface;
use Sulu\Component\DocumentManager\Exception\DocumentManagerException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class MyArticleMassiveSearchSubscriber implements EventSubscriberInterface
{
    private DocumentManagerInterface $documentManager;
    private Client $client;

    public function __construct(
        DocumentManagerInterface $documentManager,
        Client $client
    ) {
        $this->documentManager = $documentManager;
        $this->client = $client;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            SearchEvents::PRE_INDEX => 'onPreIndex',
            SearchEvents::PRE_DEINDEX => 'onPreDeIndex',
        ];
    }

    public function onPreDeIndex(PreDeindexEvent $event)
    {
        /** @var Document $document */
        $document = $event->getDocument();
        if (ArticleDocument::class !== $document->getClass() || 'my_article' !== $document->getField('_structure_type')->getValue()) {
            return;
        }
        try {
            $this->client->delete([
                'index' => 'my_index',
                'id' => $document->getId(),
            ]);
        } catch (Missing404Exception) {
        }
    }

    /**
     * @throws DocumentManagerException
     */
    public function onPreIndex(PreIndexEvent $event)
    {
        /** @var Document $document */
        $document = $event->getDocument();
        if (ArticleDocument::class !== $document->getClass() || 'my_article' !== $document->getField('_structure_type')->getValue()) {
            return;
        }

        /** @var ArticleDocument $article */
        $article = $this->documentManager->find($document->getId());
        $structure = $article->getStructure()->toArray();
        $extensions = $article->getExtensionsData()->toArray();

        $this->client->index([
            'index' => 'my_index',
            'id' => $document->getId(),
            'body' => [
                'id' => $document->getId(),
                'title' => $structure['title'],
                'date' => $structure['date'] ?? null,
                'geo_point' => $structure['geo_point'] ?? null,
                'route_path' => $structure['routePath'],
                'description' => $extensions['excerpt']['description'],
                'excerpt' => [
                    'categories' => $this->formatCategories($extensions['excerpt']['categories']),
                ],
            ],
        ]);
    }

    private function formatCategories(array $categoryIds): array
    {
        $formatted = [];

        foreach ($categoryIds as $categoryId) {
            $formatted[] = ['id' => $categoryId];
        }

        return $formatted;
    }
}

最后,您可以使用原生 Elasticsearch 查询搜索索引。