/* * @Copyright (c) 2021. 于吉利 All Rights Reserved * @Author: 于吉利 * @Function: * @Date: 2021/9/13 下午2:11 * @version:1.0 * @Changes: * @Description: * */ package com.huajun.search.service.impl; import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.databind.ObjectMapper; import com.huajun.search.entity.Product; import com.huajun.search.service.ISmartQuery; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.Operator; import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightField; import org.elasticsearch.search.sort.FieldSortBuilder; import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortOrder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.elasticsearch.common.text.Text; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Service public class SmartQueryImpl implements ISmartQuery { @Autowired private RestHighLevelClient restHighLevelClient; @Autowired private ObjectMapper objectMapper; @Override public List<Product> searcher(String keyWords, String indexName, Integer pageNum, Integer pageSize) { List<Product> productInfos = new ArrayList<Product>(); SearchRequest searchRequest; if (indexName == "all") { searchRequest = new SearchRequest(indexName); } else { searchRequest = new SearchRequest();////穿件SeachRequest,Without arguments this runs against all indices. } SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.searchSource(); //分页开始 //searchSourceBuilder.from(0).size(10); //init if (pageSize == null) { pageSize = 10; } if (pageNum == null) { pageNum = 1; } Integer from = (pageNum - 1) * pageSize; if (from <= 0) { from = 0; } searchSourceBuilder.from(from); searchSourceBuilder.size(pageSize); //设置一个可选的超时时间,用于可控制搜索允许的时间 searchSourceBuilder.timeout(new TimeValue(1200, TimeUnit.SECONDS)); //将数据按date排序 FieldSortBuilder sortBuilder = SortBuilders.fieldSort("createdate").order(SortOrder.DESC); searchSourceBuilder.sort(sortBuilder); //创建queryBuilder, 从es字段:name,content多字段查询 QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(keyWords, "name", "content").operator(Operator.OR); searchSourceBuilder.query(queryBuilder); //设置需要高亮的es字段 String preTags = "<span style='color:#29bf9d'>"; String postTags = "</span>"; HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.preTags(preTags);//设置前缀 highlightBuilder.postTags(postTags);//设置后缀 highlightBuilder.field("name");//设置高亮字段 highlightBuilder.field("content");//设置高亮字段 //设置多个高亮显示为false,根据需求也可以设置为true highlightBuilder.requireFieldMatch(false); //下面这两项,如果你要高亮如文字内容等有很多字的字段,必须配置,不然会导致高亮不全,文章内容缺失等 highlightBuilder.fragmentSize(800000); //最大高亮分片数 highlightBuilder.numOfFragments(0); //从第一个分片获取高亮片段 searchSourceBuilder.highlighter(highlightBuilder);//设置高亮信息 searchRequest.source(searchSourceBuilder); try { SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); //return toProductList(response.getHits().getHits()).stream().findFirst().orElse(null); return toProductList(response.getHits().getHits()); // } catch (Exception e) { e.printStackTrace(); } return null; } private List<Product> toProductList(SearchHit[] searchHits) throws Exception { List<Product> productList = new ArrayList<>(); for (SearchHit searchHit : searchHits) { Product Productinfo = JSON.parseObject(searchHit.getSourceAsString(), Product.class); Map<String, HighlightField> highlightFields = searchHit.getHighlightFields(); if (!highlightFields.isEmpty()) { HighlightField name = highlightFields.get("name"); if (name != null) { Productinfo.setName(Arrays.stream(name.getFragments()).map(Text::string).collect(Collectors.joining(" "))); } HighlightField content = highlightFields.get("content"); if (content != null) { Productinfo.setContent(Arrays.stream(content.getFragments()).map(Text::string).collect(Collectors.joining(" "))); } } productList.add(Productinfo); //productList.add(searchHit.getSourceAsMap()); //productList.add(objectMapper.readValue(searchHit.getSourceAsString(), Product.class)); //productList.add(objectMapper.readValue(searchHit.getSourceAsString(), Product.class)); } return productList; } }