sphinx全文检索 安装配置和使用

sphinx全文检索 安装配置和使用

https://www.cnblogs.com/findgor/p/5644540.html

 

公司项目刚刚导入大量产品数据,然后发现网站的产品搜索很卡,原本是原生sql的like来做模糊搜索,数据量20W的时候还可以接受,但是上百万就很卡了,所以需要做优化。

经过考虑,打算采用全文检索 sphinx + 数据库中间件(atlas/mycat) 的架构来优化.

我的环境:

centos6.5 64位

lnmp1.3一键环境包

sphinx全文检索 安装配置和使用

 

CentOS6.4 X64 安装sphinx及sphinx for php扩展

安装前请先确定安装了常用的组件,然后在官方网站下载最新的sphinx,

yum install -y python python-devel

http://sphinxsearch.com/downloads/release/

安装sphinx

tar zxvf sphinx-2.2.10-release.tar.gz
cd sphinx-2.2.10-release
./configure --prefix=/usr/local/sphinx –-with-mysql
make && make install

在make时如果出现undefined reference to libiconv的错,请参考 http://www.lvtao.net/database/sphinx-make-error.html 解决方法
libsphinxclient 安装(PHP模块需要)

cd api/libsphinxclient
./configure –prefix=/usr/local/sphinx
make &&  make install

安装PHP的Sphinx模块
下载地址:http://pecl.php.net/package/sphinx

wget http://pecl.php.net/get/sphinx-1.3.0.tgz
tar zxf sphinx-1.3.3.tgz
cd sphinx-1.3.3
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config --with-sphinx=/usr/local/sphinx/
make && make install

添加php扩展库
查看php.ini位置
php --ini

sphinx全文检索 安装配置和使用


编辑配置
vi /usr/local/php/etc/php.ini
:$ 跳至文件尾部

extension_dir=”/usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/”
[sphinx]
extension=sphinx.so

php -m 或者 phpinfo() 查看是否已经加载扩展

sphinx全文检索 安装配置和使用

首先我们得在服务器端把索引建立好,以便php通过端口访问获取

复制默认配置文件,重新创建一个配置文件

cp /usr/local/sphinx/etc/sphinx-min.conf.dist  /usr/local/sphinx/etc/sphinx.conf

sphinx全文检索 安装配置和使用

sphinx.conf.dist是完整版默认配置,有很多内容,我这里选择复制的是sphinx-min.conf.dist迷你版,只要满足基本查询需要即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#
# Minimal Sphinx configuration sample (clean, simple, functional)
#
 
source src1
{
        
type                   
=
mysql
 
        
sql_host               
=
localhost
        
sql_user               
=
root
        
sql_pass               
=
root
        
sql_db                 
=
allchips_test
        
sql_port               
=
3306 
# optional, default is 3306
 
        
sql_query              
=
select
*
from
products
 
        
#sql_attr_uint          = id
        
#sql_attr_timestamp     = date_added
 
        
sql_field_string       
=
product_id
        
sql_field_string       
=
partNo
}
 
source src2
{
        
type                   
=
mysql
 
        
sql_host               
=
localhost
        
sql_user               
=
root
        
sql_pass               
=
root
        
sql_db                 
=
allchips_test
        
sql_port               
=
3306 
# optional, default is 3306
 
        
sql_query              
=
select
*
from
product_prices
 
 
}
 
source src3
{
        
type                   
=
mysql
 
        
sql_host               
=
localhost
        
sql_user               
=
root
        
sql_pass               
=
root
        
sql_db                 
=
allchips_test
        
sql_port               
=
3306 
# optional, default is 3306
 
        
sql_query              
=
select
*
from
product_attrs
 
}
 
 
 
index products
{
        
source                 
=
src1
        
path                   
=
/
mnt
/
data
/
products
        
min_infix_len
=
1
        
infix_fields
=
partNo,short_desc
 
}
 
 
index prices
{
        
source                 
=
src2
        
path                   
=
/
mnt
/
data
/
prices
 
}
 
index attrs
{
        
source                 
=
src3
        
path                   
=
/
mnt
/
data
/
attrs
 
}
 
 
indexer
{
        
mem_limit              
=
128M
}
 
 
searchd
{
        
listen                 
=
9312
        
listen                 
=
9306
:mysql41
        
log                    
=
/
mnt
/
data
/
log
/
searchd.log
        
query_log              
=
/
mnt
/
data
/
log
/
query.log
        
read_timeout           
=
5
        
max_children           
=
30
        
pid_file               
=
/
mnt
/
data
/
log
/
searchd.pid
        
seamless_rotate        
=
1
        
preopen_indexes        
=
1
        
unlink_old             
=
1
        
workers                
=
threads
# for RT to work
        
binlog_path            
=
/
mnt
/
data
}

  

最下面的indexer和searchd分别是索引创建,和查询命令的配置,基本只要设置好自己想要日志路径即可

重要的上面的部分,source (来源) 和 index (索引)

分析一下我的需求,我的产品搜索主要3张表

产品表products, (id,product_id)

产品价格表product_prices, 

产品参数表product_attrs

三者以产品表的product_id关联1对多

source src1 对应  index products

source src2 对应  index prices

source src3 对应  index attrs

在source中是可以设置自定义返回的字段的

如上面的
sql_field_string = product_id
sql_field_string = partNo

配置好了之后,创建索引

在使用  /usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf  –all –rotate 命令的的时候,如果searchd进程没有在监听,执行了更新,会出现no rotate的提示。

如果不想全部生成你可以不用–all,分开多个源生成也可以

sphinx全文检索 安装配置和使用

/usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf  products

/usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf  prices

/usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf  attrs

如果没有什么问题一般是这样的。

sphinx全文检索 安装配置和使用

接下来要用searchd作为sphinx在服务器的守护进程

/usr/local/sphinx/bin/searchd -c /usr/local/sphinx/etc/sphinx.conf(途中的test.conf是以前测试的,使用sphinx.conf即可)

 sphinx全文检索 安装配置和使用

一般如果报错

文件夹不存在,则创建文件夹

如果已经端口进程已经在运行,那么有2种方法停止

1,/usr/local/sphinx/bin/searchd -c /usr/local/sphinx/etc/sphinx.conf –stop

2, netstat -tnl 查看端口9312是否在监听

lsof -i:9312  查看9312端口信息,获得pid

kill {pid}

杀掉进程之后重新执行searchd命令启动

==========

php端

 

复制代码
<?php
    //index.php phpinfo();die; $s = new SphinxClient; $s->setServer("127.0.0.1", 9312); $s->setMatchMode(SPH_MATCH_PHRASE);
  
  

  

//$s->setSortMode(SPH_SORT_ATTR_DESC,’is_tuan’); //指定模式
$s->setSortMode(SPH_SORT_EXTENDED,’is_tuan desc’); //扩展模式

$s->SetFilterString(‘status’,’1′); //这个字段 需要在 sql_attr_string 中设置显示,不然找不到字段  如果设置的是sql_attr_uint就是int ,后面是类型


$s->setMaxQueryTime(30); $res1 = $s->query('usb','products'); $res2 = $s->query('53e6dde17a667c4b2af1d38ba0a466c4','prices'); $res3 = $s->query('53e6dde17a667c4b2af1d38ba0a466c4','attrs'); //$res = $s->query('开关','products'); //$res = $s->query('products'); $err = $s->GetLastError(); //var_dump(array_keys($res['matches'])); // echo "<br>"."通过获取的ID来读取数据库中的值即可。"."<br>"; echo '<pre>'; $products=!empty($res1['matches'])?$res1['matches']:""; $prices=!empty($res2['matches'])?$res2['matches']:""; $attrs=!empty($res3['matches'])?$res3['matches']:""; print_r($products); print_r($prices); print_r($attrs); if(!empty($err)){ print_r($err); } $s->close();
复制代码

coreseek的官网挂了下载不了,所以暂时不弄中文。以后看有时间在下载个中文词典打进去

sphinx全文检索 安装配置和使用

 

 这是打印的query返回的matches匹配结果,如果要查看整个query结果,可以看PHP手册http://php.net/manual/zh/sphinxclient.query.php

返回数据结构
值说明
“matches” 存储文档ID以及其对应的另一个包含文档权重和属性值的hash表
“total” 此查询在服务器检索所得的匹配文档总数(即服务器端结果集的大小,且与相关设置有关)
“total_found” (服务器上找到和处理了的)索引中匹配文档的总数
“words” 将查询关键字(关键字已经过大小写转换,取词干和其他处理)映射到一个包含关于关键字的统计数据(“docs”——在多少文档中出现,“hits”——共出现了多少次)的小hash表上。
“error” searchd报告的错误信息
“warning” searchd报告的警告信息

上面的配置默认监听了,9312和9306端口,9312是给php程序链接的,9306是本地数据库调试端口,如果想要在服务器做测试,可以试试链接

mysql -h127.0.0.1 -P9306

 sphinx全文检索 安装配置和使用

products是索引名index,match是规则匹配,

通配符可以在官网手册上 
http://sphinxsearch.com/docs/current.html#conf-dict  搜索”wildcards” 
 看到 search (e.g. “t?st*”, “run%”, “*abc*”)
 
我在使用时,发现关键字分词不准确,比如 完整产品信号 PSMN1R1-25YLC,115 
 
PSMN1R1-25YLC,115   true
PSMN1R1-25YLC,11   false
PSMN1R1-25YLC,1   false
PSMN1R1-25YLC,   true
PSMN1R1-25YLC  true
 
由此可以判断,应该是字符分词长度设置有问题,解决如下
source中
sql_query_pre = SET NAMES utf8    #sql执行前,会执行,为了保证不是字符集的问题
index中
min_prefix_len = 1    #设置最小索引前缀长度1
 
php中:
复制代码
use sngrl\SphinxSearch\SphinxSearch; class TestController extends Controller { public function index(Request $request) { $sphinx = new SphinxSearch(); $sphinx->setMatchMode(\Sphinx\SphinxClient::SPH_MATCH_PHRASE); $results = $sphinx->search("%PSMN1R1-25YLC,11*", 'products')->query(); $error=$sphinx->getErrorMessage(); $products=!empty($results['matches']) ? $results['matches'] : array(); echo '<pre>'; print_r($products); //dd($results); //dd($error);  } }
复制代码

匹配成功。

 

 
 
 
使用中会遇到的问题:
1,索引更新,可以使用rt增量索引来记录变化的记录id
2,定时更新索引
如果searchd进程正在运行,你除了可以kill掉他的进程外,还可以执行–rotate 参数进行 无缝更新,无需重启服务
/usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf  products –rotate
你可以把这个命令 写入crontab任务中,定时执行,在laravel中你可以在程序中自定义。

 ================================================================

Atlas听说很多人都在用,安装测试中 待续 –

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/113348.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • spring boot拦截器和过滤器_java拦截器的作用

    spring boot拦截器和过滤器_java拦截器的作用SpringMVC中有两种很普遍的AOP实现:1.过滤器(Filter)2.拦截器(Interceptor)首先说一下两者之间的区别:过滤器和拦截器非常相似,但是它们有很大的区别a.最简单明了的区别就是过滤器可以修改request,而拦截器不能b.过滤器需要在servlet容器中实现,拦截器可以适用于javaEE,javaSE等各种环境c.拦截器可以调用IOC容器中的各种依赖,而过滤器不能d.过滤器只能在请求的前后使用,而拦截器可以详细到每个方法一、HandlerInterc

    2022年8月23日
    4
  • 列存储索引1:初识列存储索引

    列存储索引1:初识列存储索引

    2021年11月24日
    38
  • check the manual that corresponds to your MySQL server version for the right syntax to use near

    check the manual that corresponds to your MySQL server version for the right syntax to use near

    2021年7月15日
    81
  • 基于粒子群优化算法的函数寻优算法研究_matlab粒子群优化算法

    基于粒子群优化算法的函数寻优算法研究_matlab粒子群优化算法一、理论基础粒子群算法(particleswarmoptimization,PSO)是计算智能领域一种群体智能的优化算法。该算法最早由Kennedy和Eberhart在1995年提出的。PSO算法源于对鸟类捕食行为的研究,鸟类捕食时,找到食物最简单有效的策略就是搜寻当前距离食物最近的鸟的周围区域。PSO算法就是从这种生物种群行为特征中得到启发并用于求解优化问题的,算法中每个粒子都代表问题的一个潜在解,每个粒子对应一个由适应度函数决定的适应度值。粒子的速度决定了粒子移动的方向和距离,速度随自身及其他粒子

    2022年10月11日
    0
  • 记录 vue-cli3 配置uat环境 遇到的打包问题[通俗易懂]

    记录 vue-cli3 配置uat环境 遇到的打包问题[通俗易懂]今天给前端页面配置一个新的可供切换的环境UAT:修改package.json的scripts:”scripts”:{“serve”:”vue-cli-serviceserve”,”build”:”vue-cli-servicebuild”,”build:uat”:”vue-cli-servicebuild–modeuat”,…

    2022年9月28日
    0
  • python中%d_python中%d是什么「建议收藏」

    python中%d表示格式化一个对象为十进制整数。使用后,在需要输出的长字符串中占位置。输出字符串时,可以依据变量的值,自动更新字符串的内容。使用示例:num=14#%d打印时结果是14print(“num=%d”%num)#output:num=14#%1d意思是打印结果为1位整数,当整数的位数超过1位时,按整数原值打印,所以%1d的打印结果还是14print(“nu…

    2022年4月10日
    2.1K

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号