Home > PHP Framework > Laravel > body text

Easily integrate the new version of Elasticsearch7.9 Chinese search to Laravel7 project

藏色散人
Release: 2022-05-13 11:50:30
forward
3561 people have browsed it

The following tutorial column of Laravel will introduce to you how to easily integrate the new version of Elasticsearch7.9 Chinese search into the Laravel7 project. I hope it will be helpful to friends in need!


ar414 5分钟 集成新版 Elasticsearch7.9 中文搜索 到你的 Laravel7 项目

Only five steps:

#1. Start the integrated ik Chinese word segmentation plug-in Elasticsearch7.9 Docker Image

##Course Recommendation→:"Elasticsearch Full Text Search Practical Combat" (Practical Video)

From the course

"Ten million-level data concurrency solution (theoretical practice)"

2, Laravel7 configuration Scout

3, configure Model model

4, Import data

5. Search

Demo address

ar414 5分钟 集成新版 Elasticsearch7.9 中文搜索 到你的 Laravel7 项目

www.ar414. com/search?query=php�%...

Search scope

    Article content
  • Title
  • Tags
Result weight

    Number of keywords appearing
  1. Number of keywords appearing
Search page

    High Highlight display
  • Word segmentation display
  • Result paging

##Foreword

Mainly because I just want to make a blog Search and organize it into articles by the way

Laravel Elasticsearch Many seniors have written tutorials and cases, but with the upgrade of Elasticsearch and laravel versions, many of the previous articles are not applicable to the new version. It is recommended that everyone use For any open source project, you should go through the documentation, mainly the version documentation currently in use, supplemented by tutorials

Elasticsearch 7.9
  • Laravel 7
  • elasticsearch-analysis-ik v7.9

Reference

ik Chinese word segmentation plug-in
  • elasticsearch official document

Use integrated ik Chinese word segmentation plug-in Elasticsearch

Pull docker
$ docker pull ar414/elasticsearch-7.9-ik-plugin
Copy after login

Create log And the data storage directory

is mapped locally into the docker container to prevent data loss when docker restarts

$ mkdir -p /data/elasticsearch/data
$ mkdir -p /data/elasticsearch/log
$ chmod -R 777 /data/elasticsearch/data
$ chmod -R 777 /data/elasticsearch/log
Copy after login

Run
docker run -d -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -v /data/elasticsearch/data:/var/lib/elasticsearch -v /data/elasticsearch/log:/var/log/elasticsearch ar414/elasticsearch-7.9-ik-plugin
Copy after login

Verification
$ curl http://localhost:9200{
  "name" : "01ac21393985",  "cluster_name" : "docker-cluster",  "cluster_uuid" : "h8L336qcRb2i1aydOv04Og",  "version" : {
    "number" : "7.9.0",    "build_flavor" : "default",    "build_type" : "docker",    "build_hash" : "a479a2a7fce0389512d6a9361301708b92dff667",    "build_date" : "2020-08-11T21:36:48.204330Z",    "build_snapshot" : false,    "lucene_version" : "8.6.0",    "minimum_wire_compatibility_version" : "6.8.0",    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },  "tagline" : "You Know, for Search"}
Copy after login

Test Chinese word segmentation
curl -X POST "http://localhost:9200/_analyze?pretty" -H 'Content-Type: application/json' -d'
{
  "analyzer": "ik_max_word",
  "text":     "laravel天下无敌"
}
'{
  "tokens" : [
    {
      "token" : "laravel",      "start_offset" : 0,      "end_offset" : 7,      "type" : "ENGLISH",      "position" : 0    },    {
      "token" : "天下无敌",      "start_offset" : 7,      "end_offset" : 11,      "type" : "CN_WORD",      "position" : 1    },    {
      "token" : "天下",      "start_offset" : 7,      "end_offset" : 9,      "type" : "CN_WORD",      "position" : 2    },    {
      "token" : "无敌",      "start_offset" : 9,      "end_offset" : 11,      "type" : "CN_WORD",      "position" : 3    }
  ]}
Copy after login

Using Elasticsearch in Laravel project

Easily integrate the new version of Elasticsearch7.9 Chinese search to Laravel7 projectElasticsearch
The official SDK is provided. In the Laravel project, you can connect to Elasticsearch more elegantly. Laravel itself provides a Scout full-text search solution. We only need to change the default The Algolia driver is replaced with ElasticSearch driver.

Installation

laravel/scout
  • Easily integrate the new version of Elasticsearch7.9 Chinese search to Laravel7 project
    $ composer require laravel/scout
    $ composer require Easily integrate the new version of Elasticsearch7.9 Chinese search to Laravel7 project
    Copy after login

Configuration

    Generate Scout configuration file (config/scout.php)
  1. $ php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"Copied File [\vendor\laravel\scout\config\scout.php] To [\config\scout.php]Publishing complete.
    Copy after login

  2. Specify Scout driver
First type: Specify (recommended)
SCOUT_DRIVER=Matchish\ScoutElasticSearch\Engines\ElasticSearchEngine
Copy after login
in the
    .env
  • fileSecond type: Specify in
  • config/scout.php
  • Directly modify the default driver
    'driver' => env('SCOUT_DRIVER', 'algolia')改为'driver' => env('SCOUT_DRIVER', 'Matchish\ScoutElasticSearch\Engines\ElasticSearchEngine')
    Copy after login
    Specify the Elasticsearch service IP port
  1. If you use docker deployment, use the IP of
    docker0

    , Linux checks through ifconfig

    Configure in
    .env

    <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">ELASTICSEARCH_HOST=172.17.0.1:9200</pre><div class="contentsignin">Copy after login</div></div>

  2. Registration service
  3. config/app.php
    <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">'providers' =&gt; [  // Other Service Providers  \Matchish\ScoutElasticSearch\ElasticSearchServiceProvider::class],</pre><div class="contentsignin">Copy after login</div></div>

  4. Clear configuration cache
  5. $ php artisan config:clear
    Copy after login

  6. Laravel has been connected to Elasticsearch

实际业务中使用

需求

14分钟14秒 集成 Elasticsearch中文搜索 到你的 Laravel 项目

通过博客右上角的搜索框可以搜索到与关键词相关的文章,从以下几点匹配

  • 文章内容
  • 文章标题
  • 文章标签

涉及到2张 Mysql表 以及字段

  • article
    • title
    • tags
  • article_content
    • content

为文章配置 Elasticsearch 索引

  1. 创建索引配置文件(config/elasticsearch.php)

    $ touch config/elasticsearch.php
    Copy after login
  2. elasticsearch.php 配置字段映射

    <?phpreturn  [
     &#39;indices&#39; => [
         'mappings' => [
             'blog-articles' => [
                 "properties"=>  [
                     "content"=>  [
                         "type"=>  "text",
                         "analyzer"=>  "ik_max_word",
                         "search_analyzer"=>  "ik_smart"
                     ],
                     "tags"=>  [
                         "type"=>  "text",
                         "analyzer"=>  "ik_max_word",
                         "search_analyzer"=>  "ik_smart"
                     ],
                     "title"=>  [
                         "type"=>  "text",
                         "analyzer"=>  "ik_max_word",
                         "search_analyzer"=>  "ik_smart"
                     ]
                 ]
             ]
         ]
     ],];
    Copy after login
  • analyzer:字段文本的分词器
    • search_analyzer:搜索词的分词器
    • 根据具体业务场景选择(颗粒小占用资源多,一般场景analyzer使用ik_max_word,search_analyzer使用ik_smart):
      • ik_max_word:ik中文分词插件提供,对文本进行最大数量分词
        laravel天下无敌 -> laravel天下无敌,天下,无敌
      • ik_smart: ik中文分词插件提供,对文本进行最小数量分词
        laravel天下无敌 -> laravel天下无敌

配置文章模型

建议先看一遍 Laravel Scout 使用文档

  1. 引入Laravel Scout

     namespace App\Models\Blog;
    
     use Laravel\Scout\Searchable;
    
     class Article extends BlogBaseModel
     {
         use Searchable;
     }
    Copy after login
  2. 指定索引(刚刚配置文件中的elasticsearch.indices.mappings.blog-articles)

     /**
      * 指定索引
      * @return string
      */
     public function searchableAs()
     {
         return 'blog-articles';
     }
    Copy after login
  3. 设置导入索引的数据字段

     /**
      * 设置导入索引的数据字段
      * @return array
      */
     public function toSearchableArray()
     {
         return [
             'content' => ArticleContent::query()
                 ->where('article_id',$this->id)
                 ->value('content'),
             'tags'    => implode(',',$this->tags),
             'title'   => $this->title
         ];
     }
    Copy after login
  4. 指定 搜索索引中存储的唯一ID

     /**
      * 指定 搜索索引中存储的唯一ID
      * @return mixed
      */
     public function getScoutKey()
     {
         return $this->id;
     }
    
     /**
      * 指定 搜索索引中存储的唯一ID的键名
      * @return string
      */
     public function getScoutKeyName()
     {
         return 'id';
     }
    Copy after login

数据导入

其实是将数据表中的数据通过Elasticsearch导入到Lucene
Elasticsearch 是 Lucene 的封装,提供了 REST API 的操作接口

  • 一键自动导入: php artisan scout:import
  • 导入指定模型: php artisan scout:import ${model}
$ php artisan scout:import "App\Models\Blog\Article"Importing [App\Models\Blog\Article]Switching to the new index
5/5 [⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬⚬] 100%[OK] All [App\Models\Blog\Article] records have been imported.
Copy after login

导入失败,常见原因:

  • Unresolvable dependency resolving [Parameter #0 [  integer $retries ]] in class Elasticsearch\Transport
    • 解决: 修改配置后,没有清除配置缓存
  • invalid_index_name_exception
    • 解决: searchableAs配置错误,为索引创建别名后,指定别名

检查索引是否正确

$ curl -XGET http://localhost:9200/blog-articles/_mapping?pretty{
  "blog-articles_1598362919" : {
    "mappings" : {
      "properties" : {
        "__class_name" : {
          "type" : "text",          "fields" : {
            "keyword" : {
              "type" : "keyword",              "ignore_above" : 256            }
          }
        },        "content" : {
          "type" : "text",          "analyzer" : "ik_max_word",          "search_analyzer" : "ik_smart"
        },        "tags" : {
          "type" : "text",          "analyzer" : "ik_max_word",          "search_analyzer" : "ik_smart"
        },        "title" : {
          "type" : "text",          "analyzer" : "ik_max_word",          "search_analyzer" : "ik_smart"
        }
      }
    }
  }}
Copy after login

测试

  1. 创建一个测试命令行

    $ php artisan make:command ElasticTest
    Copy after login
  2. 代码

<?phpnamespace  App\Console\Commands;use App\Models\Blog\Article;use App\Models\Blog\ArticleContent;use Illuminate\Console\Command;use Illuminate\Support\Carbon;class ElasticTest extends Command{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = &#39;elasticsearch {query}&#39;;

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = &#39;elasticsearch test&#39;;

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

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        //
        $startTime = Carbon::now()->getPreciseTimestamp(3);
        $articles = Article::search($this->argument('query'))->get()->toArray();
        $userTime = Carbon::now()->getPreciseTimestamp(3) - $startTime;
        echo "耗时(毫秒):{$userTime} \n";

        //content在另外一张表中,方便观察测试 这里输出
        if(!empty($articles)) {
            foreach($articles as &$article) {
                $article = ArticleContent::query()->where('article_id',$article['id'])->value('content');
            }
        }

        var_dump($articles);

    }}
Copy after login
  1. 测试
    $ php artisan elasticsearch 周杰伦
    Copy after login

ar414 5分钟 集成新版 Elasticsearch7.9 中文搜索 到你的 Laravel7 项目

  1. 复杂查询
    例如:自定义高亮显示
    //ONGR\ElasticsearchDSL\Highlight\Highlight ArticleModel::search($query,function($client,$body) {
             $higlight = new Highlight();
             $higlight->addField('content',['type' => 'plain']);
             $higlight->addField('title');
             $higlight->addField('tags');
             $body->addHighlight($higlight);
             $body->setSource(['title','tags']);
             return $client->search(['index' => (new ArticleModel())->searchableAs(), 'body' => $body->toArray()]);
         })->raw();
    Copy after login

复杂自定义查询回调中的$client和$body,可根据这两个包进行灵活操作

$client 官方 elasticsearch/elasticsearch package(https://packagist.org/packages/elasticsearch/elasticsearch)

$body ongr/elasticsearch-dsl package(https://packagist.org/packages/ongr/elasticsearch-dsl)

The above is the detailed content of Easily integrate the new version of Elasticsearch7.9 Chinese search to Laravel7 project. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:learnku.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template