本文要实现的一个功能,根据品牌、分类、规格、价格过滤查询商品的功能,并对查询结果的关键字
进行高亮显示。只做后端功能。
本文是以代码驱动
,如果看不太懂,可以先复制代码,再慢慢看,注释很详细。
1、引入相关依赖
主要就是fastjson
和spring-boot-starter-data-elasticsearch
(SpringBoot项目),fastJson的作用是转换对象使用,当然也可以进行时间格式化(本文未作处理)。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.28</version>
</dependency>
2、ElasticSearch数据测试准备
①创建Goods类,测试类里注入相关对象
@Document(indexName = "goods_sku",type = "goods")
@Data
public class Goods {
@Id
@Field(type = FieldType.Long,store = true)
private Long id; // 主键Id
@Field(type = FieldType.Text,analyzer = "ik_smart",store = true)
private String name; // 商品名称
@Field(type = FieldType.Integer,store = true)
private Integer price; // 商品价格
@Field(type = FieldType.Text,store = true,index = false)
private String image; // 商品图片src
@Field(type = FieldType.Date,store = true,index = false)
private Date createTime; // 商品创建时间
@Field(type = FieldType.Long,store = true,index = false)
private Long spuId; // Spu的Id
@Field(type = FieldType.Keyword,store = true)
private String categoryName;// 分类名称
@Field(type = FieldType.Keyword,store = true)
private String brandName; // 品牌名称
@Field(type = FieldType.Object,store = true)
private Map spec; // 规格Map Map<String,String>,如<"颜色","黑色">
@Field(type = FieldType.Integer,store = true,index = false)
private Integer saleNum; // 销量
public Goods(){
}
public Goods(Long id, String name, Integer price, String image, Date createTime, Long spuId, String categoryName, String brandName, Map spec, Integer saleNum) {
this.id = id;
this.name = name;
this.price = price;
this.image = image;
this.createTime = createTime;
this.spuId = spuId;
this.categoryName = categoryName;
this.brandName = brandName;
this.spec = spec;
this.saleNum = saleNum;
}
}
@Autowired
private ElasticsearchTemplate template;
@Autowired
private GoodsRepository goodsRepository;
@Autowired
private EsResultMapper esResultMapper;
②数据准备 - 尽量多准备一些数据,方便测试查询
@Test
public void createIndex(){
template.createIndex(Goods.class);
}
@Test
public void createDoc(){
Map map1 = new HashMap();
map1.put("颜色","紫色");
map1.put("套餐","标准套餐");
Goods goods1 = new Goods(7L,"小米 Mini9秘境黑优惠套餐16G+64G",100,"xxxx",new Date(),2L,"手机","小米",map1,100);
goodsRepository.save(goods1);
// 使用saveAll批量存储
}
3、构建基本查询方法
该方法通过传过来的条件Map
,根据条件进行过滤查询,比如分类、品牌、规格、价格区间等(具体取决于需求)。
/**
* 构建基本查询 - 搜索关键字、分类、品牌、规格、价格
* @param searchMap
* @return
*/
private BoolQueryBuilder buildBasicQuery(Map searchMap) {
// 构建布尔查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// 关键字查询
boolQueryBuilder.must(QueryBuilders.matchQuery("name",searchMap.get("keywords")));
// 分类、品牌、规格 都是需要精准查询的,无需分词
// 商品分类过滤
if (searchMap.get("category") != null){
boolQueryBuilder.filter(QueryBuilders.matchPhraseQuery("categoryName",searchMap.get("category")));
}
// 商品品牌过滤
if(searchMap.get("brand") != null){
boolQueryBuilder.filter