秒杀服务中的搜索管理

183 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第25天,点击查看活动详情

每日英语:

Language will continue to put the world into words.

翻译:唯有语言文字,始终记录着世间的一切。 ——安妮·埃尔诺

搜索管理

商品搜索我们采用Elasticsearch,因为秒杀商品数据量太大,不建议大量使用Redis缓存。

业务分析

比如我们首先加载出5个秒杀时间段,当用户点击其中一个时间的时候加载对应的数据,默认加载第一个的数据即可,我们可以采用如下流程实现:

秒杀搜索管理业务分析.jpg

秒杀索引导入

秒杀数据导入到索引库去,要先创建ES对应的Pojo,再将SeckillGoods转成ES的Pojo存入ES中,我们接下来一步一步实现该操作。

1)ES映射Pojo创建

mall-search-api中创建com.xz.mall.search.model.SeckillGoodsEs代码如下:

@Data
@Document(indexName = "shopsearch",type = "seckillgoodses")
public class SeckillGoodsEs implements Serializable {
​
    @Id
    private String id;
    private String supId;
    private String skuId;
    @Field(type=FieldType.Text,searchAnalyzer = "ik_smart",analyzer = "ik_smart")
    private String name;
    private String images;
    private Integer price;
    private Integer seckillPrice;
    private Integer num;
    private Integer storeCount;
    private Date createTime;
    @Field(type=FieldType.Keyword)
    private String activityId;
}

2)数据导入

修改mall-search-service在该工程中实现秒杀数据导入到ES,我们首先引入mall-seckill-api

<!--seckill-api-->
<dependency>
    <groupId>com.xz.mall</groupId>
    <artifactId>mall-seckill-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

3)Dao

创建com.xz.mall.search.mapper.SeckillGoodsSearchMapper代码如下:

public interface SeckillGoodsSearchMapper extends ElasticsearchRepository<SeckillGoodsEs,String> {
}

4)Service

接口:创建com.xz.mall.search.service.SeckillGoodsSearchService并添加导入索引方法

public interface SeckillGoodsSearchService {
    /***
     * 导入数据到ES中
     * @param seckillGoodsEs
     */
    void add(SeckillGoodsEs seckillGoodsEs);
}

实现类:创建com.xz.mall.search.service.impl.SeckillGoodsSearchServiceImpl并实现导入索引方法:

@Service
public class SeckillGoodsSearchServiceImpl implements SeckillGoodsSearchService {
​
    @Autowired
    private SeckillGoodsSearchMapper seckillGoodsSearchMapper;
​
    /***
     * 导入数据到ES中
     * @param seckillGoodsEs
     */
    @Override
    public void add(SeckillGoodsEs seckillGoodsEs) {
        seckillGoodsSearchMapper.save(seckillGoodsEs);
    }
}

5)Controller

创建com.xz.mall.search.controller.SeckillGoodsSearchController实现导入索引调用操作,代码如下:

@RestController
@RequestMapping(value = "/seckill/goods")
public class SeckillGoodsSearchController {
​
    @Autowired
    private SeckillGoodsSearchService seckillGoodsSearchService;
​
    /***
     * 导入数据到索引库
     */
    @PostMapping(value = "/add")
    public RespResult add(@RequestBody SeckillGoodsEs seckillGoodsEs){
        seckillGoodsSearchService.add(seckillGoodsEs);
        return RespResult.ok();
    }
}

6)Feign创建

其他服务为了能够同步索引,需要调用上面方法,所以我们需要创建一个Feign接口。

mall-search-api中创建com.xz.mall.search.feign.SeckillGoodsSearchFeign代码如下:

@FeignClient(value = "mall-search")
public interface SeckillGoodsSearchFeign {
​
    /***
     * 导入数据到索引库
     */
    @PostMapping(value = "/seckill/goods/add")
    RespResult add(@RequestBody SeckillGoodsEs seckillGoodsEs);
}

秒杀商品搜索

秒杀商品搜索从页面上看是根据时间搜索,其实是根据活动ID搜索,只是可以根据时间排序。所以我们需要在后台实现根据活动ID搜索商品数据。

1)Dao

修改com.xz.mall.search.mapper.SeckillGoodsSearchMapper添加根据活动ID搜索商品,代码如下:

//根据ActivityId搜索数据
List<SeckillGoodsEs> searchByActivityId(String acid);

2)Service

接口:修改com.xz.mall.search.service.SeckillGoodsSearchService添加根据活动ID搜索商品方法,代码如下:

/**
 * 根据活动ID搜索
 * @param acid
 * @return
 */
List<SeckillGoodsEs> search(String acid);

实现类:修改com.xz.mall.search.service.impl.SeckillGoodsSearchServiceImpl添加根据ID搜索商品的实现方法,代码如下:

/***
 * 根据活动ID搜索
 * @param acid
 * @return
 */
@Override
public List<SeckillGoodsEs> search(String acid) {
    return seckillGoodsSearchMapper.searchByActivityId(acid);
}

3)Controller

修改com.xz.mall.search.controller.SeckillGoodsSearchController添加商品搜索实现控制方法

/****
 * 搜索商品数据
 */
@GetMapping(value = "/search")
public RespResult<List<SeckillGoodsEs>> list(@RequestParam("acid")String acid){
    //根据活动ID搜索
    List<SeckillGoodsEs> seckillGoodsEsList =  seckillGoodsSearchService.search(acid);
    return RespResult.ok(seckillGoodsEsList);
}

总结

本篇主要介绍了一下秒杀服务中涉及到的搜索管理业务分析、秒杀索引导入、秒杀商品搜索。