mysql全文索引thinkphp_ThinkPHP5 使用迅搜 (XunSearch) 实现全文检索实例指导

前期准备

入坑了一天,折腾的无语,个人观点:【文档太差,适合学习思路,不建议入坑】

背景

最近在整理全文检索解决方案

注意到 xunsearch 的评价很高,在此记录一番

场景描述

此处作为对 xunsearch 的初次使用,

以一个简单的商品 SKU 信息搜索场景进行描述

我已有一张 tp5_xsku表,用来存储商品 SKU 信息

主键为 "sku_id",需要进行匹配的字段为:"spec_name"

ce4b71a30ac4d27664d923d0fa342201.png

环境

PHP:php7.2.9

Linux:CentOS7.9

MySQL:mysql5.7.32

☞ XunSearch 服务端搭建

此处,我将网站应用部署在本地 windows 环境

然后,使用一台虚拟机 【192.168.80.224】作为 xunsearch 服务器的部署环境

1). 运行下面指令下载、解压安装包

此处,我选择的是一台 CentOS7 的虚拟机 [ip:192.168.80.224],作为服务端

wget http://www.xunsearch.com/download/xunsearch-full-latest.tar.bz2

tar -xjf xunsearch-full-latest.tar.bz2

2). 执行安装脚本

首先,建议将解压后的文件夹移动到 "usr/local/" 目录下

此处,我做了文件夹重命名、拷贝操作

mv xunsearch-full-1.4.15/ xunsearch

cp -r xunsearch /usr/local/xunsearch

然后执行安装脚本命令

选择默认即可(第一次安装的话,过程可能会稍显漫长)

cd /usr/local/xunsearch/

sh setup.sh

一般没啥问题,最终成功提示信息如下:

790134f33aa9662ada98cc5522211217.png

因为我的 SDK 调用和 xunsearch 服务端不在同一服务器,所以使用 -b inet 方式启动脚

/usr/local/xunsearch/bin/xs-ctl.sh -b inet start

【提示】:

注意官方建议的 不同启动方式,不然坑死你

其次,测试发现,如果我直接删掉了 "/usr/local/xunsearch/data" 文件夹,后续直接没反应

需要重启 xunsearch 服务方可!(也没见官网提示)

3). 设置端口号

通过对 xunsearch 的启动命令操作发现,需要有端口号 "8383、8384" 的支持

注意借助类似 iptables 的防火墙,

来控制 xunsearch 的 8383/8384 两个端口的访问权限

0b19be22ad52249e438a866c21ef85b4.png

启动完成后,可以输入命令查看服务的运行状态: "ps -ef | grep xs-searchd"

[root@localhost ~]# ps -ef | grep xs-searchd

root 2431 1 0 13:25 ? 00:00:00 xs-searchd: master

root 2432 2431 0 13:25 ? 00:00:00 xs-searchd: worker[1]

root 2433 2431 0 13:25 ? 00:00:00 xs-searchd: worker[2]

root 2434 2431 0 13:25 ? 00:00:00 xs-searchd: worker[3]

root 2487 2397 0 13:29 pts/0 00:00:00 grep --color=auto xs-searchd

4). 设置开机启动

建议将 xunsearch 添加到开机启动脚本中,以便每次服务器重启后能自动启动搜索服务程序

在 Linux 系统中,

可以将脚本指令 "/usr/local/xunsearch/bin/xs-ctl.sh -b inet start"

写进 "/etc/rc.local" 文件,然后保存退出即可

vi /etc/rc.local

☞ ThinkPHP5 应用框架的配置

此处,注意,应用框架跟前面的 "XunSearch" 服务端不在一个 ip 地址

1). composer 安装 sdk

进入项目根目录,执行 composer 指令如下:

composer require --prefer-dist hightman/xunsearch "*@beta"

此时,会在 "vendor" 目录下,生成两个相关文件夹

2a12c0b1c37a1f20fbdc313f5551a457.png

检测 PHP-SDK 的运行条件

此时,可以在 "vendor\hightman\xunsearch\util" 目录中

运行 php 指令:php RequiredCheck.php

533de50df0ca8ed4b72c269450db8842.png

2). 配置文件的修改

对于配置文件的详细解释,建议阅读文档 —— 【xunsearch 项目配置文件详解】

每个搜索项目必须有且仅有一个 type=id 字段,确保每条数据具备唯一值,是索引更新和删除的凭据

可以参考 "vendor/hightman/xunsearch/app/demo.ini" 文件

创建属于自己业务的配置文件

我新建了一个"goods_sku.ini" 文件,配置参考如下:

project.name = goods_sku

project.default_charset = utf-8

server.index = 192.168.80.224:8383

server.search = 192.168.80.224:8384

[sku_id]

type = id

[spec_name]

type = string

index = both

3). 集成方法类 "XunseachService" 的使用

根据网上的一些经验,建议,创建一个集成方法类

此处,提供 "XunsearchService.php" 的源码,方便参考使用

namespace app\common\lib;

/**

* xunsearch 集成使用类

* Class XunsearchService

* @package app\common\lib

*/

class XunsearchService

{

/**

* 中文分词搜索

* @param string $keywords 关键词

* @param string $file ini文件名

* @param bool $is_scws 是否开启中文分词(例如:口袋新世代,拆分成:口袋、新、世代)

* @param int $limit 搜索结果条数

* @return array 返回结果

* @throws \XSException

*/

public static function search($keywords,$file = 'demo',$is_scws = false,$limit = 100){

$xs = new \XS($file);

if($is_scws === true) {

//中文分词

$tokenizer = new \XSTokenizerScws;

//词语拆分

$words = $tokenizer->getTokens($keywords);

$where = '';

//拼接成查询条件(OR)

foreach ($words as $key => $val) {

if ($key == 0) {

$where = $val;

} else {

$where .= ' OR ' . $val;

}

}

}else {

$where = $keywords;

}

$search = $xs->search;

$result = $xs->search->setQuery($where)

//->setSort('sku_id','asc') #按索引排序

->setDocOrder(true) #按添加索引排序(升序)

->setLimit($limit)

->search();

$search->close();

return $result;

}

/**

* 新增/更新/删除 xunsearch 数据库

* @param array $data

* @param string $file ini文件名

* @param string $tag 'add':新增;'update':更新;'[主键ID]':删除

* @return bool

*/

public function save($data,$file = 'demo',$tag = 'add'){

try {

$xs = new \XS($file);

#创建文档对象

$doc = new \XSDocument;

$doc->setFields($data);

#更新(新增)数据

$index = $xs->index;

if ($tag == 'add'){

$index->add($doc);

}elseif ($tag == 'update'){

$index->update($doc);

}else{

// 此处,传来的是作为主键的值

$index->del($tag);

}

#强制刷新当前索引列表数据

return $index->flushIndex();

}catch (\Exception $e){

return false;

}

}

}

新建类名可自定义,基本没啥疑问

4). 增加索引的操作

在商品 SKU 数据操作变化的业务逻辑位置,添加如下代码:

(注意传参的不同,此处只是演示了增加的操作)

$xs_data = [

'sku_id' => $sku_ID,

'spec_name' => $spec_name

];

$xsService = new XunsearchService();

$xsService::save($xs_data,'goods_sku');

提示

如果操作成功,你会在 xunsearch服务端的 "data"目录下发现一个 "goods_sku" 的文件夹

5). 索引查询操作

在需要进行查询操作的位置,补充如下代码:

(后续便是根据返回的数组,然后匹配业务数据表的 sku_id ,进行商品信息的展示了 …)

$xsService = new XunsearchService();

try {

$message = $xsService::search('我找原味的瓜子和爆款蓝牙', 'goods_sku', true);

} catch (\XSException $e) {

$message = $e->getMessage();

}

var_dump($message);

☞ 附录

①. 代码检索测试

首先,我触发"$xsService->save()" 事件,得到了六个数据

然后,在查询操作时,置空 "$xsService::search()" 的第一个参数可得到如下数据:

14c1b332ae0ff49213a678d914894e6d.png

在此,我设置查询的文字为:"我找原味的瓜子和爆款蓝牙"

代码处理,得到的查询语句为:"我找 OR 找 OR 原味 OR 的 OR 瓜子 OR 和 OR 和爆 OR 爆款 OR 款 OR 蓝牙"

运行匹配得到的结果集如下:

090fc35d443a8ce786818ec63fa8d5e6.png

从结果上来看,还是可以接受的

不过,此处可以注意到拆分的名词还是差点意思,可对比参考下 —— 【HanLP 在线演示】

156b214abce856b5b4525c1d7c5050c7.png

②. 一点点拙见

提示: 目测官方没有好的精力去升级优化,论坛也没法访问,好多问题找不到探讨 ...

忍不住吐槽

学习过程中

网上的例子比较少,遇到问题不好解答

比较失望的是,官方文档说的不清楚,需要多次测试,碰运气的感觉

好歹给个参考实例,演示代码实现过程吧!!

再给个赞赏

话又说回来

作为开源项目为大家提供便利

本身就是值得赞赏的,太过吹毛求疵就不好了!

希望,同道中人少踩几个坑,共同进步,谢谢 ...

本文同步分享在 博客“moTzxx”(CSDN)。

如有侵权,请联系 support@oschina.cn 删除。

本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/539678.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为何有些程序员总是想要“干掉”产品经理?

好了,我准备去和产品经理做斗争去了,请祝我好运吧!小编花了大量时间收集了很多干货编程学习资源,其中资源包括 算法,大数据,人工智能,Python,Android,iOS,Jav…

Spark算子篇 --Spark算子之combineByKey详解

一。概念 rdd.combineByKey(lambda x:"%d_" %x, lambda a,b:"%s%s" %(a,b), lambda a,b:"%s$%s" %(a,b))三个参数(都是函数)第一个参数:给定一个初始值,用函数生成初始值。第二个参数:c…

SecureCRT防止自动断开

今天在宁波连接上海的linux库,是外网访问内网,使用了nat123这个软件映射的。 发现SecureCRT连接后,过几分钟就自动断开,导致使用SecureCRT做跳转机的其他应用使用起来很不方便。 于是设置了下SecureCRT。

AI工程师职业规划和学习路线完整版

AI工程师职业规划和学习路线完整版 如何成为一名机器学习算法工程师 成为一名合格的开发工程师不是一件简单的事情,需要掌握从开发到调试到优化等一系列能 力,这些能力中的每一项掌握起来都需要足够的努力和经验。而要成为一名合格的机器学习算法工程师&…

oracle 多个with as

主要看多个with的格式 [sql] view plaincopy WITH T3 AS ( SELECT T1.ID, T1.CODE1, T2.DESCRIPTION FROM TB_DATA T1, TB_CODE T2 WHERE T1.CODE1 T2.CODE ), T4 AS ( SELECT T1.ID, T1.CODE2, T2.DESCRIPTION FROM TB_DATA T1, TB_CODE T2 WHERE T1.C…

mysql主键 命中率_mysql主键问题

MySQL主键一. MySQL主键设计原则MySQL主键应当是对用户没有意义的。MySQL主键应该是单列的,以便提高连接和筛选操作的效率(当然复合主键是可以的,只是不建议)永远也不要更新MySQL主键MySQL主键不应包含动态变化的数据,如时间戳、创建时间列、…

hadoop SecondNamenode

一、定义 * The Secondary Namenode is a helper to the primary Namenode. * The Secondary is responsible for supporting periodic checkpoints * of the HDFS metadata. The current design allows only one Secondary * Namenode per HDFs cluster. * The Secondary Nam…

高性能mysql 小查询_高性能MySql进化论(十一):常见查询语句的优化

总结一下常见查询语句的优化方式1 COUNT1. COUNT的作用 COUNT(table.filed)统计的该字段非空值的记录行数 COUNT(*)或者是COUNT(not nullable field) 统计的是全表的行数如果要是统计全表记录数,COUNT(*)效率会比COUNT(not nullable fie…

首席架构师徐海峰眼中的架构和出色的架构师

CSDN架构领域编辑采访了一些与会讲师,谈谈他们将在会上分享的内容、相关技术和程序人生,带你领略讲师风采。 本期我们采访的讲师是来自阅文集团首席架构师徐海峰,主要负责内容中心的网站架构和分布式存储、分布式计算工作。10年互联网开发经验…

hadoop-eclipse-plugin使用

下载hadoop安装包:http://www.carfab.com/apachesoftware/hadoop/common/hadoop-1.0.2/ 但是没有plugin,我到这个地方下载的:http://ishare.iask.sina.com.cn/f/23642243.html?fromlikecopy到你的eclipse_home的plugins下面。配置map/reduce…

java 记事本界面_JAVA/GUI程序之记事本

自上半年JAVA课程结束后,再也没有看过JAVA了,最近不是很忙,又简单的看了看,本博客纯属记录学习过程,请大神们别笑,其中错误是难免的,毕竟是新手写的博客。下面就进入我们的正题吧,复…

mapper-reducer word count 实例

统计一个文件里各单词的个数,假设这个文件很大。 原理如下图: 编写代码: WCMapper.java package zengmg.hadoop.mr.wordcount;import java.io.IOException;import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; …

MR程序的几种提交运行模式

MR程序的几种提交运行模式 本地模型运行 1/在windows的eclipse里面直接运行main方法,就会将job提交给本地执行器localjobrunner执行 ----配置path:D:\hadoop-2.7.2\bin ----配置hadoop_home:D:\hadoop-2.7.2 ----复制 hadoop.dll和winutil…

零点起飞学java视频_零点起飞学java (刘升华) 高清PDF_IT教程网

资源名称:零点起飞学java (刘升华) 高清PDF第1篇 java开发基础第1章 java概述( 教学视频:37分钟) 2第2章 基本数据类型及运算( 教学视频:52分钟) 14第3章 java程序流程控制( 教学视频:33分钟) 36第4章 类与对…

vector 修改 java_java对vector动态数组中的对象排序,以下代码有何问题,如何修改?...

展开全部package com.tx.collection;import java.util.Comparator;import java.util.Iterator;import java.util.Map;import java.util.Set;import java.util.TreeMap;import java.util.TreeSet;import java.util.Vector;public class Student {String name;int score;public S…

hadoop的序列化与java的序列化区别

java的序列化机制 java序列化时会把具体类的数据和类的继承结构信息都序列化传递。如下图hadoop的序列化机制 序列化类的数据,但是不序列化类的继承结构信息。 网络传递的时候就少了很多流量,hadoop也不需要类的继承关系,只要类的数据就够…

ORA-08103: object no longer exists

今天工具箱报错: ORA-08103: object no longer exists 查了原因,是有session在操作表,比如插入,更新等。而工具箱这个操作刚好在select表,所以报错。-------下文是英文解释----- ORA-08103: object no longer exists错…

DAY3-“忙里偷闲”找你玩耍2018-1-11

接触Java第三天,嘿嘿,今天近代史期末考试,提前一小时交卷,回宿舍继续学习,中午去见女神姐姐了,每次见完女神姐姐都是满满地动力。这次女神姐姐告诉我们要好好规划自己的时间,早上花20分钟规划好…

基于ssm出租车管理系统的设计与实现论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本出租车管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息&…

Spring Security源码分析四:Spring Social实现微信社交登录

2019独角兽企业重金招聘Python工程师标准>>> 社交登录又称作社会化登录(Social Login),是指网站的用户可以使用腾讯QQ、人人网、开心网、新浪微博、搜狐微博、腾讯微博、淘宝、豆瓣、MSN、Google等社会化媒体账号登录该网站。 前言…