在java环境中使用sphinx搜索引擎
2017-08-15 11:30
260 查看
项目中遇到两个千万数量级的表相关联的情况,join之后加上检索条件,检索的很慢,所以选择使用sphinx搜索引擎来提高检索效率。
我使用的是2.32版本的sphinx,如何部署和配置就不赘述了,网上都可以查到很详细的教程,主要来谈谈在java环境下的使用。
sphinx的文档中写了是对java支持的,但只是寥寥几句带过,文档中的示例也都是用的PHP。下载好sphinx的压缩包,解压出来可以找到其中对java的接口,有这样几个:
SphinxClient.java
SphinxException.java
SphinxMatch.java
SphinxResult.java
SphinxWordInfo.java
这几个类很久没有更新了,添加到项目中凑合着用吧。
具体使用:
1. 创建一个SphinxClient
2. 配置SphinxClient
设置匹配模式
匹配模式有一下几种:
SPH_MATCH_ALL, 匹配所有查询词(默认模式);
SPH_MATCH_ANY, 匹配查询词中的任意一个;
SPH_MATCH_PHRASE, 将整个查询看作一个词组,要求按顺序完整匹配;
SPH_MATCH_BOOLEAN, 将查询看作一个布尔表达式 ;
SPH_MATCH_EXTENDED, 将查询看作一个Sphinx内部查询语言的表达式。这个选项被选项SPH_MATCH_EXTENDED2代替,它提供了更多功能和更佳的性能。保留这个选项是为了与遗留的旧代码兼容——这样即使Sphinx及其组件包括API升级的时候,旧的应用程序代码还能够继续工作。
SPH_MATCH_EXTENDED2, 使用第二版的“扩展匹配模式”对查询进行匹配;
SPH_MATCH_FULLSCAN, 强制使用下文所述的“完整扫描”模式来对查询进行匹配。注意,在此模式下,所有的查询词都被忽略,尽管过滤器、过滤器范围以及分组仍然起作用,但任何文本匹配都不会发生;
设置分页查询的范围
sphinx的分页查询有四个参数:
offset、limit、max、cutoff
offset和limit定义获取数据的偏移量和数量,类似mysql中的limit
max对应max_matches参数,是控制最终返回的索引结果的最大数量,例如定义offset为0,limit为1000,max为100,这样sphinx会先检索出1000条数据,再按照排序和过滤条件倒序取出前100条。注意:这个参数可以在每次的请求中设置, 也可以在sphinx的配置文件中设置, 后者的优先级高一些, 即每次请求中的max_matches 不能高于sphinx 配置文件中的max_matches!
cutoff 也是控制最终返回的索引结果的最大数量,与max_matches 不同的是,max_matches是先排序和过滤再倒序取出max_matches 条数据,而cutoff是从第一个数据开始截取cutoff条数据然后过滤和排序后返回数据。注意,sphinx在处理时cutoff优先级大于max_matches,虽然cutoff性能更高,但是容易导致搜索结果不够优,建议不使用。
offset、limit是必传参数,max和cutoff是选传参数,不传入的话max默认为1000,cutoff为0。
设置排序模式
sphinx有这几种排序模式:
SPH_SORT_RELEVANCE 模式, 按相关度降序排列(最好的匹配排在最前面)
SPH_SORT_ATTR_DESC 模式, 按属性降序排列 (属性值越大的越是排在前面)
SPH_SORT_ATTR_ASC 模式, 按属性升序排列(属性值越小的越是排在前面)
SPH_SORT_TIME_SEGMENTS 模式, 先按时间段(最近一小时/天/周/月)降序,再按相关度降序
SPH_SORT_EXTENDED 模式, 按一种类似SQL的方式将列组合起来,升序或降序排列。
SPH_SORT_EXPR 模式,按某个算术表达式排序。
如果不设置的话默认为SPH_SORT_RELEVANCE
设置过滤
使用sphinxClient.SetFilter(String attribute, int value, boolean exclude)方法设置过滤,
attribute为要过滤的字段,这个字段的数据类型需要是数字型,在sphinx配置文件中要设置为sql_attr_*,例如:sql_attr_bigint = label_status
value为过滤的值,这里可以使用整型和long型的数字和数组
exclude为true时正向过滤,为false时反向过滤,即为true时过滤掉值=value的数据保留值!=value的数据,为false过滤掉值!=value的数据保留值=value的数据,千万不要用反了
也可以使用SetFilterRange设置范围区间过滤,使用方法类似SetFilter
3.检索方法
配置完sphinxClient后,使用sphinxClient.Query(String query, String index)方法进行检索
不同的匹配模式对应的query语句写法不同,这里介绍SPH_MATCH_EXTENDED2(扩展匹配模式)的query语句写法
在扩展查询模式中可以使用如下特殊操作符:
或(OR)操作符:hello | world
非(NOT)操作符:hello -world hello !world
字段(field)搜索符:@title hello @body world
字段限位修饰符(版本Coreseek 3/Sphinx 0.9.9-rc1中引入):@body[50] hello
多字段搜索符:@(title,body) hello world
全字段搜索符:@* hello
词组搜索符:”hello world”
近似搜索符:”hello world”~10
阀值匹配符:”the world is a wonderful place”/3
严格有序搜索符(即“在前”搜索符):aaa << bbb << ccc
严格形式修饰符(版本Coreseek 3/Sphinx 0.9.9-rc1中引入):raining =cats and =dogs
字段开始和字段结束修饰符 (版本Coreseek 3.1/Sphinx 0.9.9-rc2中引入):^hello world$
一个检索条件对应多个值时,使用 | 拼接,例如
多个检索条件之间使用&拼接,例如
index为检索要使用的索引名,对应sphinx配置中的索引名,多个索引直接以 | 隔开,例如
4.结果处理
遍历sphinxResult中的matches即可得到我们想要的数据
我使用的是2.32版本的sphinx,如何部署和配置就不赘述了,网上都可以查到很详细的教程,主要来谈谈在java环境下的使用。
sphinx的文档中写了是对java支持的,但只是寥寥几句带过,文档中的示例也都是用的PHP。下载好sphinx的压缩包,解压出来可以找到其中对java的接口,有这样几个:
SphinxClient.java
SphinxException.java
SphinxMatch.java
SphinxResult.java
SphinxWordInfo.java
这几个类很久没有更新了,添加到项目中凑合着用吧。
具体使用:
1. 创建一个SphinxClient
String sphinxHost = "localhost"; int sphinxPort = 9312; SphinxClient sphinxClient = new SphinxClient(sphinxHost, sphinxPort);
2. 配置SphinxClient
设置匹配模式
匹配模式有一下几种:
SPH_MATCH_ALL, 匹配所有查询词(默认模式);
SPH_MATCH_ANY, 匹配查询词中的任意一个;
SPH_MATCH_PHRASE, 将整个查询看作一个词组,要求按顺序完整匹配;
SPH_MATCH_BOOLEAN, 将查询看作一个布尔表达式 ;
SPH_MATCH_EXTENDED, 将查询看作一个Sphinx内部查询语言的表达式。这个选项被选项SPH_MATCH_EXTENDED2代替,它提供了更多功能和更佳的性能。保留这个选项是为了与遗留的旧代码兼容——这样即使Sphinx及其组件包括API升级的时候,旧的应用程序代码还能够继续工作。
SPH_MATCH_EXTENDED2, 使用第二版的“扩展匹配模式”对查询进行匹配;
SPH_MATCH_FULLSCAN, 强制使用下文所述的“完整扫描”模式来对查询进行匹配。注意,在此模式下,所有的查询词都被忽略,尽管过滤器、过滤器范围以及分组仍然起作用,但任何文本匹配都不会发生;
// 如果不设置的话,默认也是SPH_MATCH_EXTENDED2模式 sphinxClient.SetMatchMode(SphinxClient.SPH_MATCH_EXTENDED2);
设置分页查询的范围
sphinx的分页查询有四个参数:
offset、limit、max、cutoff
offset和limit定义获取数据的偏移量和数量,类似mysql中的limit
max对应max_matches参数,是控制最终返回的索引结果的最大数量,例如定义offset为0,limit为1000,max为100,这样sphinx会先检索出1000条数据,再按照排序和过滤条件倒序取出前100条。注意:这个参数可以在每次的请求中设置, 也可以在sphinx的配置文件中设置, 后者的优先级高一些, 即每次请求中的max_matches 不能高于sphinx 配置文件中的max_matches!
cutoff 也是控制最终返回的索引结果的最大数量,与max_matches 不同的是,max_matches是先排序和过滤再倒序取出max_matches 条数据,而cutoff是从第一个数据开始截取cutoff条数据然后过滤和排序后返回数据。注意,sphinx在处理时cutoff优先级大于max_matches,虽然cutoff性能更高,但是容易导致搜索结果不够优,建议不使用。
offset、limit是必传参数,max和cutoff是选传参数,不传入的话max默认为1000,cutoff为0。
sphinxClient.SetLimits SetLimits( int offset, int limit, int max, int cutoff );
设置排序模式
sphinx有这几种排序模式:
SPH_SORT_RELEVANCE 模式, 按相关度降序排列(最好的匹配排在最前面)
SPH_SORT_ATTR_DESC 模式, 按属性降序排列 (属性值越大的越是排在前面)
SPH_SORT_ATTR_ASC 模式, 按属性升序排列(属性值越小的越是排在前面)
SPH_SORT_TIME_SEGMENTS 模式, 先按时间段(最近一小时/天/周/月)降序,再按相关度降序
SPH_SORT_EXTENDED 模式, 按一种类似SQL的方式将列组合起来,升序或降序排列。
SPH_SORT_EXPR 模式,按某个算术表达式排序。
如果不设置的话默认为SPH_SORT_RELEVANCE
sphinxClient.SetSortMode(SphinxClient.SPH_SORT_ATTR_DESC, "gmt_modified");
设置过滤
使用sphinxClient.SetFilter(String attribute, int value, boolean exclude)方法设置过滤,
attribute为要过滤的字段,这个字段的数据类型需要是数字型,在sphinx配置文件中要设置为sql_attr_*,例如:sql_attr_bigint = label_status
value为过滤的值,这里可以使用整型和long型的数字和数组
exclude为true时正向过滤,为false时反向过滤,即为true时过滤掉值=value的数据保留值!=value的数据,为false过滤掉值!=value的数据保留值=value的数据,千万不要用反了
// 等价于sql语句 where label_status= 94a8 0 sphinxClient.SetFilter("label_status", 0, false);
也可以使用SetFilterRange设置范围区间过滤,使用方法类似SetFilter
// 等价于sql语句 where label_status>0 and label_status<3 sphinxClient.SetFilterRange("label_status", 0, 3, false);
3.检索方法
配置完sphinxClient后,使用sphinxClient.Query(String query, String index)方法进行检索
不同的匹配模式对应的query语句写法不同,这里介绍SPH_MATCH_EXTENDED2(扩展匹配模式)的query语句写法
在扩展查询模式中可以使用如下特殊操作符:
或(OR)操作符:hello | world
非(NOT)操作符:hello -world hello !world
字段(field)搜索符:@title hello @body world
字段限位修饰符(版本Coreseek 3/Sphinx 0.9.9-rc1中引入):@body[50] hello
多字段搜索符:@(title,body) hello world
全字段搜索符:@* hello
词组搜索符:”hello world”
近似搜索符:”hello world”~10
阀值匹配符:”the world is a wonderful place”/3
严格有序搜索符(即“在前”搜索符):aaa << bbb << ccc
严格形式修饰符(版本Coreseek 3/Sphinx 0.9.9-rc1中引入):raining =cats and =dogs
字段开始和字段结束修饰符 (版本Coreseek 3.1/Sphinx 0.9.9-rc2中引入):^hello world$
一个检索条件对应多个值时,使用 | 拼接,例如
query="(@position=M|E|S)";
多个检索条件之间使用&拼接,例如
query="(@vocabulary=\"^左侧$\")&(@property=P)&(@position=M|E|S)";
index为检索要使用的索引名,对应sphinx配置中的索引名,多个索引直接以 | 隔开,例如
SphinxResult sphinxResult = sphinxClient.Query("(@vocabulary=\"^左侧$\")&(@property=P)&(@position=M|E|S)","index1|index2");
4.结果处理
遍历sphinxResult中的matches即可得到我们想要的数据
for (SphinxMatch m : sphinxResult.getMatches()) { String s1=m.getAttrValues().get(0); String s2=m.getAttrValues().get(1); ... }
相关文章推荐
- 燃烧的远征java(二)-开发环境:Eclipse插件系列——SQLExplorer插件的安装和使用
- 使用 Java 开源工具建立一个灵活的搜索引擎
- JAVA使用到的一些环境变量,Tomcat,Junit,Ant
- 使用开源项目JExcelApi在Java环境中生成MS Excel文档
- 使用 Java 开源工具建立一个灵活的搜索引擎
- 使用Java Excel API (JXL)在Java环境下操作Excel
- 开发接触Java并使用BEA WebLogic 环境开发
- 使用VirtualBox安装Ubuntu9.10,搭建java开发环境总结
- 使用EditPlus配置Java编译环境
- Flex与服务器交互之四(使用RemoteObject +BlazeDS+TomCat同Java交互及开发环境配置)
- 安装使用Java开发环境
- 在Java环境中使用OpenSCADA的utgard子项目连接OPCserver
- java开发环境eclipse的使用(模块代码折叠、可视化开发插件、生成Jar插件)
- .NET程序员也用JAVA:使用BlazeDS,SpringFramework,MySql,Flex构建RIA应用 part 1 :环境搭建.
- Windows下使用批处理自动设置Java环境
- 使用批处理注册Java环境变量--很好用
- 使用EditPlus配置Java编译环境
- JAVA环境使用正则表达式处理字符串
- 燃烧的远征java(二)-开发环境:eclipse 的使用技巧收集
- 使用 Java 开源工具建立一个灵活的搜索引擎