Xunsearch和laravel5.8的使用

88 篇文章 0 订阅

安装php依赖包:

composer require hightman/xunsearch

composer require laravel/scout="7.2.1"

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

开始配置:

SCOUT_DRIVER=xunsearch
XUNSEARCH_HOST=192.168.91.158
SCOUT_PREFIX=
SCOUT_QUEUE=false

 

demo.php:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
use App\Services\XunSearchEngine;

class Demo extends Model
{
    use Searchable;
    
    protected $table='demo';
    public $timestamps = true;
    
    
    public function searchableIndexData()
    {
        $indexData = [
            'id' => $this->id,
            'title' => $this->title,
        ];
        return $indexData;
    }
    
    public function searchableUsing()
    {
        $xs = new \XS(config_path('xunsearchini/demo.ini'));
        return new XunSearchEngine($xs);
    }
    
}

XunSearchEngine.php

<?php

namespace App\Services;

use Illuminate\Database\Eloquent\Collection;
use Illuminate\Support\Facades\Log;
use Laravel\Scout\Builder;

class XunSearchEngine
{
    protected $xs;

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

    /**
     * 更新给定模型索引
     *
     * @param \Illuminate\Database\Eloquent\Collection $models
     * @return void
     * @throws \XSException
     */
    public function update($models)
    {
        if ($models->isEmpty()) {
            return;
        }

        // if ($this->usesSoftDelete($models->first()) && config('scout.soft_delete', false)) {
        //     $models->each->pushSoftDeleteMetadata();
        // }
        Log::info('Update Index');
        $index = $this->xs->index;
        $models->map(function ($model) use ($index) {
            $array = $model->toSearchableArray();
            if (empty($array)) {
                return;
            }
            $doc = new \XSDocument;
//             $data = [
//                 'id' => $model->id,
//                 'title' => $model->title,
//                 'content' => $model->content,
//             ];
            $doc->setFields($model->searchableIndexData());
            $index->update($doc);
        });
        $index->flushIndex();
    }

    /**
     * 从索引中移除给定模型
     *
     * @param \Illuminate\Database\Eloquent\Collection $models
     * @return void
     * @throws \XSException
     */
    public function delete($models)
    {
        $index = $this->xs->index;
        $models->map(function ($model) use ($index) {
            Log::info('Deleted:' . $model->getKey());
            $index->del($model->getKey());
        });
        $index->flushIndex();
    }


    /**
     * 通过迅搜引擎执行搜索
     *
     * @param \Laravel\Scout\Builder $builder
     * @return mixed
     */
    public function search(Builder $builder)
    {
        return $this->performSearch($builder, array_filter(['hitsPerPage' => $builder->limit]));
    }

    /**
     * 分页实现
     *
     * @param \Laravel\Scout\Builder $builder
     * @param int $perPage
     * @param int $page
     * @return mixed
     */
    public function paginate(Builder $builder, $perPage, $page)
    {
        return $this->performSearch($builder, [
            'hitsPerPage' => $perPage,
            'page' => $page - 1,
        ]);
    }

    /**
     * 返回给定搜索结果的主键
     *
     * @param mixed $results
     * @return \Illuminate\Support\Collection
     */
    public function mapIds($results)
    {
        return collect($results)
            ->pluck('id')->values();
    }


    /**
     * 将搜索结果和模型实例映射起来
     *
     * @param Builder $builder
     * @param \Illuminate\Database\Eloquent\Model $model
     * @param mixed $results
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public function map(Builder $builder, $results, $model)
    {
        if (count($results) === 0) {
            return Collection::make();
        }

        $keys = collect($results)
            ->pluck('id')->values()->unique()->all();
        $models = $model->getScoutModelsByIds($builder, $keys)->keyBy($model->getKeyName());
        return Collection::make($results)->map(function ($hit) use ($model, $models) {
            $key = $hit['id'];
            if (isset($models[$key])) {
                return $models[$key];
            }
        })->filter();
    }

    /**
     * 返回搜索结果总数
     *
     * @param mixed $results
     * @return int
     */
    public function getTotalCount($results)
    {
        return ceil($this->xs->search->getLastCount() / 2);
    }

    // protected function usesSoftDelete($model)
    // {
    //     return in_array(SoftDeletes::class, class_uses_recursive($model));
    // }
    // 执行搜索功能
    protected function performSearch(Builder $builder, array $options = [])
    {
        $search = $this->xs->search;

        if ($builder->callback) {
            return call_user_func(
                $builder->callback,
                $search,
                $builder->query,
                $options
            );
        }

        $search->setFuzzy()->setQuery($builder->query);
        collect($builder->wheres)->map(function ($value, $key) use ($search) {
            $search->addRange($key, $value, $value);
        });

        $offset = 0;
        $perPage = $options['hitsPerPage'];

        if (!empty($options['page'])) {
            $offset = $perPage * $options['page'];
        }
        return $search->setLimit($perPage, $offset)->search();
    }

    /**
     * 获取中文分词
     * @param $text
     * @return array
     */
    public function getScwsWords($text)
    {
        $tokenizer = new \XSTokenizerScws();
        return $tokenizer->getResult($text);
    }
}

demo.ini:

project.name = demo
project.default_charset = utf-8
server.index = 192.168.91.158:8383
server.search = 192.168.91.158:8384

[id]
type = id

[title]
type = title

XunsearchController.php

<?php

namespace App\Http\Controllers;
use App\Models\Goods;
use App\Models\Student;
use App\Models\Demo;

class XunsearchController extends Controller
{
    public function xundemo(){
        //数据有更新和插入操作,会自动更新到xunsearch中
//         $goods = new Goods();
//         $goods->title = '终于成功了';
//         $goods->content= '终于成功了';
//         $goods->save();
        
//         $student = new Student();
//         $student->title = '终于成功了';
//         $student->content= '终于成功了';
//         $student->save();

//         $demo = new Demo();
//         $demo->title = '测试';
//         $demo->content= '终于成功了';
//         $demo->save();

        
        $keyword = '测试';
        $res = Demo::search($keyword)->paginate(20);
        dd($res);
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梅坞茶坊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值