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)


相关推荐

  • 国内不错的激活成功教程软件网站!

    国内不错的激活成功教程软件网站!无忧软件网-[url]http://www.51soft.com/[/url]精品软件秀-http://www.ohsoft.com/163软件园-http://www.soft163.com/中华激活成功教程联盟-http://www.softsdown.com/软件万花筒-http://www.superdown.com/番外地工作室-http://fwd.y…

  • java用正则表达式大全_Java 正则表达式 大全「建议收藏」

    java用正则表达式大全_Java 正则表达式 大全「建议收藏」什么是正则表达式?正则表达式的定义:这是一种字符串的语法规则,是一种可以用于模式匹配和替换的规则,主要用于文本和字符串的处理(匹配,查找,替换,判断字符串)。一个正则表达式是由普通的字符(a~z)以及特殊字符(元字符)组成的文字模式,用以描述在查找文字主体时待匹配的一个或多个字符串。下面我们会介绍一些常用的元字符正则表达式的元字符元字符的定义:元字符:元字符使得正则表达式具有处理能力,指的是那些在…

  • Tomcat问题集锦

    Tomcat问题集锦Tomcat问题集锦

  • vim常用命令总结[通俗易懂]

    vim常用命令总结[通俗易懂]先说明下,本文参考:https://www.cnblogs.com/yangjig/p/6014198.html总结的很好,话不多说,先上图在命令状态下对当前行用==(连按=两次),或对多行用

  • sqlserver不存在或拒绝访问怎么办_sql数据库连接不上

    sqlserver不存在或拒绝访问怎么办_sql数据库连接不上Navicat连接SQLserver数据库时报错:未发现数据源名称并且未指定默认驱动程序导致原因:navicat没有安装sqlserver驱动解决办法:打开Navicat的安装路径,Navicat自带sqlncli_x64.msi,双击安装一下;安装完成之后重启Navicat即可连接成功!…

  • C#构造函数的作用_以下程序段的作用是inta

    C#构造函数的作用_以下程序段的作用是inta构造函数是一种特殊的成员函数,它主要用于为对象分配存储空间,对数据成员进行初始化(1)构造函数的名字必须与类同名;(2)构造函数没有返回类型,它可以带参数,也可以不带参数;(3)构造函数的主要作用是完成对类的初始化工作;(4)在创建一个类的新对象(使用new关键字)时,系统会自动调用给类的构造函数初始化新对象;C#的类有两种构造函数:实例构造函数和静态构造函数实例构造函数:

发表回复

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

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