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听说很多人都在用,安装测试中 待续 –

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • jrtplib接收rtcp_qt tcpsocket 接收数据

    jrtplib接收rtcp_qt tcpsocket 接收数据一.前言JRTPLIB是C++语言编写的RTP库,它帮助我们封装了RTP协议细节,用户通过提供好的接口可以设置RTP包信息并发送到指定地址,也可以接收RTP包取出信息。本文仅介绍如何使用JRTPLIB发送/接收RTP数据包,我在这篇博客又介绍了如何使用JRTPLIB构造RTP数据包来荷载H264码流数据。二.下载编译安装gitclonehttps://github.com/j0r1/JRTPLIB.git…

  • Advanced System Care官方下载(附激活码)

    Advanced System Care官方下载(附激活码)iobit公司出品的一款系统辅助工具AdvancedSystemCare,它通过对系统全方位的诊断,找到系统性能的瓶颈所在,并将测试结果显示出来。针对系统的瓶颈对其优化,提高效率发挥最大的性能,通过优化后系统性能和网络速度都会有明显提升包含基本功能,注册表清理,垃圾文件清理等。现今系统清理,系统优化工具满天飞,可是很少有对系统全方位的诊断,找到系统性能的瓶颈所在,然后有针对性地进行修改、优化…

    2022年10月20日
  • Linux中搭建DNS服务器

    Linux中搭建DNS服务器目录DNS域传送漏洞域名空间结构DNS解析过程各种解析记录DNS服务器的安装与部署主从DNS服务器的搭建:转发DNS服务器的配置DNSDNS(DomainNameService)域名解析服务,就是将域名和ip之间做相应的转换,利用TCP和UDP的53号端口DNS系统作用:正向解析:根据域名查找对应的ip地址 反向解析:根据ip地址查…

  • touch-screen_FloatingActionButton

    touch-screen_FloatingActionButton在做练习时,触控失灵,看源码后fanx直接在init

  • Python 100道基础入门练习题(附答案)

    Python 100道基础入门练习题(附答案)实例001:数字组合题目有四个数字:1、2、3、4,能组成多少个互不相同且无重复数字的三位数?各是多少?程序分析遍历全部可能,把有重复的剃掉。1num=02forainrange(1,5):3forbinrange(1,5):4forcinrange(1,5):5if((a!=b)and(a!=c)and(b!=c)):6print(a,b,c)7nu

  • matlab 矩阵除法

    matlab 矩阵除法Matlab提供了两种除法运算:左除(/)和右除(/)。一般情况下,x=a/b是方程a*x=b的解,而x=b/a是方程x*a=b的解。例:a=[1  2  3;4  2  6;7  4  9]b=[4;1;2];x=a/b则显示:x=      -1.5000        2.0000        0.5000如果a为非奇异矩阵,则a/b和b/a可通过a的逆矩阵与

发表回复

您的电子邮箱地址不会被公开。

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