프로젝트에서 Elasticsearch를 사용하는 방법

머리말

제품 검색 모듈이 프로젝트에 참여하고 있으며, ES 지식을 습득하여 프로젝트에 ES를 적용하려고 노력하고 있습니다.이 블로그는 주로 프로젝트에서 ES를 사용하는 방법을 설명합니다. 함께 구입 한 Alibaba Cloud 서버가 만료되었으므로 여기에서는 시연하지 않습니다. 향후 작업을 위해 좋은 서버를 구입해야합니다.

ES 및 Kibana도 설치하려면 이전 블로그를 따라 포털 을 구축 할 수
있습니다. <---- 여기를 클릭하십시오.

ES의 데이터 모델

ES에서 데이터를 확인하려면 먼저 ES에 데이터를 저장해야합니다. 그때는 반 친구들과 Kibana에서 직접 데이터를 가져 오는 방법에 대해 논의했지만 생각하면 너무 힘들어요. 나중에 반 친구들이 작성한 백 스테이지 관리에 제품이 있다고 생각했습니다. 선반에있는 기능은 여기서부터 시작합니다.

모델 디자인

우리가 설계 한 모델을 살펴보십시오.

@Data
public class SkuEsModel {
    
    
	//具体商品的id
    private Long skuId;
	//某类商品的id 
    private Long spuId;
    //销售商品的标题
    private String skuTitle;
    //销售商品的价格
    private BigDecimal skuPrice;
    //销售商品的图片
    private String skuImg;
    //商品的销量
    private Long saleCount;
    //商品是否有库存
    private Boolean hasStock;
    //商品的评分
    private Long hotScore;
    //商品所属品牌的id
    private Long brandId;
    //商品所属分类的id
    private Long catalogId;
    //商品所属品牌的名字
    private String brandName;
    //商品所属品牌的图片
    private String brandImg;
    //商品所属分类的名字
    private String catalogName;
    //商品所对应的属性
    private List<Attrs> attrs;
    @Data
    public static class Attrs {
    
    
    	//属性id
        private Long attrId;
        //属性的名字
        private String attrName;
        //属性值
        private String attrValue;
    }
}

이런 디자인을하는 이유

먼저 쇼핑몰의 비즈니스에서 es를 사용하는 것에 대해 이야기 해 보겠습니다.

  • 쇼핑몰 홈페이지 3 단계 목록의 3 단계 디렉토리를 통해 검색 페이지로 진입
  • 쇼핑몰 홈페이지 검색 창을 통해 검색하고자하는 상품명을 입력하고 es를 체크하여 데이터를 반환

3 단계 디렉토리를 클릭하여 입력하면 카테고리 ID 매개 변수가 전달되므로 검색을 제공 할 모델에 카테고리 ID가 있어야하며 검색 상자를 통해 입력하면 sku 제품의 제목과 일치하는 문자열 매개 변수가 전달됩니다.
따라서 이러한 검색을 통해 세부 정보 페이지에서 렌더링 할 프런트 엔드를 제공하려면 어떤 데이터가 필요합니까?
여기에 사진 설명 삽입
위의 스크린 샷은 JD.com에서 찍은 것입니다. 제 반 친구들은 JD의 페이지를 기반으로 일부 기능을 모방했습니다. 사진의 주석을 읽은 후 모델이 왜 그렇게 디자인되었는지 이해해야합니다. 그러나 상품 상세 페이지와 관련된 다른 필드가 있습니다. 이 검색 페이지에 대해 먼저 이야기합시다.
검색 페이지에서 중간에있는 이러한 속성 및 브랜드는 검색에 따라 서로 다른 답변을 제공해야하므로 es의 집계 연산을 통해 구현됩니다.
이제 논의 할 또 다른 주제가 있습니다.이 정보는 집계를 통해 어떻게 확보됩니까?
우선 내일 모레 관리자가 선반을 클릭하면 해당 skuId와 해당 spu가 속한 spu 정보가 표시됩니다. 선반에 있으면 데이터베이스에서 확인하고 SkuModel에서 정보를 찾아 캡슐화 한 다음 원격으로 검색 서비스를 호출합니다. 이러한 데이터는 es에 저장됩니다.

ES에 입금하는 방법

다음으로 es 인덱스 매핑의 디자인을 살펴보십시오.

PUT product
{
    
    
  "mappings": {
    
    
    "properties": {
    
    
      "skuId": {
    
    
        "type": "long"
      },
      "spuId": {
    
    
        "type": "long"
      },
      "skuTitle": {
    
    
        "type": "text",//支持全文搜索的
        "analyzer": "ik_smart"//采用ik分词器
      },
      "skuPrice": {
    
    
        "type": "keyword"//必须输入精确值才能搜索
      },
      "skuImg": {
    
    
        "type": "keyword",//必须输入精确值才能搜索
        "index": false,//不能被索引
        "doc_values": false
      },
      "saleCount": {
    
    
        "type": "long"
      },
      "hosStock": {
    
    
        "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
      },
      "catelogName": {
    
    
        "type": "keyword",
        "index": false,
        "doc_values": false
      },
      "attrs": {
    
    
        "type": "nested",//es的嵌套模型
        "properties": {
    
    
          "attrId": {
    
    
            "type": "long"
          },
          "attrName": {
    
    
            "type": "keyword",
            "index": false,
            "doc_values": false
          },
          "attrValue": {
    
    
            "type": "keyword"
          }
        }
      }
    }
  }
}

ES API : RestHighLevelClient를 Java를 통해 운영하여 ES의 추가, 삭제, 수정을 수행 한 후 저장 방법 확인

@Override
    public boolean productStatusUp(List<SkuEsModel> skuEsModels) throws IOException {
    
    

		//1.在es中建立索引,建立号映射关系
        //2. 在ES中保存这些数据
        BulkRequest bulkRequest = new BulkRequest();
        for (SkuEsModel skuEsModel : skuEsModels) {
    
    
            //构造保存请求
            IndexRequest indexRequest = new IndexRequest(EsConstant.PRODUCT_INDEX);
            indexRequest.id(skuEsModel.getSkuId().toString());
            String jsonString = JSON.toJSONString(skuEsModel);
            indexRequest.source(jsonString, XContentType.JSON);
            bulkRequest.add(indexRequest);
        }


        BulkResponse bulk = esRestClient.bulk(bulkRequest, GulimallElasticSearchConfig.COMMON_OPTIONS);

        //TODO 如果批量错误
        boolean hasFailures = bulk.hasFailures();

        List<String> collect = Arrays.asList(bulk.getItems()).stream().map(item -> {
    
    
            return item.getId();
        }).collect(Collectors.toList());

        log.info("商品上架完成:{}",collect);

        return hasFailures;
    }

ES에서 데이터를 확인하는 방법

쿼리 매개 변수, 이러한 매개 변수를 캡슐화하는 모델도 설계했습니다.

@Data
public class SearchParam {
    
    
    /**
     * 页面传递过来的全文匹配关键字
     */
    private String keyword;
    /**
     * 品牌id,可以多选
     */
    private List<Long> brandId;
    /**
     * 三级分类id
     */
    private Long catalog3Id;
    /**
     * 排序条件:sort=price/salecount/hotscore_desc/asc
     */
    private String sort;
    /**
     * 是否显示有货
     */
    private Integer hasStock;
    /**
     * 价格区间查询
     */
    private String skuPrice;
    /**
     * 按照属性进行筛选
     */
    private List<String> attrs;
    /**
     * 页码
     */
    private Integer pageNum = 1;
    /**
     * 原生的所有查询条件
     */
    private String _queryString;
}

이러한 매개 변수를 전달한 다음 es로 이동하여 어셈블리 쿼리에 해당하는 인덱스를 찾고 쿼리 단계를 요약합니다.

  1. 쿼리에 필요한 DSL 문을 동적으로 구성
  2. 검색 요청 준비 : 1퍼지 일치, 필터링 (속성, 분류, 브랜드, 가격 범위, 인벤토리에 따라), 정렬, 페이징, 강조 표시, 집계 분석 2, 집계 : 브랜드 집계, 분류 집계, 속성 집계
  3. 검색 요청 수행
  4. 응답 데이터를 분석하고 필요한 형식으로 캡슐화합니다.
  5. 반환

추천

출처blog.csdn.net/MarkusZhang/article/details/108001353