2025年8_搭建商城搜索微服务[通俗易懂]

8_搭建商城搜索微服务[通俗易懂]搜索服务的父项目 supergo search 1 建 Module supergo search 2 删除 src 搜索服务的提供者 supergo search service9003 1 建 Module supergo search service9003 2 改 pom supergo search com supergo 1 0 SNAPSHOT

搜索服务的父项目:supergo_search

1、建Module:supergo_search
2、删除src

----

搜索服务的提供者:supergo_search_service9003

1、建Module:supergo_search_service9003

2、改pom




supergo_search
com.supergo
1.0-SNAPSHOT

4.0.0

supergo_search_service9003


org.springframework.boot
spring-boot-starter-web


org.springframework.boot
spring-boot-starter-actuator


org.springframework.cloud
spring-cloud-starter-netflix-hystrix


org.springframework.cloud
spring-cloud-starter-netflix-eureka-client

/dependency>

br />

br />

!--spring-es-->



org.springframework.data
spring-data-elasticsearch

/dependency>

br />

dependency>


org.springframework.boot

spring-boot-starter-test

/artifactId>

br />

scope>test

/scope>

br />

br />

groupId>org.springframework.cloud

/groupId>

br /> spring-cloud-starter-openfeign

br /> }

br />

br /> import com.supergo.search.entity.GoodsEntity;

br /> import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

br />

br /> /** * @Author: xj0927 * @Description: * @Date Created in 2021-01-04 12:31 * @Modified By: */

br /> public interface GoodsRepository extends ElasticsearchRepository

GoodsEntity, Long>{




}

/code>

code class='prism'>@Service


public class SearchService {




@Autowired


private GoodsMapper goodsMapper;



@Autowired


private GoodsRepository goodsRepository;



@Autowired


private ElasticsearchTemplate elasticsearchTemplate;



/*** * 查询数据库将所有商品数据导入到索引库 */


public HttpResult importGoods() {



//查询数据库


List

goodsList = goodsMapper.getGoodsList();
System.out.println(goodsList);
//把商品数据写入索引库
System.out.println("数据导入开始。。。");
goodsList.forEach(g -> goodsRepository.save(g));
System.out.println("数据导入完成!");
return HttpResult.ok();
}
}

/pre>

p>----

/p>

h5>controller

/h5>

pre class='language-javascript'>

@RestController
public class SearchController {


@Autowired
private SearchService searchService;

@RequestMapping("/goods/import")
public HttpResult goodsImport() {

new Thread(() -> searchService.importGoods()).start();
return HttpResult.ok();
}
}

/pre>

p>----

/p>

h5>测试

/h5>

p>浏览器输入:

/p>

pre class='language-javascript'>

http://localhost:9003/goods/import

/pre>

p>查看索引:

/p>

p>数据成功导入ElasticSearch

/p>

p>----

/p>

h4>8、搜索索引库

/h4>

p>数据导入Es后,下面开始搜索服务的创建

/p>

p>先看京东的搜索方式:

/p>

p>在输入栏搜索“苹果”,会出现按不同方式的聚合结果

/p>

p>然后在分类栏,选择”苹果”,

/p>

p>对地址url进行转义解析:

/p>

p>本次也是使用类型方案:关键词使用查询,限制条件使用过滤

/p>

h5>service

/h5>

pre class='language-javascript'>

@Service
public class SearchService {


@Autowired
private GoodsMapper goodsMapper;

@Autowired
private GoodsRepository goodsRepository;

@Autowired
private ElasticsearchTemplate elasticsearchTemplate;

/** * @Description: 商品查询 * 原则:第一个参数使用查询方式,其他参数使用过滤 [提高效率] * @Author: xj0927 * @Date Created in 2021/1/4 19:55 */
public SearchResult search(String keyword, Map filters, int page, int size) {


//设置查询条件
BoolQueryBuilder builder = QueryBuilders.boolQuery()
.should(QueryBuilders.multiMatchQuery(keyword, "goods_name"));

//判断是否有过滤条件
if (filters != null && !filters.isEmpty()) {

filters.keySet().forEach(key -> {

builder.filter(QueryBuilders.termQuery(key, filters.get(key)));
});
}

NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(builder) //查询条件
.withPageable(PageRequest.of(page, size))//设置分页信息
.addAggregation(AggregationBuilders.terms("category_aggs").field("cname3"))//聚合条件1
.addAggregation(AggregationBuilders.terms("brand_aggs").field("brand_name"))//聚合条件2
.withHighlightFields(new HighlightBuilder.Field("name").preTags("").postTags(""))//设置高亮显示
.build(); //创建q

//执行查询
AggregatedPage sResult = elasticsearchTemplate.queryForPage(query, GoodsEntity.class, new SearchResultMapper() {

@Override
public AggregatedPage mapResults(SearchResponse searchResponse, Class aClass, Pageable pageable) {

List goodsList = new ArrayList<>();
SearchHits searchHits = searchResponse.getHits();
searchHits.forEach(hits -> {

//原文档部分
GoodsEntity goodsEntity = new GoodsEntity();
goodsEntity.setId((Long) hits.getSource().get("id"));
goodsEntity.setGoods_name((String) hits.getSource().get("goods_name"));
goodsEntity.setSeller_id((String) hits.getSource().get("seller_id"));
goodsEntity.setNick_name((String) hits.getSource().get("nick_name"));
goodsEntity.setBrand_id((Integer) hits.getSource().get("brand_id"));
goodsEntity.setBrand_name((String) hits.getSource().get("brand_name"));
goodsEntity.setCategory1_id((Integer) hits.getSource().get("category1_id"));
goodsEntity.setCname1((String) hits.getSource().get("cname1"));
goodsEntity.setCategory2_id((Integer) hits.getSource().get("category2_id"));
goodsEntity.setCname2((String) hits.getSource().get("cname2"));
goodsEntity.setCategory3_id((Integer) hits.getSource().get("category3_id"));
goodsEntity.setCname3((String) hits.getSource().get("cname3"));
goodsEntity.setSmall_pic((String) hits.getSource().get("small_pic"));
goodsEntity.setPrice((Double) hits.getSource().get("price"));
//取高亮部分
HighlightField highlightField = hits.getHighlightFields().get("goods_name");
if (highlightField != null) {

String hl = highlightField.getFragments()[0].string();
goodsEntity.setGoods_name(hl);
}
goodsList.add(goodsEntity);
});
AggregatedPage aggregatedPage = new AggregatedPageImpl((List) goodsList, pageable, searchHits.totalHits, searchResponse.getAggregations());
return aggregatedPage;
}
});
//取查询结果
List content = sResult.getContent();
SearchResult searchResult = new SearchResult();
searchResult.setGoodsList(content);

//取分类聚合结果
Terms termsCat = (Terms) sResult.getAggregation("category_aggs");
List catAggsList = termsCat.getBuckets().stream().map(e -> e.getKeyAsString()).collect(Collectors.toList());
Map catAggsMap = new HashMap();
catAggsMap.put("name", "分类");
catAggsMap.put("field", "cname3");
catAggsMap.put("content", catAggsList);

//取品牌聚合结果
Terms termsBrand = (Terms) sResult.getAggregation("brand_aggs");
List brandAggsList = termsBrand.getBuckets().stream().map(e -> e.getKeyAsString()).collect(Collectors.toList());
Map brandAggsMap = new HashMap();
brandAggsMap.put("name", "品牌");
brandAggsMap.put("field", "brand_name");
brandAggsMap.put("content", brandAggsList);
List aggsList = new ArrayList();
aggsList.add(brandAggsMap);
aggsList.add(catAggsMap);

//设置过滤条件
searchResult.setAggs(aggsList);
return searchResult;
}
}

----

controller
![5](images/5.png)RestController
public class SearchController {


@Autowired
private SearchService searchService;

@RequestMapping("/goods/search")
public SearchResult search(@RequestParam(required = true) String keyword,
@RequestParam(required = false, value = "ev") String filter,
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "5") int size) {

//filter的参数形式:ev=brand_name-小米|category3_id-255、
Map filterMap = null;
try {

if (StringUtils.isNotBlank(filter)) {

String[] filters = filter.split("\\|");
filterMap = Stream.of(filters).collect(Collectors.toMap(e -> e.split("-")[0].trim(), e -> e.split("-")[1].trim()));
}
} catch (Exception e) {

e.printStackTrace();
}
System.out.println(filter);
System.out.println(filterMap);
SearchResult searchResult = searchService.search(keyword, filterMap, page, size);
return searchResult;
}
}

----

测试

浏览器输入:

http://localhost:9003/goods/search?keyword=手机&ev=brand_name-联想

----

编程小号
上一篇 2025-03-01 14:01
下一篇 2025-02-19 13:40

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/hz/140391.html