SpringCloudAlibaba云商场-海量数据搜索实现(四)

93 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情

每日英语:

Love the life you live.Live the life you love.

翻译:爱你生活的日子,过你所爱的生活。 ——鲍勃·马利

1. 商品关键词搜索

1.1 搜索分析

用户在web搜索窗口输入关键词keywords后,将keywords关键词一起传入后台,需要根据商品名字进行搜索。以后也有可能根据别的条件查询,所以传入后台的数据可以用Map接收,响应页面的数据包含列表、分页等信息,可以用Map封装。

1.2 关键词搜索代码实现

1.2.1 service

修改com.xz.mall.search.service.SkuSearchService添加搜索方法:

/**
 * 关键词搜索
 * @param searchMap
 * @return
 */
Map<String, Object> search(Map<String, Object> searchMap);

修改com.xz.mall.search.service.impl.SkuSearchServiceImpl添加搜索实现:

/**
 * 商品关键词搜索
 * @param searchMap
 * @return
 */
@Override
public Map<String, Object> search(Map<String, Object> searchMap) {
    //QueryBuilder->构建搜索条件
    NativeSearchQueryBuilder queryBuilder = queryBuilder(searchMap);
    //skuSearchMapper进行搜索
    Page<SkuEs> page = skuSearchMapper.search(queryBuilder.build());
    //获取结果集:集合列表、记录总数
    Map<String, Object> resultMap = new HashMap<>();
    List<SkuEs> list = page.getContent();
    resultMap.put("list", list);
    resultMap.put("totalElements", page.getTotalElements());
    return resultMap;
}
/**
 * 搜索条件构建
 * @param searchMap
 * @return
 */
private NativeSearchQueryBuilder queryBuilder(Map<String, Object> searchMap) {
    NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
    //判断关键词是否为空,不为空,则设置条件
    if (!CollectionUtils.isEmpty(searchMap)) {
        //获取关键词
        Object keyWords = searchMap.get("keywords");
        if (!ObjectUtils.isEmpty(keyWords)) {
            queryBuilder.withQuery(QueryBuilders.termQuery("name", keyWords.toString()));
        }
    }
    return queryBuilder;
}

1.2.2 controller

修改com.xz.mall.search.controller.SkuSearchController添加搜控制方法:

/***
 * 商品搜索
 */
@GetMapping
public RespResult<Map<String, Object>> search(@RequestParam(required = false) Map<String, Object> searchMap) {
    Map<String, Object> resultMap = searchService.search(searchMap);
    return RespResult.ok(resultMap);
}

用这个地址 http://localhost:8084/search?keywords=华为 测试一下结果,get请求方式。

2.商品搜索条件回显

2.1 条件回显业务逻辑分析

我们每次执行搜索的时候,页面会显示不同搜索条件,例如:品牌、分类、属性,这些搜索条件都不是固定的,其实他们是没执行搜索的时候,符合搜索条件的商品所有品牌和所有分类,以及所有属性,把他们查询出来,然后页面显示。但是这些条件都没有重复的,也就是说要去重,去重一般采用分组查询即可,所以我们要想动态获取这样的搜索条件,我们需要在后台进行分组查询。

2.2 品牌、分类条件查询

2.2.1 分组设置

com.xz.mall.search.service.impl.SkuSearchServiceImpl中添加方法,如下:

/**
 * 分组搜素
 * @param queryBuilder
 * @param searchMap
 * @return
 */
private void group(NativeSearchQueryBuilder queryBuilder, Map<String, Object> searchMap) {
    //用户如果没有输入分类条件,则需要将分类搜索出来,作为条件提供给用户
    if (StringUtils.isEmpty(searchMap.get("category"))) {
        queryBuilder.addAggregation(
                AggregationBuilders
                        .terms("categoryList")//别名,类似Map的key
                        .field("categoryName")//根据categoryName域进行分组
                        .size(100)//分组结果显示100个
        );
    }

    //用户如果没有输入品牌条件,则需要将分类搜索出来,作为条件提供给用户
    if (StringUtils.isEmpty(searchMap.get("brand"))) {
        queryBuilder.addAggregation(
                AggregationBuilders
                        .terms("brandList")//别名,类似Map的key
                        .field("brandName")//根据brandName域进行分组
                        .size(100)//分组结果显示100个
        );
    }
}

2.2.2 分组结果解析

com.xz.mall.search.service.impl.SkuSearchServiceImpl中添加方法,如下:

/**
 * 分组结果解析
 * @return
 */
private void parseGroup(Aggregations aggregations, Map<String, Object> resultMap) {
    if (!ObjectUtils.isEmpty(aggregations)) {
        for (Aggregation aggregation : aggregations) {
            //强转成ParsedStringTerms类型
            ParsedStringTerms terms = (ParsedStringTerms) aggregation;

            //循环结果集对象
            List<String> values = new ArrayList<>();
            for (Terms.Bucket bucket : terms.getBuckets()) {
                values.add(bucket.getKeyAsString());
            }
            //名字
            String key = aggregation.getName();
            resultMap.put(key,values);
        }
    }
}

2.2.3 调用实现分组查询

com.xz.mall.search.service.impl.SkuSearchServiceImplsearch方法中添加一下上面两个方法的调用,如下:

/**
 * 商品关键词搜索
 * @param searchMap
 * @return
 */
@Override
public Map<String, Object> search(Map<String, Object> searchMap) {
    //QueryBuilder->构建搜索条件
    NativeSearchQueryBuilder queryBuilder = queryBuilder(searchMap);
    //分组搜索调用
    group(queryBuilder, searchMap);

    //skuSearchMapper进行搜索
    //Page<SkuEs> page = skuSearchMapper.search(queryBuilder.build());
    AggregatedPage<SkuEs> page = (AggregatedPage<SkuEs>) skuSearchMapper.search(queryBuilder.build());

    //获取结果集:集合列表、记录总数
    Map<String, Object> resultMap = new HashMap<>();
    //分组数据解析
    parseGroup(page.getAggregations(), resultMap);
    List<SkuEs> list = page.getContent();
    resultMap.put("list", list);
    resultMap.put("totalElements", page.getTotalElements());
    return resultMap;
}

用postman请求测试:http://127.0.0.1:8084/search ,结果如下:

品牌、分类条件查询结果.jpg

总结:

本篇主要介绍了一下商品关键词搜索和商品品牌、分类条件查询分组查询回显的具体实现。