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本身写比较好。

相关文章
相关标签/搜索