Spring-Data-Elasticsearch实现 条件查询+分页+高亮+排序功能

一、依赖

  • Spring Boot 2.4.5
  • Elasticsearch 7.13.2
  • Kibana 7.13.2
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.5</version>
    <relativePath/>
</parent>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
</dependency>
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>

父类是spring-boot,注意es的版本问题,spring-boot依赖中es默认版本与本机es版本不一致会导致报错,需要进入到xml文件中修改es版本。 

二、配置

server:
  port: 8083
spring:
  application:
    name: rest
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/xxx?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
      username: root
      password: root
  elasticsearch:
    rest:
      uris: http://127.0.0.1:9200
management:
  health:
    elasticsearch:
      enabled: false

 三、核心代码

1.索引实体(此处注意es时间的时间格式)

@Data
@Document(indexName = "dish_es4")
public class DishDtoEs implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;


    //菜品名称
    @Field(analyzer = FieldAnalyzer.IK_MAX_WORD, type = FieldType.Text)
    private String name;


    //菜品分类id
    private Long categoryId;


    //菜品价格
    private BigDecimal price;


    //商品码
    private String code;


    //图片
    private String image;


    //描述信息
    private String description;


    //0 停售 1 起售
    private Integer status;


    //顺序
    private Integer sort;

    private Integer count;

    private String categoryName;

    private Integer copies;

    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
    @Field(type = FieldType.Date, format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_second")
    private LocalDateTime createTime;


    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
    @Field(type = FieldType.Date, format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_second")
    private LocalDateTime updateTime;


    @TableField(fill = FieldFill.INSERT)
    private Long createUser;


    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateUser;

}

2.Repository层

@Repository
public interface DishRepository extends ElasticsearchRepository<DishDtoEs,Long> {

}

3.service层

public interface DishService extends IService<Dish> {
    /**
     * 分页查询菜品信息
     *
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    Page<DishDtoEs> pageES(int page, int pageSize, String name);
}
    @Override
    public Page<DishDtoEs> pageES(int page, int pageSize, String name) {
        Page pageInfo = new Page<>();
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize);
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //给name字段设置高亮显示
        if (StringUtils.isNotEmpty(name)) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("name", name));
            queryBuilder.withHighlightFields(new HighlightBuilder.Field("name"))
                    .withHighlightBuilder(new HighlightBuilder().preTags("<font style='color: red;'>").postTags("</font>"));
        }
        //查询条件
        queryBuilder.withQuery(boolQueryBuilder);
        //排序
        queryBuilder.withSort(SortBuilders.fieldSort("updateTime").order(SortOrder.DESC));
        //设置分页
        queryBuilder.withPageable(pageRequest);
        SearchHits<DishDtoEs> search = elasticsearchRestTemplate.search(queryBuilder.build(), DishDtoEs.class);
        List<SearchHit<DishDtoEs>> searchHits = search.getSearchHits();
        List<DishDtoEs> result=new ArrayList<>(searchHits.size());
        //替换高亮内容
        for (SearchHit<DishDtoEs> searchHit:searchHits){
            //高亮的内容
            Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
            //将高亮的内容填充到content中
            searchHit.getContent().setName(highlightFields.get("name")==null ? searchHit.getContent().getName():highlightFields.get("name").get(0));
            //放到实体类中
            result.add(searchHit.getContent());
        }
        long totalHits = search.getTotalHits();
        Stream<SearchHit<DishDtoEs>> searchHitStream = search.get();
        List<DishDtoEs> collect = searchHitStream.map(SearchHit::getContent).collect(Collectors.toList());
        pageInfo.setRecords(result);
        pageInfo.setTotal(totalHits);
        return pageInfo;
    }

4.controller层

@Slf4j
@RestController
@RequestMapping("/dish")
public class DishController {

    /**
     * 分页查询菜品
     *
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(int page, int pageSize, String name) {
        Page dishDtoPage = dishService.pageES(page, pageSize, name);
        return R.success(dishDtoPage);
    }

}

5.前端处理(需要加<v-html>解析为html语言否则无法正常显示)

        <el-table
                :data="tableData"
                stripe
                class="tableBox"
                @selection-change="handleSelectionChange">
            <el-table-column label="菜品名称">
              <template slot-scope="scope">
                <div v-html="scope.row.name"></div>
              </template>
            </el-table-column>
         </el-table>

6.结果显示

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值