Xunsearch和laravel5.8的操作

原创
小哥 3年前 (2022-11-05) 阅读数 15 #AI人工智能
文章标签 Laravel

安装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);
}
}

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除