使用laravel scout集成xunsearch进行全文搜索

创建于 9个月前 / 阅读数 160 / PHP


简介

Laravel Scout 为 Eloquent 模型的全文搜索提供了一个简单的、基于驱动程序的解决方案。使用模型观察员,Scout 会自动同步你的搜索索引和 Eloquent 记录。

但其本身并非是一套完整的查询引擎,Scout 自带了一个 Algolia 驱动,结合命令行操作,方便我们对现有数据进行缓存和索引,但超过查询接口的一定数量需要收费。

安装 Laravel Scout

安装依赖包

$ composer require laravel/scout

说明:由于使用的 Laravel 5.5 会自动发现 package

生成配置文件

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

模型引入 trait 如:app / Post.php

<?php

use Laravel\Scout\Searchable;

class Post extends Model
{
    use Searchable;
    ...
}

使用 Algolia

安装

$ composer require algolia/algoliasearch-client-php

登录 Algolia 官网注册账号获取密钥信息
.env

ALGOLIA_APP_ID=xxx
ALGOLIA_SECRET=xxx

将现有测试数据导入

$ php artisan scout:import "App\Post"

说明:在 Algolia 官网可以看到数据信息

路由测试 web / routes.php

Route::get('postSearch', function () {
    $re = $post -> search('xxx') -> get();
    dump($re);
});

使用 ElasticSearch

硬性条件:

  • 请确保服务器内存 > 2G
  • 确保安装了 java-sdk 环境

下载并安装

$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.5.3.zip
$ unzip elasticsearch-6.5.3.zip
$ cd elasticsearch-6.5.3

启动并测试

$ ./bin/elasticsearch
$ curl http://127.0.0.1:9200

{
    "name" : "i6ksBTY",
    "cluster_name" : "elasticsearch",
    "cluster_uuid" : "fgCVTDWqRGuZNQ5WDWaoag",
    "version" : {
        "number" : "6.5.3",
        "build_flavor" : "default",
        "build_type" : "zip",
        "build_hash" : "159a78a",
        "build_date" : "2018-12-06T20:11:28.826501Z",
        "build_snapshot" : false,
        "lucene_version" : "7.5.0",
        "minimum_wire_compatibility_version" : "5.6.0",
        "minimum_index_compatibility_version" : "5.0.0"
    },
    "tagline" : "You Know, for Search"
}

安装分词插件

$ cd /selslim/elasticsearch-6.5.3/plugins
$ wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.5.3/elasticsearch-analysis-ik-6.5.3.zip
$ mkdir ik
$ unzip elasticsearch-analysis-ik-6.5.3.zip -d ik

说明:注意删除 plugins 下的 zip 包否则无法启动

重新启动 elasticsearch 并测试

...
[2018-12-18T14:55:34,828][INFO ][o.e.p.PluginsService     ] [i6ksBTY] loaded plugin [analysis-ik]
...

./bin/elasticsearch-plugin list
ik

ElasticSearch 安装完成后,安装对应 composer 包使用即可,唯一问题是非常吃服务器资源:sweat_smile:

使用 Xunsearch

接下来谈到今天的主角,也是本博客全文搜索的解决方案,不仅对服务器占用资源少,且查询效率极高,包括热门搜索关键词,高亮显示,建议搜索,纠错等功能

Xunsearch 本身提供了一套基于 Yii 的 sdk,但对于 laravel 而言明显不适用,为了能结合 scout 使用,第一步便是扩展继承 scout 的引擎,这样便能使用 scout 提供的命令行工具进行查询和导入数据

首先我们可以查看官网对于 scout 扩展的说明:

你的引擎需要继承 Laravel\Scout\Engines\Engine 抽象类,这个抽象类包含了你自定义的引擎必须要实现的五种方法

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);

iiiku.com 案例

这里提供本网站的全文搜索解决方案,具体细节还请大家通读 xunsearch 文档,可以自行先在本地测试功能。将对应方法注册即可打通即可。

新建 app / Services / SearchEngine / XunSearchEngine.php

namespace App\Services\SearchEngine;

use Illuminate\Database\Eloquent\Collection;
use Laravel\Scout\Builder;
use Laravel\Scout\Engines\Engine;
use XS;

class XunSearchEngine extends Engine
{
    protected $xs;

    public function __construct(XS $xs)
    {
        $this -> xs = $xs;
    }

    // 后续实现需要继承的方法
    ...

注册引擎 app / Providers / AppServiceProvider.php

use Laravel\Scout\EngineManager;
use App\Services\SearchEngine\XunSearchEngine;
use XS;

public function boot()
{
    resolve(EngineManager::class) -> extend('xunsearch', function () {
    $xs = new XS('articles.ini');
        return new XunSearchEngine($xs);
    });
}

后续可以按照 scout 提供的 api 进行一系列操作

批量导入

$ php artisan scout:import "app\Post"

进行查询

use App\Post;

Route::get('test', function (Post $post) {
    // 普通查询
    $post -> search('Selslim') -> get();
    // 分页结果
    $post -> search('Selslim') -> paginate();
});

说明:返回普通查询的 Collection,那么后续操作和平时一样