為什么不用 Scout?
熟悉 Laravel 的同學,應該會有此疑問。Scout 是 Laravel 官方出的一個讓 Eloquent 模型支持全文搜索的包,這個包封裝好一批方法,通過這些方法就可以將數據索引到全文搜索引擎中、以及使用關鍵字從搜索引擎搜索文檔。這個包適用於一些簡單的搜索場景,比如博客文章搜索,但無法發揮出全文搜索引擎全部威力,像 Elasticsearch 這種重量級的搜索引擎有無數種查詢語句,例如 我們should 語句、模糊查詢、分片查詢等,根本不是 Scout 幾個簡單的方法能夠覆蓋的,也就無法滿足電商系統搜索模塊的需求。
一、安裝 elasticsearch/elasticsearch
包詳細介紹:https://packagist.org/packages/elasticsearch/elasticsearch
1):安裝(請根據elasticsearch 版本安裝對應的包)
composer require elasticsearch/elasticsearch '~7.0'
2)配置
在.env文件中增加一行: ES_HOSTS=localhost
在config/database.config 增加
'elasticsearch' => [
// Elasticsearch 支持多台服務器負載均衡,因此這里是一個數組
'hosts' => explode(',', env('ES_HOSTS')),
]
修改 app/Providers/AppServiceProvider.php 文件
use Elasticsearch\ClientBuilder as ElasticBuilder;
。。。。。。。。。。。
public function register()
{
$this->app->singleton('es',function()
{
$bulider=ElasticBuilder::create()->setHosts(config('database.elasticsearch.hosts'));
if(app()->environment()=='local')
{
//配置日志,Elasticsearch 的請求和返回數據將打印到日志文件中,方便我們調試
$bulider->setLogger(app('log'));
}
return $bulider->build();
});
}
3)測試
輸入 php artisan tinker 進入測試模式輸入: app('es')->info()

4)常用查詢
增加數據結構:
/*增加index 相當於數據庫名稱*/
curl -XPUT http://localhost:9200/video_list?pretty
/*增加數據結構*/
curl -H'Content-Type: application/json' -XPOST http://localhost:9200/video_list/_doc?pretty -d'{
"properties":{
"video_id": { "type": "text" },
"user_id":{"type":"integer"},
"title": { "type": "text", "analyzer": "ik_smart" },
"cover": { "type": "text" } ,
"description":{ "type": "text" } ,
"status": { "type": "short" },
"is_tui": { "type": "short" },
"play_num":{ "type": "integer"},
"zan_num": { "type": "integer" },
"comment_num": { "type": "integer" },
"report_num": { "type": "integer" },
"share_num": { "type": "integer" },
"city_id": { "type": "integer" },
"special_id": { "type": "integer" },
"city": { "type": "text"},
"comments":{"type":"Nested","properties":
{
"user_id":{"type":"integer"},
"zan_num":{"type":"integer"},
"status":{"type":"short"},
"content":{"type":"text"}
}},
"users":{"type":"Nested","properties":
{
"user_name":{"type":"text"},
"nick_name":{"type":"text"},
"user_picture":{"type":"text"}
}
}
}}'
在model中增加方法,以便處理成elasticsearch 需要的數據
1 public function user() 2 { 3 return $this->belongsTo(User::class,'user_id','user_id'); 4 } 5 6 public function comments(){ 7 return $this->hasMany(VideoComment::class,'video_id','video_id'); 8 } 9 /* 轉化成 elasticSearch 數據*/ 10 public function toESArray() 11 { 12 $arr=Arr::only($this->toArray(),['video_id','user_id','title','cover','description','status','is_tui','play_num','zan_num','comment_num','report_num','share_num','city','city_id','special_id']); 13 14 $arr['comments']=$this->comments->map(function (VideoComment $comments) 15 { 16 return array_only($comments->toArray(),['user_id','zan_num','status','content']); 17 }); 18 19 $arr['users']=array_only($this->user->toArray(),['user_name','nick_name','user_picture']); 20 21 return $arr; 22 23 }
使用命令:php artisan tinker進入 測試
$arr=App\Http\Model\Video::where('video_id','016e468adb5341928a3e8cab57ffe7b3')->first()->toESArray();
app('es')->index(['index'=>'video_list', 'id'=>'016e468adb5341928a3e8cab57ffe7b3','body'=>$arr])

查詢數據:app('es')->get(['id'=>數據id,'body'=>內容])

