laravel下elasticsearch+analysis-ik实现中文全文搜索

这篇文章需要建立在 elasticsearch 已经配置完成的前提下;
如果还没安装 elasticsearch ;
请先出门左转 elasticsearch和analysis-ik的安装使用;

新建一个项目演示;

laravel new elasticsearch

创建一个文章表和文章模型;

php artisan make:model Models/Article -m

添加文章标题和内容字段
/database/migrations/2018_06_03_080124_create_articles_table.php

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title')->default('')->comment('标题');
            $table->mediumText('content')->comment('文章内容');
            $table->timestamps();
        });
    }

修改 .env 数据库配置项;

DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret

运行迁移生成表;

php artisan migrate

创建填充文件;

php artisan make:seed ArticlesTableSeeder

生成测试数据;

    public function run()
    {
        DB::table('articles')->insert([
            [
                'title' => 'elasticsearch',
                'content' => '一个基于Lucene的企业级搜索引擎'
            ],
            [
                'title' => 'elasticsearch analysis ik',
                'content' => '用于 elasticsearch 的中文分词插件'
            ]
        ]);
    }

运行填充;

php artisan db:seed --class=ArticlesTableSeeder

/routes/web.php

<?php
use App\Models\Article;

Route::get('search', function () {
    // 为查看方便都转成数组
    dump(Article::all()->toArray());
});

准备工作至此结束;
下面开始整合入 laravel ;
有三种方案可供选择;

第一种方案是 laravel-scout-elastic ;
这种基于 scout 的;
好处我们上篇文章已经写了;
增删改操作后自动更新索引;
配置起来也简单方便;
可以非常方便的在各种基于 scout 搜索方案间切换;
但是它并不理解东方神秘的方块字;
不能自定义分词器;
也不能愉快的完成中文搜索功能;

另一种是 Elasticquent ;
这种是独立于 scout 的;
它提供了符合 laravel 风格的操作索引的 api ;
并且和模型结合在了一起可以方便的进行搜索;
可以自定义分词愉快的中文搜索了;
但是结合的不像 scout 那样紧密;
对数据库增删改后还需要手动同步对索引进行相同的操作;
想便捷点也需要自己绑定监听增删改的事件;

那能不能有一个开箱即用还支持中文搜索的方案;
于是有了第三种方案 baijunyao/laravel-scout-elasticsearch 横空出世;
安装 driver ;

composer require baijunyao/laravel-scout-elasticsearch "^3.0"

添加 Provider ;
config/app.php

'providers' => [

    // ...

    /**
     * Elasticsearch全文搜索
     */
    Laravel\Scout\ScoutServiceProvider::class,
    Baijunyao\LaravelScoutElasticsearch\ElasticsearchServiceProvider::class,
],

发布配置项;

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

增加配置项;
/.env ;

SCOUT_DRIVER=elasticsearch

模型中定义全文搜索;
/app/Models/Article.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class Article extends Model
{
    use Searchable;

    /**
     * 索引的字段
     *
     * @return array
     */
    public function toSearchableArray()
    {
        return $this->only('id', 'title', 'content');
    }
}

生成索引;

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

使用起来也相当简单;
只需要把要搜索的内容传给 search() 方法即可;
/routes/web.php

<?php
use App\Models\Article;

Route::get('search', function () {
    // 为查看方便都转成数组
    dump(Article::all()->toArray());
    dump(Article::search('功能齐全的搜索引擎')->get()->toArray());
});


成功的查出了数据;

最后我们再测下修改数据后的同步索引;

routes/web.php

<?php

use App\Models\Article;

Route::get('search', function () {
    // 为查看方便都转成数组
    dump(Article::all()->toArray());
    dump('下面搜索的是:企业搜索');
    dump(Article::search('企业搜索')->get()->toArray());
    dump('此处把content改为:能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据');
    // 修改 content 测试索引是否会自动同步
    $first = Article::find(1);
    // $first->content = '一个基于Lucene的企业级搜索引擎';
    $first->content = '能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据';
    $first->save();
    // 因 Elasticsearch 同步索引需要点时间此处休眠5秒钟
    sleep(5);
    dump('下面搜索的是:企业搜索');
    dump(Article::search('企业搜索')->get()->toArray());
    dump('下面搜索的是:能胜服务');
    dump(Article::search('能胜服务')->get()->toArray());
});

———————————————————— 更新 ———————————————————— 本篇教程是基于 laravel-scout-elasticsearch v3 版本编写;
最新版的 laravel-scout-elasticsearch 已经不适用于本文章;
使用新版请参考 文档教程

白俊遥博客
请先登录后发表评论
  • latest comments
  • 总共29条评论
白俊遥博客

石石石 :如何处理特殊字符  比如我想全文检索”6+8=“如何处理+和=?大佬请指教

2020-06-05 18:22:26 回复

白俊遥博客

ShuiPingYang :可以试一下phantomjs

2020-04-13 10:53:52 回复

白俊遥博客

啸沧海 :按照这个一步一步,也是出现这个来的,php artisan elasticsearch:import "App\Models\Article"提示  There are no commands defined in the "elasticsearch" namespace.是不是漏了哪里没有配置啊?

2020-02-04 15:57:17 回复

白俊遥博客

呆萌@ :Elasticsearch\Common\Exceptions\NoNodesAvailableException  : No alive nodes found in your cluster  at E:\laravel-test\seo\vendor\elasticsearch\elasticsearch\src\Elasticsearch\ConnectionPool\StaticNoPingConnectionPool.php:53    49|                 return $connection;    50|             }    51|         }    52|  > 53|         throw new NoNodesAvailableException("No alive nodes found in your cluster");    54|     }    55|    56|     public function scheduleCheck()    57|     {  Exception trace:  1   Elasticsearch\ConnectionPool\StaticNoPingConnectionPool::nextConnection()      E:\laravel-test\seo\vendor\elasticsearch\elasticsearch\src\Elasticsearch\Transport.php:78  2   Elasticsearch\Transport::getConnection()      E:\laravel-test\seo\vendor\elasticsearch\elasticsearch\src\Elasticsearch\Transport.php:96  Please use the argument -v to see more details.

2019-12-04 13:31:58 回复

白俊遥博客

呆萌@ :Elasticsearch\Common\Exceptions\NoNodesAvailableException  : No alive nodes found in your cluster  at E:\laravel-test\seo\vendor\elasticsearch\elasticsearch\src\Elasticsearch\ConnectionPool\StaticNoPingConnectionPool.php:53    49|                 return $connection;    50|             }    51|         }    52|  > 53|         throw new NoNodesAvailableException("No alive nodes found in your cluster");    54|     }    55|    56|     public function scheduleCheck()    57|     {  Exception trace:  1   Elasticsearch\ConnectionPool\StaticNoPingConnectionPool::nextConnection()      E:\laravel-test\seo\vendor\elasticsearch\elasticsearch\src\Elasticsearch\Transport.php:78  2   Elasticsearch\Transport::getConnection()      E:\laravel-test\seo\vendor\elasticsearch\elasticsearch\src\Elasticsearch\Transport.php:96  Please use the argument -v to see more details.

2019-12-04 13:25:58 回复

白俊遥博客

呆萌@ :大佬, 在执行  php artisan elasticsearch:import "App\Models\Article"提示  There are no commands defined in the "elasticsearch" namespace.

2019-12-02 10:27:13 回复

白俊遥博客

新西..!? :这样的: php artisan scout:import "App\Models\Article"

2019-12-02 19:37:59 回复

白俊遥博客

呆萌@ :也不行

2019-12-04 13:24:33 回复

白俊遥博客

新西..!? :config\scout.php中这些都配置正确了吗?'elasticsearch' => [ 'index' => env('ELASTICSEARCH_INDEX', 'laravel'), 'hosts' => [ env('ELASTICSEARCH_HOST', 'http://127.0.0.1'), ], 'host'=>env('ELASTICSEARCH_HOST', '127.0.0.1'), 'port'=>env('ELASTICSEARCH_PORT',9200), 'scheme'=>env('ELASTICSEARCH_SCHEME','http')]

2019-12-04 16:49:57 回复

白俊遥博客

ysk99 :大神好:请问如何实现搜索结果高亮呢?谢谢

2019-03-07 15:18:28 回复

白俊遥博客

wcxxxxxx :请先登录后发表评论白俊遥博客

2018-11-29 17:03:14 回复

白俊遥博客

wcxxxxxx :试试

2018-11-29 17:37:11 回复

白俊遥博客

wcxxxxxx :试试

2018-11-29 17:38:16 回复

白俊遥博客

满成 :无限级?

2019-07-25 10:56:04 回复

白俊遥博客

ytkah :这些都实现了以后如何整合到站内搜索框里呢?期待大咖的回复

2018-11-01 18:19:17 回复

白俊遥博客

重来 :您好,请问用oderBy排序提示这个该怎么办呢?Article::search($keywords)->orderBy('hits','desc')->paginate();No mapping found for [hits] in order to sort on"

2018-08-05 23:49:35 回复

白俊遥博客

guanhui07 :挺赞的 

2018-07-24 11:41:32 回复

白俊遥博客

Come|`oN :大神,你是之前在**学习的那位吗?

2018-06-27 12:23:20 回复

白俊遥博客

ペキン 白俊遥博客

2018-06-24 22:05:56 回复

白俊遥博客

yi1501145484 白俊遥博客白俊遥博客

2018-06-22 11:43:08 回复

白俊遥博客

☆【唯①敏〗★ :白大哥,请问  怎么把 将 MySQL已有的数据导入到 ES6.2.4 里面?我搜索的  【elasticsearch-jdbc-2.3.4.1】插件,这是最后一个版本,2年没更新了,版本严重落后,所以一直导入不了。求教

2018-06-21 14:56:59 回复

白俊遥博客 白俊遥博客

云淡风晴 :数据量不大的可以考虑使用官方提供的扩展包用php导入https://github.com/elastic/elasticsearch-php;

2018-06-24 19:37:22 回复

白俊遥博客

:想和博主交换友情连接,不知道可以么?    我已经先添加好了,如果不可以还望通知一下。博客关键词:蜗居     博客地址:https://woj.app

2018-06-21 11:41:35 回复

白俊遥博客

孤城浪子 :还是要对elasticsearch有一定的了解,不然用起来也是一脸懵逼的,白大神可以写个es的简易教程,比廖雪峰那个详细些就好了。

2018-06-21 09:53:09 回复

白俊遥博客

cout <<"Hello,word!" <<endl; :哈哈

2018-06-14 14:58:00 回复

白俊遥博客

梦。 :好

2018-06-14 09:48:32 回复

白俊遥博客

碗杯碟筷勺 :能请教一下大神,phpdebugbar是怎么展示在前端页面的。找了许久你的代码都看不见,在哪里写入了js代码

2018-06-12 23:53:19 回复

白俊遥博客

洪乃火 白俊遥博客白俊遥博客

2018-06-13 23:11:00 回复

白俊遥博客 白俊遥博客

云淡风晴 :是这个 https://github.com/barryvdh/laravel-debugbar 提供的

2018-06-24 19:40:02 回复