本文最后更新于100 天前,其中的信息可能已经过时,如有错误请发送邮件到sherry.rain@qq.com
前言
最近在项目中遇到一个困扰我蛮久的一个问题,使用Lucene8做一个全文检索的一个功能。在实际业务中用户想要类似知网的高级查询,由于这个模块项目的v1中有对应代码,需要我进行更改,但老项目的高级搜索只是根据一个字符串类型字段查询的,跟现在的需求匹配不上,所以我自己看了一下官方文档,研究了一下,在这里记录一下。
建立索引
建立索引的具体方法,以及自定义的vo由于代码保密,这里就不能放出来展示了。
主要是操作Document对象建立索引的文档对象,大家可以网上搜索一下。
字符串
字符串类型建立索引的话使用默认的Field就可以了:
Field title = new TextField("title", Jsoup.clean(luceneVo.getVo_title(), Whitelist.none()), Field.Store.YES);
数字
数字需要范围查询,不能使用默认的Field。根据不同的数据类型,使用不同的Field
整型
IntPoint intPoint = new IntPoint(k, (Integer) v);
浮点型
DoublePoint doublePoint = new DoublePoint(k, (Double) v);
长整型
LongPoint longPoint = new LongPoint(k, (Long) v);
检索
检索使用Query以及Query的子类查询器进行检索,如果像我一样有多条件查询的需求,可以使用Query下的BooleanQuery.Builder类(布尔查询器)。
这里介绍一下BooleanQuery.Builder的示例用法:
Query querys = null;
BooleanQuery.Builder builder = new BooleanQuery.Builder();
// 字符串查询
// BooleanClause.Occur.MUST 表示并且
// BooleanClause.Occur.SHOULD 表示或者
String keyword = "(title : 查询值)";
Analyzer analyzer = new MyIKAnalyzer();
QueryParser parse = new QueryParser("title", analyzer);
querys = parse.parse(keyword)
builder.add(querys,BooleanClause.Occur.MUST);
// 数字范围
// 整型
querys = IntPoint.newRangeQuery("数字列",1,100);
builder.add(querys,BooleanClause.Occur.MUST);
// 浮点型
querys = DoublePoint.newRangeQuery("数字列",1.0,100.0);
builder.add(querys,BooleanClause.Occur.MUST);
// 长整型
querys = LongPoint.newRangeQuery("数字列",1L,10L);
builder.add(querys,BooleanClause.Occur.MUST);
// builder转换为query
querys = builder.build();
// 使用IndexSearcher.search查询结果
// …………
上面的代码可以实现字符串检索和数字范围检索,可以实现多检索条件、查询的逻辑,还是比较贴合我这里的实际业务场景的。
不过在我使用的过程中,LongPoint的查询实际上是不生效的,这个问题我也在研究,后面如果有方法解决,我会第一时间更新。
总结
这几天研究这个Lucene,感觉Lucene并不是很好用,用的比较繁琐。
但毕竟项目架构决定使用Lucene,也是没有什么挣扎的余地,不然我更乐意使用ES(虽然ES也是基于Lucene的底层)。
下次见!