laravel Scout包在elasticsearch中的應用

laravel Scout包在elasticsearch中的應用

laravel的Scout包是針對自身的Eloquent模型開發的基於驅動的全文檢索引擎。意思就是咱們能夠像使用ORM同樣使用檢索功能。無論你用的是什麼搜索引擎,scout包給你封裝好了幾個方法php

use Laravel\Scout\Builder;

abstract public function update($models);
abstract public function delete($models);
abstract public function search(Builder $builder);
abstract public function paginate(Builder $builder, $perPage, $page);
abstract public function map($results, $model);

你只須要建立一個引擎(好比es引擎)就可使用orm來操做search了。laravel

惋惜laravel的scout包只提供了Algolia的驅動。我我的很喜歡的es並無提供驅動。好在網上有人分享了驅動,好比 https://github.com/ErickTamayo/laravel-scout-elasticgit

看裏面的代碼,其實很簡單,兩個類,一個類ElasticsearchEngine用於實現Scout定義的幾個方法,一個類ElasticsearchProvider用於作服務註冊。咱們使用composer require就能用好這個類了。這裏就不說了。github

scout包在es中的存儲

說說laravel的scout包在es裏面是怎麼存儲的。首先,在配置文件裏面elasticsearch建立一個index數據庫

'driver' => env('SCOUT_DRIVER', 'elasticsearch'),

    ...    
    'elasticsearch' => [
        'index' => env('ELASTICSEARCH_INDEX', 'laravel'),
        'hosts' => [            
            env('ELASTICSEARCH_HOST', 'http://localhost'),
            ],
        ],
    ...

而後每一個對應的model都是不一樣的type。這個type的名字是在model裏面定義的。composer

class Post extends Model
use Laravel\Scout\Searchable;

class Post extends Model
{
    use Searchable;

    protected $table = "posts";

    /*
     * 搜索的type
     */
    public function searchableAs()
    {
        return 'posts_index';
    }

    public function toSearchableArray()
    {
        return [
            'title' => $this->title,
            'content' => $this->content,
        ];
    }

因此它裏面每一個條目其實是這麼一個結構:elasticsearch

我本身用的幾點體驗:

1 scout會很聰明把表的主鍵做爲es的_idide

這個真是很是贊,不須要存儲一個id,作_id和id的關聯了函數

2 scout在model作增刪改查的時候會自動更新索引post

這個也是咱們最須要的,索引數據和數據庫數據的同步使用代碼進行保證了。固然,用代碼保證可能並非什麼很好的方法,可是對於小型的網站來講,這個無疑增長了便捷性。

3 scout的創建索引方法是一個網站統一一個index, 不一樣的model使用不一樣的type

這種一個index多type的形式是否適用你的項目呢?不必定,若是你的model各不相同,可能多個index更好點。關於index和type的選擇,https://www.elastic.co/blog/index-vs-type 能夠參考這篇。因此這種方式可能更適合的是存儲到es的都是文本的搜索。

4 search函數裏面不能指定搜索字段

好比個人Post索引存入了title和content。那麼我使用Post::search("china")的時候,搜索出來的結果就是title和content中包含有china的。若是我想搜索content中包含有"china"的,沒辦法,scout作不到,只能本身作擴展了。

5 分頁指定了查詢的字段名必須是query

這個意思是在搜索接口,你上交上來的查詢接口必須是query=xx,形如http://127.0.0.1:8000/posts/search?query=china
看了源碼發現這個query字段是由Scout/Builder寫死在代碼裏面的...這個估計不少人用到這個分頁的時候會踩進去

6 搜索的query強制使用通配符

這個是laravel-scout-elasticsearch的問題了,它在query的時候強制在搜索的先後使用上了通配符*,這個在標準分詞器中文搜索的時候會出現問題,會變成一個詞,具體問題能夠看這個帖子:http://elasticsearch.cn/question/228

因此若是要使用標準分詞器,須要把query的先後兩個*都去掉,具體代碼在vendor/tamayo/laravel-scout-elastic/src/ElasticsearchEngine.php中。

總結

scout仍是主要偏向於統一搜索接口,若是你的網站很小,而且搜索只是做爲文本搜索的話,那麼用這個是很是合適的,可是若是你的搜索功能佔你的網站大部分功能的話,那麼我建議咱們可使用scout作搜索和數據庫的同步,其餘的搜索請求,咱們使用elasticsearch/elasticsearch本身寫比較好。

相關文章
相關標籤/搜索