一.Es的配置
实现es的全文检索功能的第一步,首先从与es进行连接开始,这里我使用的是es的5.x java api语法.
public TransportClient esClient() throwsUnknownHostException{
Settings settings=Settings.builder()
.put("cluster.name", "my-application") //节点的名字
.put("client.transport.sniff", true)
.build();
InetSocketTransportAddress iAddress= new InetSocketTransportAddress( //连接es的ip地址和端口号
InetAddress.getByName("127.0.0.1"),9300);//根据先前的配置生成client,后面的操作基本都是基于这个
TransportClient client = newPreBuiltTransportClient(settings)
.addTransportAddress(iAddress);returnclient;
}
二.功能的实现
以下是全文检索的核心代码,包括我遇到的错误以及解决,包括如何对高亮失效,高亮不全等的解决.
1.查询条件
TransportClient esClient = esClient(); //获取先前生成的client
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); //生成复合查询构造器
boolQuery.mustNot(
QueryBuilders.matchQuery("",) //字段必须不包含啥
);
boolQuery.should(
QueryBuilders.matchQuery(, )//字段可以包含啥,相当于或者
);
boolQuery.must(
QueryBuilders.matchQuery(,)//字段必须包含啥
);
2.高亮条件
//配置标题高亮显示
HighlightBuilder highlightBuilder= new HighlightBuilder(); //生成高亮查询器
highlightBuilder.field(title); //高亮查询字段
highlightBuilder.field(content); //高亮查询字段
highlightBuilder.requireFieldMatch(false); //如果要多个字段高亮,这项要为false
highlightBuilder.preTags(""); //高亮设置
highlightBuilder.postTags("");//下面这两项,如果你要高亮如文字内容等有很多字的字段,必须配置,不然会导致高亮不全,文章内容缺失等
highlightBuilder.fragmentSize(800000); //最大高亮分片数
highlightBuilder.numOfFragments(0); //从第一个分片获取高亮片段
3.查询配置
//根据字段进行排序,这里我根据时间进行倒排
FieldSortBuilder timeSort = SortBuilders.fieldSort("time").order(SortOrder.DESC);//查询请求生成
SearchRequestBuilder requestBuilder = esClient.prepareSearch(indexname)//索引名字
.setTypes(indextype) //索引类型
.setQuery(boolQuery) //配置查询条件
.addSort(new ScoreSortBuilder()) //根据查询相关度进行排序
.addSort(timeSort) //再根据时间进行排序
.setTrackScores(true) //避免分页之后相关性乱了
.highlighter(highlightBuilder) //配置高亮
.setFrom(from) //设置分页
.setSize();
4.获取查询结果对其高亮
//获取查询结果
SearchResponse searchResponse =requestBuilder.get();
List> course = new ArrayList<>();if(searchResponse.status() !=RestStatus.OK){returncourse;
}for(SearchHit hit:searchResponse.getHits()){//获取高亮字段
Map highlightFields =hit.getHighlightFields();
HighlightField titleField= highlightFields.get("");
HighlightField contentField= highlightFields.get("");
Map source =hit.getSource();//千万记得要记得判断是不是为空,不然你匹配的第一个结果没有高亮内容,那么就会报空指针异常,这个错误一开始真的搞了很久
if(titleField!=null){
Text[] fragments=titleField.fragments();
String name= "";for(Text text : fragments) {
name+=text;
}
source.put("", name); //高亮字段替换掉原本的内容
}
course.add(source);
}
esClient.close();//用完记得关闭
return course;
三.结语
这样前端所获取结果的搜索内容将会被所包含,比如我前端是微信小程序,所以直接获取内容进行渲染的话,就是一堆字符串,所以用的是小程序的富文本标签.
如果你觉得文章内容对你有用的话,不用忘记评论,点赞.