Laravel + Elasticsearch реализует китайский поиск

Elasticsearch Laravel

Elasticsearch

Elasticsearch — это поисковая система с открытым исходным кодом, основанная на Apache Lucene™. Независимо от того, является ли она открытой или проприетарной, Lucene можно считать самой передовой, наиболее эффективной и функциональной библиотекой поисковой системы на сегодняшний день.

Однако Lucene — это всего лишь библиотека. Чтобы использовать его возможности, вам нужно использовать Java и интегрировать его в свое приложение. Lucene очень сложен, и вам нужно глубоко понимать поиск, чтобы понять, как он работает.

Elasticsearch также написан на Java и использует Lucene для функций индексирования и поиска, но его цель — упростить полнотекстовый поиск и скрыть сложность Lucene с помощью простого и согласованного API RESTful.

Однако Elasticsearch — это больше, чем просто Lucene и система полнотекстового поиска, она также предоставляет:

  • Распределенное хранилище файлов в реальном времени, каждое поле индексируется и доступно для поиска
  • Распределенная поисковая система для анализа в реальном времени
  • Масштабируемость до сотен серверов, обработка петабайт структурированных или неструктурированных данных

И все эти функции интегрированы в единый сервер, с которым ваше приложение может взаимодействовать с помощью простых API-интерфейсов RESTful, клиентов на разных языках и даже командной строки. Начать работу с Elasticsearch очень просто, он предоставляет множество разумных значений по умолчанию и скрывает сложную теорию поисковых систем от новичков. Он работает «из коробки» (установка готова к использованию) и может использоваться в производственной среде с минимальным обучением.

Elasticsearch распространяется под лицензией Apache 2, и его можно бесплатно загружать, использовать и изменять.

Установка ElasticSearch

ElasticSearch уже интегрирован в Laradock. Мы можем напрямую использовать:

docker-compose up -d elasticsearch

Если вам нужно установить плагин, выполните команду:

docker-compose exec elasticsearch /usr/share/elasticsearch/bin/elasticsearch-plugin install {plugin-name}

// 重启容器
docker-compose restart elasticsearch

Примечание:

  • The vm.max_map_count kernel setting must be set to at least 262144 for production use.

Поскольку я нахожусь в среде Centos 7, я устанавливаю его прямо в настройках системы:sysctl -w vm.max_map_count=262144

  • Имя пользователя и пароль по умолчанию: "elastic", "changeme", номер порта: 9200.

ElasticHQ

ElasticHQ is an open source application that offers a simplified interface for managing and monitoring Elasticsearch clusters.

Management and Monitoring for Elasticsearch.

www.elastichq.org/

  • Real-Time Monitoring
  • Full Cluster Management
  • Full Cluster Monitoring
  • Elasticsearch Version Agnostic
  • Easy Install - Always On
  • Works with X-Pack

Войдите в наш хост Elasticsearch, чтобы войти в фон.

По умолчанию он создает:

Кластер кластера: ларадок-кластер Узел узла: laradock-node Индекс индекса: .elastichq

Установка ИК токенизатора

ElasticSearch в основном используется для поиска статей в собственном блоге или официальном аккаунте, поэтому вам нужно выбрать китайский токенизатор для совместного использования.Здесь мы просто рекомендуем использовать токенизатор IK.Приступим к установке плагина, соответствующего версии ElasticSearch ( 7.5.1):

GitHub.com/many out/E последний…

// 安装插件
docker-compose exec elasticsearch /usr/share/elasticsearch/bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.5.1/elasticsearch-analysis-ik-7.5.1.zip

Примечание. Вы можете сначала загрузить zip-файл, а затем установить его, скорость будет выше.

Проверить эффект сегментации слов

Согласно тесту Elasticsearch API, эффект сегментации слов достиг:

 ~ curl -X POST "http://your_host/_analyze?pretty" -H 'Content-Type: application/json' -d'
{
  "analyzer": "ik_max_word",
  "text":     "我是中国人"
}
'

{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "是",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "中国人",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "中国",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "国人",
      "start_offset" : 3,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 4
    }
  ]
}

Объедините с Laravel

Хотя Elasticsearch официально предоставляет соответствующую PHP-версию подключаемого модуля, мы все же надеемся на более тесную интеграцию с Laravel, поэтому здесь мы решили использовать его в сочетании со Scout.tamayo/laravel-scout-elasticплагин.

composer require tamayo/laravel-scout-elastic
 
composer require laravel/scout
 
php artisan vendor:publish

выберите:Laravel\Scout\ScoutServiceProvider

Измените драйвер наelasticsearch:

'driver' => env('SCOUT_DRIVER', 'elasticsearch'),

создать индекс

Существует несколько способов создания индекса, один из которых можно создать непосредственно с помощью инструмента визуализации Ela ElasticHQ.

Далее нам нужно обновить этот индекс, дополнить раздел Mappings, можно использовать Postman.

Другой способ — использовать функциональность командной строки Artisan, которая поставляется с Laravel.

Здесь мы рекомендуем использовать командную строку Artisan.

php artisan make:command ESOpenCommand

Согласно официальному сайту, мы можемESOpenCommandОтправьте запрос PUT на сервер Elasticsearch.Здесь с помощью подключаемого модуля PHP, предоставленного Elasticsearch, мы используемtamayo/laravel-scout-elasticКогда вы добавляете плагин, плагин Elasticsearch PHP уже установлен:

Теперь мы можем использовать плагин для создания нашего индекса и непосредственно смотреть на код:

    public function handle()
    {
    $host = config('scout.elasticsearch.hosts');
    $index = config('scout.elasticsearch.index');
    $client = ClientBuilder::create()->setHosts($host)->build();

    if ($client->indices()->exists(['index' => $index])) {
        $this->warn("Index {$index} exists, deleting...");
        $client->indices()->delete(['index' => $index]);
    }

    $this->info("Creating index: {$index}");

    return $client->indices()->create([
        'index' => $index,
        'body' => [
            'settings' => [
                'number_of_shards' => 1,
                'number_of_replicas' => 0
            ],
            'mappings' => [
                '_source' => [
                    'enabled' => true
                ],
                'properties' => [
                    'id' => [
                        'type' => 'long'
                    ],
                    'title' => [
                        'type' => 'text',
                        'analyzer' => 'ik_max_word',
                        'search_analyzer' => 'ik_smart'
                    ],
                    'subtitle' => [
                        'type' => 'text',
                        'analyzer' => 'ik_max_word',
                        'search_analyzer' => 'ik_smart'
                    ],
                    'content' => [
                        'type' => 'text',
                        'analyzer' => 'ik_max_word',
                        'search_analyzer' => 'ik_smart'
                    ]
                ],
            ]
        ]
    ]);
}

Что ж, запускаем Kibana и видим, что мы создали Index:

Примечание. Локальная установка Kibana Docker:

Дальнейшие действия будут сосредоточены на том, как использовать Kibana.

docker run -d --name kibana -e ELASTICSEARCH_HOSTS=http://elasticsearch_host -p 5601:5601 -e SERVER_NAME=ki.test kibana:7.5.2

Чтобы проверить, доступен ли индекс, вы можете вставить часть данных, чтобы увидеть:

curl -XPOST your_host/coding01_open/_create/1 -H 'Content-Type:application/json' -d'
{"content":"中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"}

Вы можете просмотреть соответствующие данные через браузер:

Следующим шагом с Index является объединение Laravel для импорта, обновления, запроса и других операций.

Использование модели Laravel

Фреймворк Laravel порекомендовал нам использовать полнотекстовый поиск Scout.Нам нужно только добавить официальный контент в Модель статьи.Это очень просто.Рекомендуется ознакомиться с документацией Scout:Learncool.com/docs/Лара В.Е.…, непосредственно следующий код:

<?php

namespace App;

use App\Tools\Markdowner;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Laravel\Scout\Searchable;

class Article extends Model
{
    use Searchable;

    protected $connection = 'blog';
    protected $table = 'articles';
    use SoftDeletes;

    /**
     * The attributes that should be mutated to dates.
     *
     * @var array
     */
    protected $dates = ['published_at', 'created_at', 'deleted_at'];

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'user_id',
        'last_user_id',
        'category_id',
        'title',
        'subtitle',
        'slug',
        'page_image',
        'content',
        'meta_description',
        'is_draft',
        'is_original',
        'published_at',
        'wechat_url',
    ];

    protected $casts = [
        'content' => 'array'
    ];

    /**
     * Set the content attribute.
     *
     * @param $value
     */
    public function setContentAttribute($value)
    {
        $data = [
            'raw'  => $value,
            'html' => (new Markdowner)->convertMarkdownToHtml($value)
        ];

        $this->attributes['content'] = json_encode($data);
    }

    /**
     * 获取模型的可搜索数据
     *
     * @return array
     */
    public function toSearchableArray()
    {
        $data = [
            'id' => $this->id,
            'title' => $this->title,
            'subtitle' => $this->subtitle,
            'content' => $this->content['html']
        ];

        return $data;
    }

    public function searchableAs()
    {
        return '_doc';
    }
}

Scout предоставляет команду Artisan import для импорта всех существующих записей в поисковый индекс.

php artisan scout:import "App\Article"

Глядя на Kibana, было сохранено 12 записей, что соответствует количеству записей в базе данных.

С данными мы можем проверить, можем ли мы запросить данные.

Все так же, создайте команду:

class ElasearchCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:search {query}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $article = Article::search($this->argument('query'))->first();
        $this->info($article->title);
    }
}

Это мои заголовки, я просто ввожу ключевое слово: «список», чтобы посмотреть, смогу ли я его найти.

Суммировать

Выполнено в целом:

  1. установка эластичного поиска;
  2. Установка плагина Elasticsearch IK tokenizer;
  3. инструменты визуализации Elasticsearch и простота установки и использования Kibana ElasticHQ;
  4. использование Скаута;
  5. Используйте Elasticsearch со Scout.

Следующим шагом будет хранение большего количества контента в Elasticsearch для обеспечения полнотекстового поиска по вашему блогу, официальной учетной записи, автоматического поиска и других сценариев.

Ссылаться на