原生查询
可以查询的范围更精确,当ElasticsearchRepository提供的基本方法无法满足我们所需要的查询可以使用原生的方式查询
@Test//原生查询 public void naticeQuery(){ //创建原生查询构建器对象 NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); //过滤条件 queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{"id","title","price"},new String[0])); //搜索条件 queryBuilder.withQuery(QueryBuilders.matchQuery("title","荣耀")); //分页及排序条件 当前页起始数据的下标 每页的大小 排列的顺序 queryBuilder.withPageable(PageRequest.of(0,2,Sort.by(Sort.Direction.DESC,"price"))); //高亮显示 TODO //聚合 terms()方法指定分组的名称(聚合名称),field方法指定要按照哪一个字段进行分组 queryBuilder.addAggregation(AggregationBuilders.terms("brandAgg").field("brand")); //构建查询条件,并且查询 AggregatedPage<Producter> result = template.queryForPage(queryBuilder.build(), Producter.class); //解析结果 System.out.println("总条数:"+result.getTotalElements()); System.out.println("总页数:"+ result.getTotalPages()); List<Producter> content = result.getContent(); System.err.print("数据:"); content.forEach(System.err::print); System.out.println(""); Aggregations aggregations = result.getAggregations(); Terms terms = aggregations.get("brandAgg"); terms.getBuckets().forEach(b->{ System.out.println("品牌:"+b.getKeyAsString()); System.out.println("count:"+b.getDocCount()); }); }
高亮查询
高亮查询的配置类,固定写法
import com.google.gson.Gson; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.text.Text; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.fetch.subphase.highlight.HighlightField; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.SearchResultMapper; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl; import java.util.ArrayList; import java.util.List; import java.util.Map; //SearchResultMapper 用来自定义查询结果的映射,将结果安装开发者配置,进行重组,然后再返回给客户端 //重写mapResults方法:配置自定义结果映射 public class ProductSearchResultMapper implements SearchResultMapper { @Override public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) { //记录总数 long totalHits = searchResponse.getHits().getTotalHits(); //记录列表(泛型) ---构建Aggregate使用 List<T> list =new ArrayList<>(); //获取真正的记录 SearchHits hits = searchResponse.getHits(); SearchHit[] hs = hits.getHits(); for (SearchHit h : hs) { Map<String, Object> map = h.getSourceAsMap(); //获取需要高亮显示的字段 Map<String, HighlightField> highlightFields = h.getHighlightFields(); for(Map.Entry<String,HighlightField> hf :highlightFields.entrySet()){ //一组高亮显示的字段 String key = hf.getKey(); HighlightField value = hf.getValue(); //实际需要高亮显示的结果 Text[] fragments = value.getFragments(); //高亮的字段在key中 map.put(key,fragments[0].toString()); } //把Map转化为对象 Gson gson = new Gson(); T t = gson.fromJson(gson.toJson(map), aClass); list.add(t); } //返回带分页的结果 AggregatedPageImpl<T> ts = new AggregatedPageImpl<>(list, pageable, totalHits); return ts; } }
高亮查询
@Test//高亮查询 public void naticeQuery1(){ //创建原生查询构建器对象 NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); //过滤条件 queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{"id","title","price"},new String[0])); //搜索条件 queryBuilder.withQuery(QueryBuilders.matchQuery("title","荣耀")); //分页及排序条件 当前页起始数据的下标 每页的大小 排列的顺序 queryBuilder.withPageable(PageRequest.of(0,2,Sort.by(Sort.Direction.DESC,"price"))); //高亮显示 //指定需要高亮显示的字段名称 HighlightBuilder.Field field =new HighlightBuilder.Field("title"); // field.preTags("<span style='color:yellow'>");//前缀 field.preTags("<span id='highred'>");//前缀 field.postTags("</span>");//后缀 //将指定前缀和后缀的Field对象,绑定到queryBuilder对象上 queryBuilder.withHighlightFields(field); //聚合 terms()方法指定分组的名称(聚合名称),field方法指定要按照哪一个字段进行分组 queryBuilder.addAggregation(AggregationBuilders.terms("brandAgg").field("brand")); //构建查询条件,并且查询 AggregatedPage<Producter> result = template.queryForPage(queryBuilder.build(), Producter.class,new ProductSearchResultMapper()); //解析结果 //分页结果 System.out.println("总条数:"+result.getTotalElements()); System.out.println("总页数:"+ result.getTotalPages()); List<Producter> content = result.getContent(); System.out.println("数据"+content); }
高亮显示的字段可以将指定的字段添加标签,然后前端写样式来改变展示的样式