这里使用Springboot 2.7.12版本,Elasticsearch为7.15.0。
导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
yaml文件配置:
elasticsearch: uris: http://localhost:9200
构建实体类,这里为商品的SKU属性表
@Data @Document(indexName = "skusearch") public class SkuEs { @Id private String id; @Field(type = FieldType.Text,analyzer = "ik_smart",searchAnalyzer = "ik_smart") private String name; private Integer price; private Integer num; private String image; private String images; private Date createTime; private Date updateTime; private String spuId; private Integer categoryId; //Keyword:不分词 @Field(type= FieldType.Keyword) private String categoryName; private Integer brandId; @Field(type=FieldType.Keyword) private String brandName; @Field(type=FieldType.Keyword) private String skuAttribute; private Integer status; }
构建service层进行复杂查询:指定条件查询,聚合查询,分页查询,排序查询,高亮等等
@Service public class SkuSearchServiceImpl implements SkuSearchService { @Autowired ElasticsearchRestTemplate elasticsearchRestTemplate; @Override public Map<String, Object> search(Map<String, Object> map) { if(map!=null&&map.size()>0) { NativeSearchQueryBuilder queryBuilder = queryBuilder(map); //分组查询 group(queryBuilder, map); // NativeSearchQuery nativeSearchQuery = queryBuilder.build(); SearchHits<SkuEs> skuEsSearchHits = elasticsearchRestTemplate.search(queryBuilder.build(), SkuEs.class); AggregationsContainer<?> aggregations = skuEsSearchHits.getAggregations(); Aggregations aggregations1 = (Aggregations) aggregations.aggregations(); Map<String, Object> searchMap = new HashMap<>(); //解析分组数据 parseGroup(aggregations1, searchMap); //遍历返回的内容进行处理 List<SearchHit<SkuEs>> searchHits = skuEsSearchHits.getSearchHits(); //将高亮的内容填充到content中 List<SkuEs> skuEsList = searchHits.stream().map(i -> { Map<String, List<String>> highlightFields = i.getHighlightFields(); List<String> name = highlightFields.get("name"); i.getContent().setName(name==null?i.getContent().getName():name.get(0)); return i.getContent(); }).collect(Collectors.toList()); //数据元素 searchMap.put("list", skuEsList); //数据元素总数 searchMap.put("totalElements", skuEsList.size()); return searchMap; } return null; } public NativeSearchQueryBuilder queryBuilder(Map<String, Object> searchMap){ NativeSearchQueryBuilder queryBuilder=new NativeSearchQueryBuilder(); BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder(); if(searchMap!=null&&searchMap.size()>0){ //根据产品关键词进行查询 String keyword = searchMap.get("keyword").toString(); if(!StringUtils.isEmpty(keyword)) boolQueryBuilder.must(QueryBuilders.termQuery("name",keyword)); //查询指定的品牌 String brandName=searchMap.get("brand").toString(); if(!StringUtils.isEmpty(brandName)){ boolQueryBuilder.must(QueryBuilders.termQuery("brandName",brandName)); } //根据价格进行查询,形式为gteprice-lteprice String price = searchMap.get("price").toString(); if(!StringUtils.isEmpty(price)){ String[] split = price.split("-"); boolQueryBuilder.must(QueryBuilders.rangeQuery("price").gte(split[0])); if(split.length>1) boolQueryBuilder.must(QueryBuilders.rangeQuery("price").lte(split[1])); } } //根据价格,对于查询出来的产品进行降序排列 queryBuilder.withSort(SortBuilders.fieldSort("price").order(SortOrder.DESC)); //分页查询 queryBuilder.withPageable(PageRequest.of(Integer.parseInt(searchMap.get("current").toString()),Integer.parseInt(searchMap.get("size").toString()))); queryBuilder.withQuery(boolQueryBuilder); //高亮设置 queryBuilder.withHighlightFields(new HighlightBuilder.Field("name")); queryBuilder.withHighlightBuilder(new HighlightBuilder().preTags("<em>").postTags("</em>")); return queryBuilder; } public void group(NativeSearchQueryBuilder queryBuilder,Map<String, Object> searchMap){ //用户如果没有输入分类条件,则需要将分类搜索出来,作为条件提供给用户 if(StringUtils.isEmpty(searchMap.get("category"))){ queryBuilder.withAggregations(AggregationBuilders.terms("categoryList"). field("categoryName").size(100)); } //用户如果没有输入品牌条件,则需要将品牌搜索出来,作为条件提供给用户 if(StringUtils.isEmpty(searchMap.get("brand"))){ queryBuilder.withAggregations(AggregationBuilders.terms("brandList") .field("brandName").size(100)); } } //解析分组数据 public void parseGroup(Aggregations aggregations, Map<String,Object> resultMap){ if(aggregations!=null){ for (Aggregation aggregation : aggregations) { ParsedStringTerms terms = (ParsedStringTerms) aggregation; String name = terms.getName(); List<String> collect = terms.getBuckets().stream().map(i -> i.getKeyAsString()).collect(Collectors.toList()); resultMap.put(name,collect); } } } }
接口测试:
查询如下:
{ "data": { "categoryList": [ "软件研发" ], "brandList": [ "华为" ], "list": [ { "id": "1318594982227025922", "name": "<em>华为</em>Mate40 Pro 32G", "price": 114, "num": 1228, "image": "https://sklll.oss-cn-beijing.aliyuncs.com/secby/af1faf56-b10a-4700-9896-3143a2d1c40f.jpg", "images": "https://sklll.oss-cn-beijing.aliyuncs.com/secby/a65bfbe4-21b7-42b2-b5cf-47a9730e0a16.jpg,https://sklll.oss-cn-beijing.aliyuncs.com/secby/fa52ef66-7724-4d6e-bece-15eba0f8f903.jpg,https://sklll.oss-cn-beijing.aliyuncs.com/secby/734f0f17-ac73-45d3-a6bf-83e1569ce887.jpg", "createTime": "2020-10-20T08:48:37.000+00:00", "updateTime": "2023-12-30T07:41:20.000+00:00", "spuId": "1318594982147334146", "categoryId": 11159, "categoryName": "软件研发", "brandId": 11, "brandName": "华为", "skuAttribute": "{\"就业薪资\":\"10K起\",\"学习费用\":\"2万\"}", "status": 1, "attrMap": null }, { "id": "1318596430360813570", "name": "<em>华为</em>Mate40 Pro 32G 1800万像素", "price": 112, "num": 1227, "image": "https://sklll.oss-cn-beijing.aliyuncs.com/secby/9247d041-e940-426c-8e50-06084b631063.jpg", "images": "https://sklll.oss-cn-beijing.aliyuncs.com/secby/5f5b7435-6cf2-4797-8f65-d4abff181390.jpg", "createTime": "2020-10-20T08:54:22.000+00:00", "updateTime": "2023-12-30T07:41:21.000+00:00", "spuId": "1318596430293704706", "categoryId": 11159, "categoryName": "软件研发", "brandId": 11, "brandName": "华为", "skuAttribute": "{\"就业薪资\":\"10K起\",\"学习费用\":\"2万\"}", "status": 1, "attrMap": null }, { "id": "1318596430398562305", "name": "<em>华为</em>Mate40 Pro 128G", "price": 111, "num": 1226, "image": "https://sklll.oss-cn-beijing.aliyuncs.com/secby/900a3618-9884-4778-bad9-c6c31eaf3eab.jpg", "images": "https://sklll.oss-cn-beijing.aliyuncs.com/secby/5f5b7435-6cf2-4797-8f65-d4abff181390.jpg", "createTime": "2020-10-20T08:54:22.000+00:00", "updateTime": "2023-12-30T07:41:24.000+00:00", "spuId": "1318596430293704706", "categoryId": 11159, "categoryName": "软件研发", "brandId": 11, "brandName": "华为", "skuAttribute": "{\"就业薪资\":\"10K起\",\"学习费用\":\"2万\"}", "status": 1, "attrMap": null } ], "totalElements": 3 }, "code": 20000, "message": "操作成功" }