技术栈入门------ElasticSearch

本文详细介绍了如何在Linux环境中使用Docker安装ElasticSearch和Kibana,包括创建目录、启动容器以及设置内存。接着,文章讲解了如何在SpringBoot应用中整合ElasticSearch,导入依赖并配置客户端。此外,还展示了商品服务如何利用ElasticSearch进行商品上架,包括数据存入ElasticSearch的过程和涉及的业务逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用ElasticSearch的准备工作

一、在Linux上安装ElasticSearch

1、docker下载elasticSearch和kibana的镜像

docker pull elasticsearch:7.4.2 存储和检索数据
docker pull kibana:7.4.2 可视化检索数据

2、创建目录

mkdir -p /mydata/elasticsearch/config 
mkdir -p /mydata/elasticsearch/data 
echo "http.host: 0.0.0.0" >> /mydata/elasticsearch/config/elasticsearch.yml

3、启动并挂载Elasticsearch

chmod -R 777 /mydata/elasticsearch/ 保证权限 
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \ -e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx1024m" \ 
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \ 
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \ 
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \ 
-d elasticsearch:7.4.2

特别注意: -e ES_JAVA_OPTS="-Xms64m -Xmx256m" \ 
测试环境下,设置 ES 的初始内存和最大内存,否则导 致过大启动不了 ES

4、启动kibana

docker run --name kibana -e ELASTICSEARCH_HOSTS=http://虚拟机Linux的ip地址:9200 -p 5601:5601 \ -d kibana:7.4.2

http://192.168.56.10:9200 一定改为自己虚拟机的地址

二、整合SpringBoot

1、导入Elasticsearch客户端的依赖

注意这里的<elasticsearch.version>7.4.2</elasticsearch.version>要写成和自己Linux的elasticsearch版本,如果不写这句那就用的是SpringBoot默认的版本,然后上面的linux中的elasticSearch和kibana版本最好保持一致性

<properties>
  <java.version>1.8</java.version>
  <elasticsearch.version>7.4.2</elasticsearch.version>
  <spring-cloud.version>2021.0.0</spring-cloud.version>
</properties>

<dependency>
  <groupId>org.elasticsearch.client</groupId>
  <artifactId>elasticsearch-rest-high-level-client</artifactId>
  <version>7.4.2</version>
</dependency>

2、ElasticSearch的配置类

package com.saodai.saodaimall.search.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* ElasticSearch的配置类
**/
@Configuration
public class SaodaimallElasticSearchConfig {
    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();
    }
    
    
    @Bean
    public RestHighLevelClient esRestClient(){
        RestClientBuilder builder = null;
        builder = RestClient.builder(new HttpHost("192.168.241.128", 9200, "http"));
        RestHighLevelClient client = new RestHighLevelClient(builder);
        return  client;
    }
    
    
}

本商城项目哪里用到了ElasticSearch

商品服务

商品服务的商品上架功能就是把上架的商品的所有信息存到ElasticSearch

1、在Vscode中发送上架请求

2、商品服务的SpuInfoController来处理请求/{spuId}/up

/**
     * 商品维护的spu管理的上架功能
     */
    @PostMapping("/{spuId}/up")
    public R spuUp(@PathVariable("spuId") Long spuId){
        spuInfoService.up(spuId);
        return R.ok();
    }

分流程:

(1)查找出spuId对应的所有sku对象

(2)查出当前sku的所有可以被用来检索的规格属性

  //商品维护的spu管理的上架功能
    @Override
    public void up(Long spuId) {
        //查找出spuId对应的所有sku对象
        List<SkuInfoEntity> skuInfoEntities = skuInfoService.getSkusBySpuId(spuId);
        //查出当前sku的所有可以被用来检索的规格属性
        List<ProductAttrValueEntity> productAttrValueEntities = attrValueService.baseAttrlistforspu(spuId);
        List<Long> attrIds = productAttrValueEntities.stream().map(attr -> {
            return attr.getAttrId();
        }).collect(Collectors.toList());
/*        //在批量规格参数attrids找到具有检索属性的规格参数的id集
        List<Long> sarchAttrIds = attrService.selectSearchAttrsIds(attrIds);*/
        Set<Long> idSet = new HashSet<>(attrIds);
        //找到符合要求的数据
        List<SkuEsModel.Attrs> attrsList = productAttrValueEntities.stream().filter(item -> {
            //下面返回的是List<ProductAttrValueEntity>
            return idSet.contains(item.getAttrId());
        }).map(item -> {
            //把上面过滤的List<ProductAttrValueEntity>对象转为List<SkuEsModel.Attrs>
            SkuEsModel.Attrs attrs = new SkuEsModel.Attrs();
            BeanUtils.copyProperties(item, attrs);
            return attrs;
        }).collect(Collectors.toList());

        //发送远程调用,库存服务查询是否有库存
          //获取skuIds集合
        List<Long> skuIdList = skuInfoEntities.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());

        Map<Long, Boolean> stockMap =null;
        //进行异常处理(因为远程调用可能因为网络问题导致失败,进行异常处理就不会影响下面的代码运行)
        try{
            //远程调用仓库接口
            R r = wareFeignService.getSkusHasStock(skuIdList);
            TypeReference<List<SkuHasStockVo>> typeReference = new TypeReference<List<SkuHasStockVo>>() {};
            //获取返回R中的数据并封装成map<skuId,HasStock>
            stockMap = r.getData(typeReference).stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));
        } catch (Exception e) {
            log.error("库存服务查询异常:原因{}",e);
        }

        Map<Long, Boolean> finalStockMap =stockMap;
        List<SkuEsModel> collect = skuInfoEntities.stream().map(skuInfoEntity -> {
            //组装需要的数据
            SkuEsModel skuEsModel = new SkuEsModel();
            BeanUtils.copyProperties(skuInfoEntity,skuEsModel);
            skuEsModel.setSkuPrice(skuInfoEntity.getPrice());
            skuEsModel.setSkuImg(skuInfoEntity.getSkuDefaultImg());
            //hasStock,hotScore
            //设置库存信息
            if (finalStockMap == null) {
                skuEsModel.setHasStock(true);
            } else {
                skuEsModel.setHasStock(finalStockMap.get(skuInfoEntity.getSkuId()));
            }


            //热度评分
            //查询品牌和分类的名称信息
            BrandEntity brandEntity = brandService.getById(skuInfoEntity.getBrandId());
            skuEsModel.setBrandName(brandEntity.getName());
            skuEsModel.setBrandId(brandEntity.getBrandId());
            skuEsModel.setBrandImg(brandEntity.getLogo());

            CategoryEntity categoryEntity = categoryService.getById(skuInfoEntity.getCatalogId());
            skuEsModel.setCatalogId(categoryEntity.getCatId());
            skuEsModel.setCatalogName(categoryEntity.getName());

            //设置可以检索的规格参数
            skuEsModel.setAttrs(attrsList);
            return skuEsModel;

        }).collect(Collectors.toList());

        //TODO 5、远程调用将数据发给es进行保存:saodaimall-search
        R r = searchFeginService.productStatusUp(collect);

        if (r.getCode() == 0) {
            //远程调用成功
            //TODO 6、修改当前spu的状态
            System.out.println("远程调成功!");
            this.baseMapper.updaSpuStatus(spuId, ProductConstant.ProductStatusEnum.SPU_UP.getCode());
        } else {
            //远程调用失败
            //TODO 7、重复调用?接口幂等性:重试机制
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好运仔dzl

打赏有用的话还要工作干嘛

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值