Laravel + Elasticsearch 实现中文搜索
作者:互联网
Elasticsearch
Elasticsearch 是一个基于 Apache Lucene (TM) 的开源搜索引擎,无论在开源还是专有领域,Lucene 可 以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。
但是,Lucene 只是一个库。想要发挥其强大的作用,你需使用 Java 并要将其集成到你的应用中。Lucene 非常复杂,你需要深入的了解检索相关知识来理解它是如何工作的。
Elasticsearch 也是使用 Java 编写并使用 Lucene 来建立索引并实现搜索功能,但是它的目的是通过简单连贯的 RESTful API 让全文搜索变得简单并隐藏 Lucene 的复杂性。
不过,Elasticsearch 不仅仅是 Lucene 和全文搜索引擎,它还提供:
分布式的实时文件存储,每个字段都被索引并可被搜索
实时分析的分布式搜索引擎
可以扩展到上百台服务器,处理 PB 级结构化或非结构化数据
而且,所有的这些功能被集成到一台服务器,你的应用可以通过简单的 RESTful API、各种语言的客户端甚至命令行与之交互。上手 Elasticsearch 非常简单,它提供了许多合理的缺省值,并对初学者隐藏了复杂的搜索引擎理论。它开箱即用(安装即可使用),只需很少的学习既可在生产环境中使用。
Elasticsearch 在 Apache 2 license 下许可使用,可以免费下载、使用和修改。
ElasticSearch 安装
官方下载地址:
https://www.elastic.co/cn/downloads/elasticsearch
安装过程不再赘述,网上一堆教程哈。
我用的是Windows系统,安装完成后,用cmd进入es安装目录下的bin文件夹,执行 elasticsearch 启动es服务,
访问127.0.0.1:9200,出现以下界面为安装成功
IK 分词器安装
ElasticSearch 主要是用于自己 blog 或者公众号文章的搜索使用,所以需要选择一个中文分词器配合使用,这里刚开始推荐使用 IK 分词器,下面开始安装对应 ElasticSearch 版本 (7.15.1) 一致的插件:
https://github.com/medcl/elasticsearch-analysis-ik/releases
下载完成后,解压插件到文件夹 es安装目录/plugins/ik
重启elasticsearch
用postman 试一下分词效果,
结合 Laravel
虽然 Elasticsearch 官方提供了对应的 PHP 版本的插件,但我们还是希望和 Laravel 结合的更紧密些,所以这里选择和 Scout 结合使用,具体用到了 babenkoivan/elastic-scout-driver 插件
github地址:https://github.com/babenkoivan/elastic-scout-driver
我看到网上的教程都用的是laravel-scout-elastic 这个软件包,但是我用的时候发现他不支持laravel8,所以我找到了他的完美替代品“elastic-scout-drive”。
安装 elasticsearch-php 客户端
composer require elasticsearch/elasticsearch
安装 elastic-scout-driver 软件包
composer require babenkoivan/elastic-scout-driver
请注意,这个库只是 Laravel Scout 的驱动程序,不要忘记预先安装它:
composer require laravel/scout
安装Scout后,使用发布其配置文件
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
发布完成后,编辑config/scout.php
// config/scout.php
...
// Set your driver to elasticsearch
'driver' => env('SCOUT_DRIVER', 'elastic'),
...
/*
|--------------------------------------------------------------------------
| Elasticsearch Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your Elasticsearch settings.
|
*/
'elasticsearch' => [
'hosts' => [
env('ELASTICSEARCH_HOST', 'localhost'),
// [
// 'host' => env('ELASTICSEARCH_HOST', 'localhost'),
// 'port' => env('ELASTICSEARCH_PORT', '9200'),
// 'scheme' => env('ELASTICSEARCH_SCHEME', 'https'),
// 'path' => env('ELASTICSEARCH_PATH', '/elastic'),
// 'user' => env('ELASTICSEARCH_USER', 'username'),
// 'pass' => env('ELASTICSEARCH_PASS', 'password'),
// ]
],
]
...
在.env 里加入ELASTICSEARCH_HOST地址
ELASTICSEARCH_HOST=127.0.0.1:9200
创建索引#
创建索引有好几种方式,可以用postMan
或者用Laravel 自带的 Artisan 命令行功能。
php artisan make:command ESOpenCommand
根据官网提示,我们可以在 ESOpenCommand 上向 Elasticsearch 服务器发送 PUT 请求,这里借助 Elasticsearch 提供的 PHP 插件,在我们上面的过程中,已经安装了 Elasticsearch PHP 插件
下面就可以借助插件,创建我们的 Index,直接看代码:
<?php
namespace App\Console\Commands;
use Elasticsearch\ClientBuilder;
use Illuminate\Console\Command;
class ESOpenCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'es:create';
/**
* 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 int
*/
public function handle()
{
$host = config('scout.elasticsearch.hosts');
$index = 'bloges';
$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_max_word'
],
'content' => [
'type' => 'text',
'analyzer' => 'ik_max_word',
'search_analyzer' => 'ik_max_word'
]
],
]
]
]);
}
}
执行一下php artisan 命令 php artisan es:create
好了,我们已经成功创建index ,验证一下
用postman 访问 127.0.0.1:9200/_cat/indices 查看所有index
可以看到bloges 索引已经成功创建,注意黄色圆圈的数字,他代表这个索引里面有多少条数据。之后可以验证数据是否导入成功。
OK,配置完成后我们开始随便建个Controller 和 model
php artisan make:model Blog -mc
迁移文件
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateBlogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('blogs', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->integer('red_num');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('blogs');
}
}
model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
class Blog extends Model
{
use HasFactory;
use Searchable;
protected $table = 'blogs';
public function searchableAs()
{
return 'bloges';
}
public function toSearchableArray()
{
$data = [
'id' => $this->id,
'title' => $this->title,
'content' => $this->content
];
return $data;
}
}
model 里注意searchableAs 这里写索引的名称,toSearchableArray 里写可以用于搜索的字段。具体可以参考scout的文档 https://learnku.com/docs/laravel/9.x/scout/12273
然后我们随便复制粘贴一些数据到blog表里。
Scout 提供了 Artisan 命令 import 用来导入所有已存在的记录到搜索索引中。
php artisan scout:import "App\Models\Blog"
接下来在controller里面
$orders = Blog::search('树叶 过来 业绩')->raw();
//或者
$orders = Blog::search('树叶 过来 业绩')->get();
//raw 输出原始格式,get 输出 Eloquent Model
dd($orders);
看下结果
大功告成!
参考:
https://learnku.com/articles/40289
https://blog.csdn.net/jam00/article/details/52983056
https://www.cnblogs.com/mmmzh/p/11599678.html
标签:Laravel,index,中文搜索,scout,Elasticsearch,env,elasticsearch,ELASTICSEARCH 来源: https://www.cnblogs.com/houying/p/15963542.html