ES实战
效果
实现关键字搜索并高亮关键字
导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
配置文件
spring:
elasticsearch:
uris: http://47.96.73.90:9200
# 连接超时时间(默认1s)
connection-timeout: 10s
ES客户端配置
/**
* ElasticSearch 客户端配置
*/
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
@Bean
@Override
public RestHighLevelClient elasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("host:9200")
.build();
return RestClients.create(clientConfiguration).rest();
}
}
ES实体类
/**
* ES中的商品实体类
* @author author
* @since 2023-11-14
*/
@Data
@Document(indexName = "qs_goods")
public class EsGoodsDto{
@Id
@Field(type = FieldType.Keyword)
private Integer key;
@Field(type = FieldType.Keyword)
private Integer storeId;
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String store;
@Field(index=false,type = FieldType.Keyword)
private String storeImage;
@Field(type = FieldType.Text,analyzer = "ik_max_word")
private String name;
@Field(type = FieldType.Double)
private double price;
@Field(index = false,type = FieldType.Integer)
private Integer sale;
@Field(index=false,type = FieldType.Keyword)
private String image;
}
ES Repository
/**
* 方便创建索引库,项目启动后自动创建实体类
*/
@Repository
public interface EsGoodsDtoRepository extends ElasticsearchRepository<EsGoodsDto,String> {
}
ES常用方法
/**
* 封装ES的一些常用方法
* @Author: @weixueshi
* @Create: 2023/12/29 - 10:11
* @Version: v1.0
*/
@Service
public class EsGoodsService {
@Autowired
private RestHighLevelClient client;
/**
* 批量导入商品数据
* @param list
*/
public void bulkSaveGoods(List<EsGoodsDto> list) throws IOException {
BulkRequest bulkRequest = new BulkRequest();
list.stream().forEach(goods -> {
bulkRequest.add(new IndexRequest(EsConstant.INDEX_NAME_GOODS)
.id(goods.getKey().toString())
.source(JSON.toJSONString(goods),XContentType.JSON));
});
client.bulk(bulkRequest, RequestOptions.DEFAULT);
}
/**
* 封装数据
* @param response
* @return
*/
private List<EsGoodsDto> handlerResponse(SearchResponse response) {
SearchHits searchHits = response.getHits();
SearchHit[] hits = searchHits.getHits();
List<EsGoodsDto> list = new ArrayList<EsGoodsDto>();
for(SearchHit hit : hits){
String json = hit.getSourceAsString();
EsGoodsDto esGoodsDto = JSON.parseObject(json, EsGoodsDto.class);
list.add(esGoodsDto);
}
return list;
}
/**
* 返回搜索匹配到的商品id
* @param param
* @return
* @throws IOException
*/
public List<Integer> frontSearchList(String param,String selectMsg) throws IOException {
SearchRequest request = new SearchRequest(EsConstant.INDEX_NAME_GOODS);
if(StringUtils.isBlank(param)){
return null;
}else{
if(EsConstant.GOODS_NAME.equalsIgnoreCase(selectMsg)){
//按商品名称搜索
request.source().query(QueryBuilders.multiMatchQuery(param,"name"));
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//处理返回数据
List<EsGoodsDto> list = handlerResponse(response);
List<Integer> goodsIds = list.stream().map(EsGoodsDto::getKey).collect(Collectors.toList());
return goodsIds;
} else if (EsConstant.STORE_NAME.equalsIgnoreCase(selectMsg)) {
//按店铺名称搜索
request.source().query(QueryBuilders.multiMatchQuery(param,"store"));
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//处理返回数据
List<EsGoodsDto> list = handlerResponse(response);
List<Integer> storeIds = list.stream().map(EsGoodsDto::getStoreId).collect(Collectors.toList());
return storeIds;
}
}
return null;
}
/**
* 商品搜索
* @param pageNo
* @param pageSize
* @param ids
* @return
*/
public Map<String, Object> searchGoodsFrontList(Integer pageNo, Integer pageSize, List<Integer> ids,String name) throws IOException {
if(!CollectionUtils.isEmpty(ids)){
SearchRequest request = new SearchRequest(EsConstant.INDEX_NAME_GOODS);
//根据key查询
request.source().query(QueryBuilders.termsQuery("key",ids));
request.source().query(QueryBuilders.multiMatchQuery(name,"name"));
//高亮查询完成
request.source().highlighter(new HighlightBuilder()
.field("name")
.preTags("<font color='red'>")
.postTags("</font>")
.requireFieldMatch(false));
request.source().from((pageNo - 1) * pageSize).size(pageSize);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//高亮处理返回数据
List<EsGoodsDto> list = handlerGoodsLightResponse(response);
Map<String,Object> map = new HashMap<String,Object>();
map.put("data",list);
map.put("total",response.getHits().getTotalHits().value);
return map;
}
return null;
}
private List<EsGoodsDto> handlerGoodsLightResponse(SearchResponse response) {
SearchHits searchHits = response.getHits();
SearchHit[] hits = searchHits.getHits();
List<EsGoodsDto> list = new ArrayList<EsGoodsDto>();
for(SearchHit hit : hits){
String json = hit.getSourceAsString();
EsGoodsDto esGoodsDto = JSON.parseObject(json, EsGoodsDto.class);
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
if(!CollectionUtils.isEmpty(highlightFields)){
HighlightField highlightField = highlightFields.get("name");
if(highlightField != null){
String name = highlightField.getFragments()[0].string();
esGoodsDto.setName(name);
}
}
list.add(esGoodsDto);
}
return list;
}
/**
* 新增商品文档
* @param esGoodsDto
* @throws IOException
*/
public void addDocument(EsGoodsDto esGoodsDto) throws IOException {
IndexRequest indexRequest = new IndexRequest(EsConstant.INDEX_NAME_GOODS).id(esGoodsDto.getKey().toString());
indexRequest.source(JSON.toJSONString(esGoodsDto),XContentType.JSON);
client.index(indexRequest,RequestOptions.DEFAULT);
}
/**
* 删除文档
* @param list
* @throws IOException
*/
public void deleteDocument(List<Integer> list,String indexName) throws IOException {
BulkRequest bulkRequest = new BulkRequest();
list.stream().forEach(id -> {
bulkRequest.add(new DeleteRequest(indexName,id.toString()));
});
client.bulk(bulkRequest, RequestOptions.DEFAULT);
}
/**
* 删除索引库
* @throws IOException
*/
public void deleteIndex(String indexName) throws IOException {
DeleteIndexRequest deleteRequest = new DeleteIndexRequest(indexName);
client.indices().delete(deleteRequest,RequestOptions.DEFAULT);
}
/**
* 判断索引库是否存在
* @return
* @throws IOException
*/
public boolean isExits(String indexName) throws IOException {
GetIndexRequest getIndexRequest = new GetIndexRequest(indexName);
return client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
}
}