Springboot集成使用ElasticSearch

集成ES

pom.xml

<!--Elasticsearch相关依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

application.yml

spring:
  elasticsearch:
    rest:
      uris: 你的ip:9200

代码

  1. 实体
/**
 * 商品主表---对应的ES数据Document
 */
@Data
@Document(indexName = "shop_product")
public class ESProduct implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    private Long id;
    private Long category_id;
    
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String name;
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String sub_title;
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String keywords;

    private String pic;
    private Integer sort;
    private BigDecimal price;
}
  1. controller
    @ApiOperation("ES分页搜索-所有商品")
    @RequestMapping(value = "/SearchGoods", method = RequestMethod.POST)
    public ResponseCon<ESProductVo> SearchGoods(Integer pageStart, Integer pageSize, String query,
                                                String filtration, String interval, String SortField, String sort) {
        log.info("=======ES搜索参数=======");
        log.info("开始页: "+ pageStart);
        log.info("行数: "+ pageSize);
        log.info("搜索框字符串: "+ query);
        log.info("过滤字段: "+ filtration);
        log.info("价格区间: "+ interval);
        log.info("排序字段: "+ SortField);
        log.info("顺序: "+ sort);
        log.info("执行搜索...");
        
		//filtration = "category_id:12";
        //interval = "0-10";
        //或
        //interval = "100-*";
       
        ESProductVo esProductVo = esProductService.SearchGoods(pageStart, pageSize, query, filtration, interval, SortField, sort);
        return new ResponseCon<>(200, "success", esProductVo);
    }        
  1. service,新版官方是推荐使用ElasticsearchOperations和ESProductDao的
    @Resource
    private ESProductDao esProductDao;
    @Resource
    private ElasticsearchOperations operations;

   /**
     * 搜索ES商品
     */
    @Override
    public ESProductVo SearchGoods(Integer pageStart, Integer pageSize, String query, String filtration, String interval, String sortField, String sort) {
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        //条件
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        //搜索框的字符串查询,为空则查询全部
        if (query != null && !query.equals("") && !query.equals("null")) {
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("keywords", query);
            boolQueryBuilder.must(termQueryBuilder);
        }

        //筛选字段
        if (filtration != null && !filtration.equals("")) {
            String[] strings = filtration.split(":");
            MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery(strings[0], strings[1]);
            boolQueryBuilder.must(matchPhraseQueryBuilder);
        }

        //价格区间过滤
        if (interval != null && !interval.equals("")) {
            String[] strings = interval.split("-");
            RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price");
            
            if(!strings[1].equals("*")){
                //区间
                rangeQueryBuilder.from(Integer.parseInt(strings[0])).to(Integer.parseInt(strings[1]));
            } else {
                //大于或等于 strings[0] 就是 100-*
                rangeQueryBuilder.gte(Integer.parseInt(strings[0]));
            }
            boolQueryBuilder.must(rangeQueryBuilder);
        }

        //价格排序, 升序or倒序
        if (sortField != null && !sortField.equals("")) {
            if (sort.equals("desc")) {
                nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(sortField).order(SortOrder.DESC));
            } else {
                nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(sortField).order(SortOrder.ASC));
            }
        }

        //分页
        nativeSearchQueryBuilder.withPageable(PageRequest.of(pageStart, pageSize));

        //构建高亮查询域, 两个字段
        HighlightBuilder highlightBuilder = new HighlightBuilder()
                .field("sub_title")
                .field("name")
                .preTags("<b style='color:red'>").postTags("</b>").requireFieldMatch(false);

        //构造查询
        nativeSearchQueryBuilder.withHighlightBuilder(highlightBuilder);
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        NativeSearchQuery build = nativeSearchQueryBuilder.build();

        //获取查询结果
        SearchHits<?> searchHits = operations.search(build, Map.class, IndexCoordinates.of("shop_product"));

        //组装查询结果
        ArrayList<ESProduct> list = new ArrayList<>();
        for (SearchHit<?> hit : searchHits) {
            Map<String, Object> content = (Map<String, Object>) hit.getContent();
            Map<String, List<String>> highlightFields = hit.getHighlightFields();
            
			//替换高亮文本
            if (highlightFields.size() > 0) {
                for (String key : highlightFields.keySet()) {
                    content.put(key,highlightFields.get(key).get(0));
                }
            }
            //只留第一张图片
            String pics = (String) content.get("pic");
            String stringPic = pics.substring(0, pics.indexOf(","));
            content.put("pic", stringPic);

            list.add(JSON.parseObject(JSON.toJSONString(content), ESProduct.class));
        }
        //返回包装类
        ESProductVo esProductVo = new ESProductVo();
        esProductVo.setProducts(list);
        esProductVo.setTotal(searchHits.getTotalHits());
        return esProductVo;
    }
  1. dao

/**
 * 商品ES操作类DAO,Repository方式
 * 第一个泛型是实体类类型,第二个泛型是id的类型
 * 继承ElasticsearchRepository对实体数据映射操作
 */
@Repository
public interface ESProductDao extends ElasticsearchRepository<ESProduct, Long> {
//    比如
//    List<ESProduct> findByName(String name);
//    List<ESProduct> findByNameOrDesc(String a,String text);
}
  1. 测试,你先要把数据库中的商品导入到es中。。。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值