elasticsearch匹配关键词高亮+中文分词(包含数组字段处理)

开始前准备

springdata elastic接入方法
https://blog.csdn.net/qq_36289377/article/details/105843733

对应版本

elasticsearch 6.8
spring-boot 2.2.2.RELEASE
spring-boot-starter-data-elasticsearch 2.2.2.RELEASE

本文创作时,es最新版为7.2,可以兼容,6.0以下版本需要根据版本改部分代码,主要是低版本的几个Hits类不同,其他差别不大,可以自己查,这里不提供具体哪几个类。未来更高版本也不确定能否可用,自己去判断。

原理分析

实现关键词高亮在本质上是利用es的自定义ResultMapper功能,将匹配到的结果通过反射替换为加入高亮标识的片段的过程,对于这一点来说,网上相关文档数不胜数,并不是说完全不能用,但是对于聚合字段的处理基本是选择性忽略,而且对于使用的es client也停留在较老的版本,如果毫不思考直接使用,通常会遇到很多问题,别问我怎么知道的😓。

第一步:ES数据结构设计

如果你的es映射类含聚合信息:如数组字段、对象字段、对象数组字段,如

/**
 * es公司信息聚合映射实体类
 * @author tino
 * @date 2020/7/27
 */
@org.springframework.data.elasticsearch.annotations.Document(indexName = "tino", type = "company_info", shards = 1, replicas = 0)
public class EsCompanyInfoModel extends BaseModel {
   

    /**
     * 公司名称
     */
    private String companyName;
    
    /**
     * 数组
     */
    private List<BizProductModel> products;

    /**
     * 公司分类
     */
    private List<String> categories;

    /**
     * 公司案例
     */
    private CompanyCaseModel companyCaseModel;

    public String getCompanyName() {
   
        return companyName;
    }

    public void setCompanyName(String companyName) {
   
        this.companyName = companyName;
    }

    public List<BizProductModel> getProducts() {
   
        return products;
    }

    public void setProducts(List<BizProductModel> products) {
   
        this.products = products;
    }

    public List<String> getCategories() {
   
        return categories;
    }

    public void setCategories(List<String> categories) {
   
        this.categories = categories;
    }

    public CompanyCaseModel getCompanyCaseModel() {
   
        return companyCaseModel;
    }

    public void setCompanyCaseModel(CompanyCaseModel companyCaseModel) {
   
        this.companyCaseModel = companyCaseModel;
    }
}

那么你可能需要将聚合的对象数组、对象更改数据结构为:仅包含基本类型数组字符串类型数组
原因时对象数组的在反射时,想通过反射替换对象数组中对应索引的对象的字段操作起来比较困难,所以我们需要尽量简化数据结构,只将需要匹配的字段单独拿出来放到字符串数组中(应该没有业务会全字段匹配吧,如果有建议从设计层面去杜绝),更改数据结构后,需要清理ES中的旧数据

## 删除所有
index/type/_delete_by_query
{
   
  "query": {
   
    "match_all": {
   }
  }
}

调整后的数据结构

/**
 * es公司信息聚合映射实体类
 * @author tino
 * @date 2020/7/27
 */
@org.springframework.data.elasticsearch.annotations.Document(indexName = "tino", type = "company_info", shards = 1, replicas = 0)
public class EsCompanyInfoModel extends BaseModel {
   

    /**
     * 产品名称
     */
    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private List<String> productNames;

    /**
     * 产品线路
     */
    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private List<String> productRoutes;

    /**
     * 产品分类
     */
    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private List<String> productCategories;

    /**
     * 标签
     */
    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private List<String> productLabels;

    /**
     *
     */
    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private List<String> productIntros;

    /**
     * 公司案例标题
     */
    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private List<String> caseTiles;

    /**
     * 公司案例内容
     */
    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private List<String> casesValueContents;

    public List<String> getProductNames() {
   
        return productNames;
    }

    public void setProductNames(List<String> productNames) {
   
        this.productNames = productNames;
    }

    public List<String> getProductRoutes() {
   
        return productRoutes;
    }

    public void setProductRoutes(List<String> productRoutes) {
   
        this.productRoutes = productRoutes;
    }

    public List<String> getProductCategories() {
   
        return productCategories;
    }

    public void setProductCategories(List<String> productCategories) {
   
        this.productCategories = productCategories;
    }

    public List<String> getProductLabels() {
   
        return productLabels;
    }

    public void setProductLabels(List<String> productLabels) {
   
        this.productLabels = productLabels;
    }

    public List<String> getProductIntros() {
   
        return productIntros;
    }

    public void setProductIntros(List<String> productIntros) {
   
        this.productIntros = productIntros;
    }

    publi
  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值