记录在此,作为分享,也作为自己的存档。
不要用原生Sphinx,因为中文支持不好。要用sphinx-for-chinese,数据库编码要用utf-8,既能很好的受sphinx支持,又符合php规范。
git clone https://github.com/eric1688/sphinx
cd sphinx
./configure --prefix=/usr/local/sphinx --with-mysql
make & make install
/usr/local/sphinx/bin/mkdict xdict_1.1.txt xdict
xdict生成完成显示:
Preparing...
Making Chinese dictionary: 100% |******************************|
Total words: 284757
File size: 2854912 bytes
Compression ratio: 100 %
Chinese dictionary was successfully created!
cp xdict /usr/local/sphinx/etc/
cd /usr/local/sphinx/etc/
cp sphinx.conf.dist sphinx.conf
vim sphinx.conf
配置文件参考网上一个人写的吧,搬来:
# sphinx基本配置
# 索引源
source goods_src
{
# 数据库类型
type = mysql
# MySQL主机IP
sql_host = localhost
# MySQL用户名
sql_user = sphinxuser
# MySQL密码
sql_pass = sphinxpass
# MySQL数据库
sql_db = sphinx
# MySQL端口(如果防火墙有限制,请开启)
sql_port= 3306
# MySQL sock文件设置(默认为/tmp/mysql.sock,如果不一样,请指定)
sql_sock = /tmp/mysql.sock
# MySQL检索编码(数据库非utf8的很可能检索不到)
sql_query_pre = SET NAMES UTF8
# 获取数据的SQL语句
sql_query = SELECT goods_id,goods_id AS goods_id_new,goods_name,goods_color,goods_name AS goods_name_search,goods_color AS goods_color_search From goods_test
# 以下是用来过滤或条件查询的属性(以下字段显示在查询结果中,不在下面的字段就是搜索时要搜索的字段,如SQL语句中的goods_color_search,goods_name_search)
# 无符号整型
#goods_id为主键,如果加在这里在生成索引的时候会报attribute 'goods_id' not found,这里用goods_id_new来变通
sql_attr_uint = goods_id_new
# 字符串类型
sql_attr_string = goods_name
sql_attr_string = goods_color
# 用于命令界面端(CLI)调用的测试(一般来说不需要)
#sql_query_info = SELECT * FROM goods_test Where goods_id = $goods_id;
}
# 索引
index goods
{
# 索引源声明
source = goods_src
# 索引文件的存放位置
path = /usr/local/sphinx/var/data/goods
# 文件存储模式(默认为extern)
docinfo = extern
# 缓存数据内存锁定
mlock = 0
# 马氏形态学(对中文无效)
morphology = none
# 索引词最小长度
min_word_len = 1
# 数据编码(设置成utf8才能索引中文)
charset_type = utf-8
# 中文分词词典
chinese_dictionary = /usr/local/sphinx/etc/xdict
# 最小索引前缀长度
min_prefix_len = 0
# 最小索引中缀长度
min_infix_len = 1
# 对于非字母型数据的长度切割(for CJK indexing)
ngram_len = 1
# 对否对去除用户输入查询内容的html标签
html_strip = 0
}
# 索引器设置
indexer
{
# 内存大小限制 默认是 32M, 最大 2047M, 推荐为 256M 到 1024M之间
mem_limit = 256M
}
# sphinx服务进程search的相关配置
searchd
{
# 监测端口及形式,一下几种均可,默认为本机9312端口
# listen = 127.0.0.1
# listen = 192.168.0.1:9312
# listen = 9312
# listen = /var/run/searchd.sock
# search进程的日志路径
log = /usr/local/sphinx/var/log/searchd.log
# 查询日志地址
query_log = /usr/local/sphinx/var/log/query.log
# 读取超时时间
read_timeout = 5
# 请求超时市时间
client_timeout = 300
# searche进程的最大运行数
max_children = 30
# 进程ID文件
pid_file = /usr/local/sphinx/var/log/searchd.pid
# 最大的查询结果返回数
max_matches = 1000
# 是否支持无缝切换(做增量索引时需要)
seamless_rotate = 1
# 在启动运行时是否提前加载所有索引文件
preopen_indexes = 0
# 是否释放旧的索引文件
unlink_old = 1
# MVA跟新池大小(默认为1M)
mva_updates_pool = 1M
# 最大允许的网络包大小(默认8M)
max_packet_size = 8M
# 每个查询最大允许的过滤器数量(默认256)
max_filters = 256
#每个过滤器最大允许的值的个数(默认4096)
max_filter_values = 4096
# 每个组的最大查询数(默认为32)
max_batch_queries = 32
}
# Sphinx配置文件结束
/usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf goods
/usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf --all
/usr/local/sphinx/bin/searchd -c /usr/local/sphinx/etc/sphinx.conf
如果重建索引时守护进程正在运行,需要运行下面的指令,会重建索引并且重开守护进程
/usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf --all --rotate
ufw disable
<?php
include_once(LIBRARY_PATH ."/sphinxapi.php");
class Model_SphinxClient extends SphinxClient {
protected static $_instance = null;
public static function instance(){
if(self::$_instance == null){
self::$_instance = new self();
self::$_instance->SetServer('127.0.0.1',9312);
self::$_instance->SetConnectTimeout(3);
self::$_instance->SetMaxQueryTime(2000);
}
return self::$_instance;
}
}
$sphinx = Model_SphinxClient::instance();
//...//排序
//...//分页
//...//筛选等
$data = $sphinx->Query($keywords,$indexName);
//拿到$data里的id后,再到数据库查数据
其余sphinx具体操作(最基本的排序、筛选、分页): 详细的见官方文档:http://sphinxsearch.com/docs/current.html
配置文件里面设置
sql_attr_float = price
然后php:
$sphinx->SetSortMode (SPH_SORT_ATTR_DESC,price);//相当于sql 的 order by price desc
$sphinx->SetSortMode (SPH_SORT_ATTR_ASC,price);//相当于sql 的 order by price asc
配置文件里面设置
sql_attr_uint = weight
$sphinx->SetFilterRange("weight",42,50);//筛选42kg到50kg之间的姑娘
按罩杯筛选姑娘:筛选2
配置文件sql_query 的 select里面 记得 CRC32(cup) as cup
sql_attr_uint = cup
$sphinx->SetFilter("cup",array(crc32('B'),crc32('C')));//筛选出罩杯B或者C的
$sphinx->SetFilter("cup",array(crc32('C')));//只要C罩杯的
$sphinx->SetLimits($offset,$limit);//总数见查询结果total_found
容易犯的错误记录:
排序:官方文档说了“不要将匹配模式常量放到引号里面”,那样会导致排序失效!
WARNING: (PHP specific) you must not take the matching mode constant name in quotes, that syntax specifies a string and is incorrect:
$cl->SetSortMode ( "SPH_SORT_ATTR_DESC" ); // INCORRECT! will not work as expected
$cl->SetSortMode ( SPH_SORT_ATTR_ASC ); // correct, works OK