Elasticsearch在项目中的应用,商品搜索功能设计与实现

以下内容默认掌握了Elasticsearch的基本用法,不太熟悉的同学可以先去Elasticsearch的官网查看文档

中文分词器

由于商品搜索会涉及中文搜索,Elasticsearch需要安装插件才可以支持,我们先来了解下中文分词器,这里使用的是IKAnalyzer。

使用IKAnalyzer

  • 使用默认分词器,可以发现默认分词器只是将中文逐词分隔,并不符合我们的需求;
GET /equipment/_analyze
{
  "text": "智利樱桃味道很好",
  "tokenizer": "standard"
}

  • 使用中文分词器以后,可以将中文文本按语境进行分隔,可以满足我们的需求。
GET /equipment/_analyze
{
  "text": "智利樱桃味道很好",
  "tokenizer": "ik_max_word"
}

SpringBoot中的使用

对于需要进行中文分词的字段,我们直接使用@Field注解将analyzer属性设置为ik_max_word即可。

/**
 * 搜索中的商品信息
 */
@Document(indexName = "equipment", type = "product",shards = 1,replicas = 0)
public class EsProduct implements Serializable {
    private static final long serialVersionUID = -1L;
    @Id
    private Long id;
    @Field(analyzer = "ik_max_word",type = FieldType.Text)
    private String name;
    @Field(analyzer = "ik_max_word",type = FieldType.Text)
    private String type;
    @Field(analyzer = "ik_max_word",type = FieldType.Text)
    private String system;
    //省略若干代码......
}

简单商品搜索

  • 使用Query DSL调用Elasticsearch的Restful API实现;
POST equipment/_search
{
  "from": 0, 
  "size": 2, 
  "query": {
    "multi_match": {
      "query": "设备一",
      "fields": [
        "name",
        "type",
        "system"
      ]
    }
  }
}
  • 在SpringBoot中实现,使用Elasticsearch Repositories的衍生查询来搜索;
/**
 * 商品搜索管理Service实现类
 */
@Service
public class EsProductServiceImpl implements EsProductService {
    @Override
    public Page<EsProduct> search(String keyword, Integer pageNum, Integer pageSize) {
        Pageable pageable = PageRequest.of(pageNum, pageSize);
        return productRepository.findByNameOrTypeOrSystem(keyword, keyword, keyword, pageable);
    }
}
  • 衍生查询其实原理很简单,就是将一定规则方法名称的方法转化为Elasticsearch的Query DSL语句,看完下面这张表你就能明白。

综合商品搜索

接下来我们来实现一个复杂的商品搜索,涉及到过滤、不同字段匹配权重不同以及可以进行排序。

  • 首先来说下我们的需求,按输入的关键字搜索商品名称、类型和系统,可以按名称和分类进行筛选,可以有5种排序方式,默认按相关度进行排序,看下接口文档有助于理解;

  • 这里我们有一点特殊的需求,比如商品名称匹配关键字的的商品我们认为与搜索条件更匹配,其次是类型和系统,这时就需要用到function_score查询了;

  • 在Elasticsearch中搜索到文档的相关性由_score字段来表示的,文档的_score字段值越高,表示与搜索条件越匹配,而function_score查询可以通过设置权重来影响_score字段值,使用它我们就可以实现上面的需求了;

  • 使用Query DSL调用Elasticsearch的Restful API实现,可以发现商品名称权重设置为了10,商品类型权重设置为了5,商品系统设置为了2;

  • 在SpringBoot中实现,使用Elasticsearch Repositories的search方法来实现,但需要自定义查询条件QueryBuilder;

posted @ 2021-02-18 15:34  JasonBo  阅读(469)  评论(0)    收藏  举报