How to use Elasticsearch in the project

Preface

The product search module is involved in the project. Through learning ES knowledge, I try to apply ES to the project. This blog mainly describes how I use ES in the project. Since the Alibaba Cloud server we bought together has expired, we will not demonstrate it here. You must buy a good server for future work

If you also want to install ES and Kibana, you can follow my previous blog to build a
portal <---- click here

Model of data in ES

If you want to check data from ES, you first need to store the data in ES. At that time, I discussed with my classmates to import the data directly in Kibana, but when I think about it, this is too much trouble. Later, I thought that the backstage management written by my classmates had products. The functions on the shelves, and then start from here.

Model design

Take a look at the model we designed:

@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;
    }
}

Why design like this

First, let’s talk about what businesses in the mall use es:

  • Enter the search page through the three-level directory of the three-level list on the mall homepage
  • Enter the name of the product you want to search through the search box on the homepage of the mall, and return the data by checking es

If you click to enter in the third-level directory, a category id parameter will be passed, so there should be a category id in the model to provide search, and then if you enter through the search box, a String parameter will be passed, which matches the title of the sku product.
So through these searches, what data do I need to provide the front end to render on the details page?
Insert picture description here
The above screenshots are from JD.com. My classmates imitated some functions based on JD’s page. After reading the annotations in the picture, you should understand why the model is so designed. However, there are some other fields, which are related to the product detail page. Let's talk about this search page first.
In the search page, these attributes and brands in the middle need to give different answers according to different searches, so they are realized through the aggregation operation in es.
Now there is still another topic for discussion: how is this information obtained through aggregation?
First of all, the day after tomorrow the administrator clicks on the shelf, there will be the corresponding skuId and the information of the spu to which it belongs. When it is on the shelf, we will check it in the database, find and encapsulate the information in the SkuModel, and call the search service remotely. These data are stored in es.

How to deposit into ES

Next, look at the design of es index mapping:

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"
          }
        }
      }
    }
  }
}

Operate ES API: RestHighLevelClient through java to operate the addition, deletion, modification and check of ES, and then see how to save it

@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;
    }

How to check data from ES

Query parameters, we also designed a model to encapsulate these parameters

@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;
}

Through these parameters, then go to es to find the corresponding index for assembly query, and summarize my query steps:

  1. Dynamically construct the DSL statements needed for the query
  2. Prepare search request: 1Fuzzy matching, filtering (according to attributes, classification, brand, price range, inventory), sorting, paging, highlighting, aggregation analysis 2, aggregation: brand aggregation, classification aggregation, attribute aggregation
  3. Perform retrieval request
  4. Analyze the response data and encapsulate it into the format we need
  5. return

Guess you like

Origin blog.csdn.net/MarkusZhang/article/details/108001353