1.基本的查询方法
// 构建基本查询条件
private QueryBuilder buildBasicQueryWithFilter(SearchRequest request) {
String flag = "";
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery();
//如果输入的查询条件为空,则查询所有数据
if(request.getKey() == null || "".equals(request.getKey())) {
queryBuilder.must(QueryBuilders.matchAllQuery());
return queryBuilder;
}
// 基本查询条件
//queryBuilder.must(QueryBuilders.matchQuery(request.getKeyField(), request.getKey()));
//queryBuilder.must(QueryBuilders.multiMatchQuery(request.getKey(), request.getKeyFields()));//多字段查询,字段直接是or的关系
//过滤条件
Map<String, Object> filter = request.getFilter();
if(filter != null) {
for (Map.Entry<String, Object> entry : filter.entrySet()) {
String key = entry.getKey();
flag = key;
Map<String, String> value = (Map<String, String>) entry.getValue();
for (Map.Entry<String, String> map : value.entrySet()) {
String filterKey = map.getKey();
String filterValue = map.getValue();
if(key == "and") {
queryBuilder.filter(QueryBuilders.termQuery(filterKey, filterValue));
}
if(key == "or") {
shouldQuery.should(QueryBuilders.termQuery(filterKey, filterValue));
}
if(key == "not") {
queryBuilder.mustNot(QueryBuilders.termQuery(filterKey, filterValue));
}
}
}
}
if(flag == "or") {
queryBuilder.must(QueryBuilders.multiMatchQuery(request.getKey(), request.getKeyFields())).must(shouldQuery);//解决should和must共用不生效问题
}else {
queryBuilder.must(QueryBuilders.multiMatchQuery(request.getKey(), request.getKeyFields()));//多字段查询,字段直接是or的关系
}
return queryBuilder;
}
2.构建多字段高亮
QueryBuilder basicQuery =buildBasicQueryWithFilter(request);
//1.1多字段高亮
HighlightBuilder.Field highlightFields = null;
List<HighlightBuilder.Field> lst = new ArrayList<>();
for(String field : request.getKeyFields()) {
highlightFields = new HighlightBuilder.Field(field);
highlightFields.preTags("<span style=\"color:red\">").postTags("</span>");
lst.add(highlightFields);
}
HighlightBuilder.Field[] ary = new HighlightBuilder.Field[lst.size()];
for(int i=0;i<lst.size();i++) {
ary[i] = lst.get(i);
}
queryBuilder.withQuery(basicQuery).withHighlightFields(ary);
//5.2 高亮查询结果
AggregatedPage<Item> pageInfo = template.queryForPage(queryBuilder.build(), Item.class
,new SearchResultMapper() {
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz,
Pageable pageable) {
List<Map<String,Object>> list=new ArrayList<>();
SearchHits hits = response.getHits();
for (SearchHit searchHit : hits) {
if (hits.getHits().length <= 0) {
return null;
}
Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
//将高亮值放入高亮字段
for(String keyField : request.getKeyFields()){//循环遍历得到分词(高亮)字段名称
String keyFieldValue= (String) sourceAsMap.get(keyField); //取出分词字段值
HighlightField highlightFieldValue =searchHit.getHighlightFields().get(keyField);//取出分词字段值,关键词部分高亮
if(highlightFieldValue == null) {
sourceAsMap.put(keyField, keyFieldValue);
}else {
String hcontent = highlightFieldValue.fragments()[0].toString();//取值
sourceAsMap.put(keyField, hcontent);
}
}
list.add(sourceAsMap);
}
if (list.size() > 0) {
return new AggregatedPageImpl<T>((List<T>) list);
}
return null;
}
}
);
3.补充SearchRequest部分字段
private String key;// 搜索条件
private String[] keyFields; //全文检索的字段名称