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;


浙公网安备 33010602011771号