一.Es的配置
实现es的全文检索功能的第一步,首先从与es进行连接开始,这里我使用的是es的5.x java api语法.
-
public TransportClient esClient() throws UnknownHostException{
-
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 =
new PreBuiltTransportClient(settings)
-
.addTransportAddress(iAddress);
-
return client;
-
}
二.功能的实现
以下是全文检索的核心代码,包括我遇到的错误以及解决,包括如何对高亮失效,高亮不全等的解决.
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(
"<span style=\"color:red\">");
//高亮设置
-
highlightBuilder.postTags(
"</span>");
-
-
//下面这两项,如果你要高亮如文字内容等有很多字的字段,必须配置,不然会导致高亮不全,文章内容缺失等
-
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<Map<String, Object>> course =
new ArrayList<>();
-
if(searchResponse.status() != RestStatus.OK){
-
return course;
-
}
-
for(SearchHit hit:searchResponse.getHits()){
-
-
//获取高亮字段
-
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
-
HighlightField titleField = highlightFields.get(
"");
-
HighlightField contentField = highlightFields.get(
"");
-
-
-
-
Map<String, Object> 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;
三.结语
这样前端所获取结果的搜索内容将会被<span style="color:red;"></span>所包含,比如我前端是微信小程序,所以直接获取内容进行渲染的话,就是一堆字符串,所以用的是小程序的富文本标签<rich-text>.
如果你觉得文章内容对你有用的话,不用忘记评论,点赞.
版权声明:本文为qq_44813090原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。