封装ES高亮Yxh-Es
拉取代码
git拉取 yxh-elasticsearch: es基本封装工具
使用场景
我们拿游览器举例,我将我要搜索的内容输入到输入框进行搜索,游览器就会根据对应的内容查出文章中出现过的关键字,并加上样式,让我们看的更清晰。
我们以就是使用全文检索的时候,好比用户输入关键字,es进行查询,给用户呈现的页面对应的内容,以及将用户输入的关键字,加粗或标识出来。
获取泛型
/**
* 获取泛型
*/
private Class<T> deSerializable() {
Type type = getClass().getGenericSuperclass();
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
System.out.println(parameterizedType.getActualTypeArguments()[0]);
return (Class<T>) parameterizedType.getActualTypeArguments()[0];
}
throw new RuntimeException();
}
接口
接口需要加上泛型
核心代码
高亮查询
这块代码主要就是实现一个查询出高亮字段,通过读取注解里的参数,做对应的替换。
/**
* 高亮查询
* @param request 参数
* @param data 泛型
* @param indexName 索引名
* @param client 连接
* */
public List<Object> queryHighLight(String request, Class<?> data, String indexName, RestHighLevelClient client) throws IllegalAccessException {
List<Object> list = new ArrayList<>();
//获取list的泛型
HighLightDTO highLightDTO = readHighLight(data);
try {
//创建请求索引
SearchRequest searchRequest = new SearchRequest(indexName);
//创建构造器
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//创建条件拼接
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//查询用户名 模糊查询
if (null != request){
boolQueryBuilder.must(QueryBuilders.wildcardQuery(highLightDTO.getName(),"*"+request+"*"));
}
//条件存放构造器
searchSourceBuilder.query(boolQueryBuilder);
//高亮
searchSourceBuilder.highlighter(new HighlightBuilder().field(highLightDTO.getName()).preTags(highLightDTO.getPreTag()).postTags(highLightDTO.getPostTag()));
searchRequest.source(searchSourceBuilder);
SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = search.getHits();
for (SearchHit hit : hits.getHits()) {
String sourceAsString = hit.getSourceAsString();
Object object = JSONObject.parseObject(sourceAsString, data);
//获取高亮集合
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
if (null!=highlightFields){
HighlightField obj = highlightFields.get(highLightDTO.getName());
if (null != obj){
String str = "";
for (Text fragment : obj.getFragments()) {
str += fragment;
}
//将字段赋值
assignment(object, highLightDTO.getMapping(), str);
}
}
//将存储的结果存入list集合
list.add(object);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return list;
}
标记映射
主要起到,读取@HighLight该注解所映射的字段。
/**
* 读取@HighLight映射字段
* */
private HighLightDTO readHighLight(Class<?> data) throws IllegalAccessException {
Field[] fields = data.getDeclaredFields();
String name = null;
String preTags = null;
String postTags = null;
String mapping = null;
for (Field field : fields) {
HighLight annotation = field.getAnnotation(HighLight.class);//映射@highLight值
if (annotation!=null){
field.setAccessible(true);
name = field.getName();//字段名
preTags = annotation.preTag();//自定义标签前缀
postTags = annotation.postTag();//自定义标签后缀
mapping = annotation.mappingField();//映射字段
}
}
return new HighLightDTO(name,preTags,postTags,mapping);
}
/**
* 给高亮值赋值
*/
private void assignment(Object data, String fieldName, String newValue) throws IllegalAccessException, NoSuchFieldException {
Field field = data.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(data, convertValue(field.getType(), newValue));
}
/**
* 转类型
*/
private Object convertValue(Class<?> fieldType, String value) {
JdkDataTypeEnum byType = JdkDataTypeEnum.getByType(String.valueOf(fieldType));
switch (byType){
case INTEGER:
return Integer.parseInt(value);
case LONG:
return Long.parseLong(value);
case BOOLEAN:
return Boolean.parseBoolean(value);
default:
return value;
}
}
总结
这次我是将原先的yxh-es做了一个迭代,一开始没有查询方法,也没有高亮,当时这个高亮灵感是来自于easy-es,因为之前在使用这个工具的时候,发现他们团的做的少了个高亮查询,我测了好几次,让身边的同事也测了,发现不行,就是有问题的,想着就自己封装es,把这个高亮也补上。当然我这个高亮目前仅限于一个字段来模糊查,我后门会在对该工具迭代更新。