Laravel Scout + Elasticsearch + ik 分词

平凡
2018-06-29 09:12:57
1.6k 阅读

Laravel Scout 是针对Eloquent 模型开发的一个简单的,基于驱动的全文检索系统。Scout 使用模型观察者时会自动保持你的检索索引与你的 Eloquent 记录同步。
目前,Scout 带着一个Algolia驱动;然而,扩展 Scout 并不难,你可以通过自定义驱动来自由的扩展 Scout。接下来我们就自定义搜索引擎elasticsearch来扩展Scount。
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。

安装elasticsearch

参考 CentOS 7.x 安装 Elasticsearch 7.x

安装Scout

1、 首先,使用 composer 包管理器来安装 Scout

composer require laravel/scout

2、Laravel5.5 之前的版本需要将 ScoutServiceProvider 添加到你的 config/app.php 配置文件的 providers 数组中

 'providers' => [
	 ...
	 Laravel\Scout\ScoutServiceProvider::class,
 ],

3、生成配置文件

php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"

4、安装scout的es驱动

composer require tamayo/laravel-scout-elastic

5、修改config\scout.php配置文件,将驱动修改为elasticsearch

'driver' => env('SCOUT_DRIVER', 'elasticsearch'),
'elasticsearch' => [
       'index' => env('ELASTICSEARCH_INDEX', 'blog'),
       'hosts' => [
         env('ELASTICSEARCH_HOST', 'http://127.0.0.1:9200'),
       ],
],

6、修改文章Model app/Models/Article.php

 use Searchable;

 // 定义索引里面的type
 public function searchableAs()
 {
 	 return 'articles';
 }

 // 定义有哪些字段需要搜索
 public function toSearchableArray()
 {
	  return [
		 'title' => $this->title,
		 'content' => $this->content,
	  ];
 }

创建command命令

1、安装guzzlehttp/guzzle 扩展

composer require guzzlehttp/guzzle

2、创建command命令

php artisan make:command ESInit

3、执行完命令后会创建app\Console\Command\ESInit.php文件,修改ESInit.php

 <?php

 namespace App\Console\Commands;

 use GuzzleHttp\Client;
 use Illuminate\Console\Command;

 class ESInit extends Command
 {
     /**
      * The name and signature of the console command.
      *
      * @var string
      */
     protected $signature = 'es:init';

     /**
      * The console command description.
      *
      * @var string
      */
     protected $description = 'init laravel es for article';

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

     /**
      * Execute the console command.
      *
      * @return mixed
      */
     public function handle(Client $client)
     {
         $this->createTemplate($client);
         $this->createIndex($client);
     }

     /**
      * 创建模板 see https://www.elastic.co/guide/en/elasticsearch/reference/current/dynamic-templates.html
      * @param Client $client
      */
     private function createTemplate(Client $client)
     {
         $url = config('scout.elasticsearch.hosts')[0] . '/_template/template_1';
         $client->put($url, [
             'json' => [
                 'template' => config('scout.elasticsearch.index'),
                 'settings' => [
                     'number_of_shards' => 1,
                 ],
                 'mappings' => [
                     '_default_' => [
                         'dynamic_templates' => [ // 动态映射模板
                             [
                                 'string_fields' => [ // 字段映射模板的名称,一般为"类型_fields"的命名方式
                                     'match' => '*', // 匹配的字段名为所有
                                     'match_mapping_type' => 'string', // 限制匹配的字段类型,只能是 string 类型
                                     'mapping' => [ // 字段的处理方式
                                         'type' => 'text', // 字段类型限定为 string
                                         'analyzer' => 'ik_smart', // 字段采用的分析器名,默认值为 standard 分析器
                                         'fields' => [
                                             'raw' => [
                                                 'type' => 'keyword',
                                                 'ignore_above' => 256, // 字段是索引时忽略长度超过定义值的字段。
                                             ]
                                         ],
                                     ],
                                 ],
                             ],
                         ],
                     ],
                 ],
             ],
         ]);

         $this->info("=======创建模板成功=======");
     }

     private function createIndex(Client $client)
     {
         $url = config('scout.elasticsearch.hosts')[0] . '/' . config('scout.elasticsearch.index');

         $client->put($url, [
             'json' => [
                 'settings' => [
                     'refresh_interval' => '5s',
                     'number_of_shards' => 1, // 分片为
                     'number_of_replicas' => 0, // 副本数
                 ],
                 'mappings' => [
                     '_default_' => [
                         '_all' => [
                             'enabled' => false, // 是否开启所有字段的检索
                         ],
                     ],
                 ],
             ],
         ]);

         $this->info("=========创建索引成功=========");
     }
 }

4、使用php artisan执行该命令初始化Elasticsearch项目

php artisan es:init

5、验证是否执行成功

curl localhost:9200/blog
curl localhost:9200/_template/template_1

导入数据

1、使用php artisan命令导入数据

php artisan scout:import "App\Models\Article"

2、查看是否导入成功

curl localhost:9200/blog/articles/_search
2
1 评论
  • comment-avatar

    执行php artisan es:init的时候报错:

    GuzzleHttp\Exception\ClientException  : Client error: `PUT http://elasticsearch:9200/_template/template_1` resulted in a `400 Bad Request` response:
    {"error":{"root_cause":[{"type":"mapper_parsing_exception","reason":"Root mapping definition has unsupported parameters: (truncated...)
    

    请问这个怎么解决呢

    • 回复
    comment-avatar

    analysis-ik 插件安装了吗?

    • 回复
    comment-avatar

    新版本的ES报这个错,也安装了ik

    • 回复
    comment-avatar

    ik 需要安装对应版本的哦,不然会失败的。我服务器现在用的是 7.2.0,没有出现这个问题。

    • 回复