整合ES
创建gulimall-search模块
使用web
导入high-level-client,参照RestClient操作索引库这篇文章
导入common模块的依赖
配置文件
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
application:
name: gulimall-search
开启服务注册发现@EnableDiscoveryClient
编写配置
@Configuration
public class GulimallElasticSearchConfig {
@Bean
public RestHighLevelClient esRestClient(){
RestClientBuilder restClientBuilder = null;
restClientBuilder = RestClient.builder(new HttpHost("192.168.205.128", 9200, "http"));
RestHighLevelClient client = new RestHighLevelClient(restClientBuilder);
return client;
}
}
将数据源排除
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
在GulimallElasticSearchConfig中添加设置项
public static final RequestOptions COMMON_OPTIONS;
static {
RequestOptions.Builder builder=RequestOptions.DEFAULT.toBuilder();
// builder.addHeader("Authorization","Bearer"+TOKEN);
// builder.setHttpAsyncResponseConsumerFactory(
// new HttpAsyncResponseConsumerFactory
// .HeapBufferedResponseConsumerFactory(30*1024*1024*1024)
// );
COMMON_OPTIONS=builder.build();
}
type:nested
PUT /myindex/_doc/1
{
"group":"fans",
"user":[
{"firstName":"Alice",
"lastName":"Smith"
},
{
"firstName":"John",
"lastName":"White"
}
]
}
user的类型为text
GET /myindex/_search
{
"query": {
"bool": {
"must": [
{"match": {"user.firstName": "Alice"}},
{"match": {"user.lastName": "White"}}
]
}
}
}
结果出现了不满足条件的数据
修改user的type为nested
要先删除索引
DELETE /myindex
修改user的type
PUT myindex
{
"mappings": {
"properties": {
"user":{
"type": "nested"
}
}
}
}
查询结果:
商品上架功能
es中建立 product 索引
最终选用的数据模型:
{ “type”: “keyword” }, # 保持数据精度问题,可以检索,但不分词
“analyzer”: “ik_smart” # 中文分词器
“index”: false, # 不可被检索,不生成 index
“doc_values”: false # 默认为 true,不可被聚合,es 就不会维护一些聚合的信息
PUT product
{
"mappings":{
"properties": {
"skuId":{
"type": "long"
},
"spuId":{
"type": "keyword"
},
"skuTitle": {
"type": "text",
"analyzer": "ik_smart"
},
"skuPrice": {
"type": "keyword"
},
"skuImg":{
"type": "keyword",
"index": false,
"doc_values": false
},
"saleCount":{
"type":"long"
},
"hasStock": {
"type": "boolean"
},
"hotScore": {
"type": "long"
},
"brandId": {
"type": "long"
},
"catelogId": {
"type": "long"
},
"brandName": {
"type": "keyword",
"index": false,
"doc_values": false
},
"brandImg":{
"type": "keyword",
"index": false,
"doc_values": false
},
"catalogName": {
"type": "keyword",
"index": false,
"doc_values": false
},
"attrs": {
"type": "nested",
"properties": {
"attrId": {
"type": "long"
},
"attrName": {
"type": "keyword",
"index": false,
"doc_values": false
},
"attrValue": {
"type": "keyword"
}
}
}
}
}
}
在common模块下创建一个SkuEsModule类
属性与es中的一一对应
@Data
public class SkuEsModule {
private Long skuId;
private Long spuId;
private String skuTitle;
private BigDecimal skuPrice;
private String skuImg;
private Long saleCount;
private Boolean hasStock;
private Long hotScore;
private Long brandId;
private Long catelogId;
private String brandName;
private String brandImg;
private String catelogName;
private List<Attrs> attrs;
//检索属性
@Data
public static class Attrs {
private Long attrId;
private String attrName;
private String attrValue;
}
}
在SpuInfoController中编写controller
///product/spuinfo/{spuId}/up
@PostMapping("/{spuId}/up")
public R up(@PathVariable("spuId") Long spuId){
spuInfoService.up(spuId);
return R.ok();
}
编写方法up(spuId)
1、先根据传过来的spuId查询sku的基本信息,直接对拷到SkuEsModule中
2、设置skuImg; skuPrice的值
3、热度评分(hotScore),这里先直接设置
4、设置private String brandName,private String brandImg,private String catelogName;
5、查询AttrsValue,且attr为可以检索的
@Data
public static class Attrs {
private Long attrId;
private String attrName;
private String attrValue;
}
*
*/
//TODO 查询当前SKU所有的规格属性,可以被用来检索的--Attrs
其中selectSearchAttrIds
@Override
public List<Long> selectSearchAttrIds(List<Long> attrIds) {
List<Long> list = this.baseMapper.selectSearchAttrIds(attrIds);
return list;
}
<select id="selectSearchAttrIds" resultType="java.lang.Long">
SELECT attr_id FROM `pms_attr` WHERE attr_id in
<foreach collection="attrIds" item="attr" separator="," open="(" close=")">
#{attr}
</foreach>and search_type=1
</select>
6、hasStock,hotScore;库存,需要远程调用
@FeignClient("gulimall-ware")
public interface WareFenginService {
@PostMapping("/ware/waresku/hasstock")
public R<List<SkuHasStockVo>> getSkuHasStock(@RequestBody List<Long> skuIds);
}
修改R,使用泛型
public class R<T> extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public R() {
put("code", 0);
put("msg", "success");
}
使得远程调用返回的是SkuHasStockVo集合
创建SkuHasStockVo类
@Data
public class SkuHasStockVo {
private Long skuId;//skuId
private Boolean hasStock;//是否有库存
}
远程调用这个方法
//查询sku是否有库存
@PostMapping("/hasstock")
public R<List<SkuHasStockVo>> getSkuHasStock(@RequestBody List<Long> skuIds){
List<SkuHasStockVo> vos = wareSkuService.getSkuHasStock(skuIds);
R ok = R.ok();
ok.setData(vos);
return ok;
}
@Override
public List<SkuHasStockVo> getSkuHasStock(List<Long> skuIds) {
List<SkuHasStockVo> collect = skuIds.stream().map(item -> {
SkuHasStockVo vo = new SkuHasStockVo();
Long count = baseMapper.getSkuStock(item);
vo.setSkuId(item);
vo.setHasStock(count==null?false:count>0);
return vo;
}).collect(Collectors.toList());
return collect;
}
查询有多少库存
<select id="getSkuStock" resultType="java.lang.Long">
SELECT SUM(stock-stock_locked) FROM `wms_ware_sku` WHERE sku_id=#{item}
</select>
7、将数据发送给es进行保存
//TODO 将数据发送给es,进行保存
R r = searchFeignService.productStatusUp(upProducts);
if (r.getCode()==0){
//远程调用成功
//TODO 修改SPU的发布状态
this.baseMapper.updateSpuStatus(spuId, ProductConstant.StatusEnum.SPU_UP.getCode());
}
else{
//远程调用失败
//TODO 重复调用,接口幂等性
}
转载:https://blog.csdn.net/qq_57907966/article/details/128885484