Abstract

This article describes how to import, query, modify, and delete product information from Elasticsearch using Mall. Elasticsearch is a distributed, scalable, real-time search and data analysis engine. It enables you to search, analyze, and explore your data from the start of a project, enabling full text search and real-time data statistics.

Project use framework introduction

Elasticsearch

Elasticsearch is a distributed, scalable, real-time search and data analysis engine. It enables you to search, analyze, and explore your data from the start of a project, enabling full text search and real-time data statistics.

Install and use Elasticsearch

  1. Download Elasticsearch6.2.2 zip and unzip to the specified directory, download address: www.elastic.co/cn/download…

  1. Elasticsearch -plugin install github.com/medcl/elast…

  1. Run elasticSearch. bat in the bin directory to start ElasticSearch

  1. Download Kibana, as a visiting Elasticsearch client, please download the 6.2.2 version of the zip, and extract the to the specified directory, download address: artifacts. Elastic. Co/downloads/k…

  1. Run kibana.bat in the bin directory to start the Kibana user interface

  1. Visit http://localhost:5601 to open the Kibana user interface

Spring Data Elasticsearch

Spring Data Elasticsearch is a Spring Data style way to manipulate Data stores without writing a lot of boilerplate code.

Commonly used annotations

@Document
// identifies the domain object mapped to the Elasticsearch document
public @interface Document {
  // Index library name, mysql database concept
	String indexName(a);
  // Document type, mysql table concept
	String type(a) default "";
  // Default number of fragments
	short shards(a) default 5;
  // Default number of copies
	short replicas(a) default 1;

}
Copy the code

@Id

// represents the id of a document, which can be thought of as the concept of a table row in mysql
public @interface Id {
}
Copy the code

@Field

public @interface Field {
  // The type of the field in the document
	FieldType type(a) default FieldType.Auto;
  // Whether to create inverted index
	boolean index(a) default true;
  // Whether to store
	boolean store(a) default false;
  // participle ranking
	String analyzer(a) default "";
}
Copy the code
// Automatically specify metadata types for documents
public enum FieldType {
	Text,// A character type that is segmented and indexed
	Integer,
	Long,
	Date,
	Float,
	Double,
	Boolean,
	Object,
	Auto,// Automatically determine the field type
	Nested,// Nested object types
	Ip,
	Attachment,
	Keyword// The type of index that will not be segmented
}
Copy the code

Sping Data Data operations

Inherit the ElasticsearchRepository interface to obtain common data manipulation methods

You can use derived queries

You can directly specify the name of the query method on the interface. For example, if the product table contains the product name, title, and keyword, you can directly define the following query to perform full-text search for these three fields.

    /** * search query **@paramName Commodity name *@paramSubTitle Product title *@paramKeywords commodity keywords *@paramPage page information *@return* /
    Page<EsProduct> findByNameOrSubTitleOrKeywords(String name, String subTitle, String keywords, Pageable page);
Copy the code

The corresponding field is displayed in IDEA

Use the @Query annotation to Query with Elasticsearch’s DSL statement
@Query("{"bool": {"must": {"field": {"name":"?0"}}}}")
Page<EsProduct> findByName(String name,Pageable pageable);
Copy the code

Project usage table description

  • pms_product: Commodity information sheet
  • pms_product_attribute: Commodity attribute parameter list
  • pms_product_attribute_value: a table of storage product parameter values

Implement commodity search with Elasticsearch

Add related dependencies in pom.xml

<! --Elasticsearch dependencies -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch<artifactId>
</dependency>
Copy the code

Example Modify the SpringBoot configuration file

Modify the application.yml file and add Elasticsearch configuration under the Spring node.

data:
  elasticsearch:
    repositories:
      enabled: true
    cluster-nodes: 127.0. 01.: 9300 # es connection address and port number
    cluster-name: elasticsearch # es cluster name
Copy the code

Add the product document object EsProduct

Field(type = fieldtype.keyword); Field(Analyzer = “ik_max_word”,type = fieldtype.text).

package com.macro.mall.tiny.nosql.elasticsearch.document;

import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

/** * Created by macro on 2018/6/19. */
@Document(indexName = "pms", type = "product",shards = 1,replicas = 0)
public class EsProduct implements Serializable {
    private static final long serialVersionUID = -1L;
    @Id
    private Long id;
    @Field(type = FieldType.Keyword)
    private String productSn;
    private Long brandId;
    @Field(type = FieldType.Keyword)
    private String brandName;
    private Long productCategoryId;
    @Field(type = FieldType.Keyword)
    private String productCategoryName;
    private String pic;
    @Field(analyzer = "ik_max_word",type = FieldType.Text)
    private String name;
    @Field(analyzer = "ik_max_word",type = FieldType.Text)
    private String subTitle;
    @Field(analyzer = "ik_max_word",type = FieldType.Text)
    private String keywords;
    private BigDecimal price;
    private Integer sale;
    private Integer newStatus;
    private Integer recommandStatus;
    private Integer stock;
    private Integer promotionType;
    private Integer sort;
    @Field(type =FieldType.Nested)
    private List<EsProductAttributeValue> attrValueList;

    // omits all getters and setters
}

Copy the code

Add the EsProductRepository interface to manipulate Elasticsearch

Inheriting the ElasticsearchRepository interface, you now have some basic Elasticsearch data manipulation methods and a derived query method defined.

package com.macro.mall.tiny.nosql.elasticsearch.repository;

import com.macro.mall.tiny.nosql.elasticsearch.document.EsProduct;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

/** * Created by macro on 2018/6/19. */
public interface EsProductRepository extends ElasticsearchRepository<EsProduct.Long> {
    /** * search query **@paramName Commodity name *@paramSubTitle Product title *@paramKeywords commodity keywords *@paramPage page information *@return* /
    Page<EsProduct> findByNameOrSubTitleOrKeywords(String name, String subTitle, String keywords, Pageable page);

}

Copy the code

Example Add the EsProductService interface

package com.macro.mall.tiny.service;

import com.macro.mall.tiny.nosql.elasticsearch.document.EsProduct;
import org.springframework.data.domain.Page;

import java.util.List;

/** * Service * Created by macro on 2018/6/19. */
public interface EsProductService {
    /** * import all items from the database into ES */
    int importAll(a);

    /** * Delete item */ by id
    void delete(Long id);

    /** * Create item */ based on id
    EsProduct create(Long id);

    /** * Delete items */
    void delete(List<Long> ids);

    /** * Search by keyword for name or subtitle */
    Page<EsProduct> search(String keyword, Integer pageNum, Integer pageSize);

}

Copy the code

Add the implementation class EsProductServiceImpl for the EsProductService interface

package com.macro.mall.tiny.service.impl;

import com.macro.mall.tiny.dao.EsProductDao;
import com.macro.mall.tiny.nosql.elasticsearch.document.EsProduct;
import com.macro.mall.tiny.nosql.elasticsearch.repository.EsProductRepository;
import com.macro.mall.tiny.service.EsProductService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


/** * Created by macro on 2018/6/19. */
@Service
public class EsProductServiceImpl implements EsProductService {
    private static final Logger LOGGER = LoggerFactory.getLogger(EsProductServiceImpl.class);
    @Autowired
    private EsProductDao productDao;
    @Autowired
    private EsProductRepository productRepository;

    @Override
    public int importAll(a) {
        List<EsProduct> esProductList = productDao.getAllEsProductList(null);
        Iterable<EsProduct> esProductIterable = productRepository.saveAll(esProductList);
        Iterator<EsProduct> iterator = esProductIterable.iterator();
        int result = 0;
        while (iterator.hasNext()) {
            result++;
            iterator.next();
        }
        return result;
    }

    @Override
    public void delete(Long id) {
        productRepository.deleteById(id);
    }

    @Override
    public EsProduct create(Long id) {
        EsProduct result = null;
        List<EsProduct> esProductList = productDao.getAllEsProductList(id);
        if (esProductList.size() > 0) {
            EsProduct esProduct = esProductList.get(0);
            result = productRepository.save(esProduct);
        }
        return result;
    }

    @Override
    public void delete(List<Long> ids) {
        if(! CollectionUtils.isEmpty(ids)) { List<EsProduct> esProductList =new ArrayList<>();
            for (Long id : ids) {
                EsProduct esProduct = newEsProduct(); esProduct.setId(id); esProductList.add(esProduct); } productRepository.deleteAll(esProductList); }}@Override
    public Page<EsProduct> search(String keyword, Integer pageNum, Integer pageSize) {
        Pageable pageable = PageRequest.of(pageNum, pageSize);
        returnproductRepository.findByNameOrSubTitleOrKeywords(keyword, keyword, keyword, pageable); }}Copy the code

Add the EsProductController definition interface

package com.macro.mall.tiny.controller;

import com.macro.mall.tiny.common.api.CommonPage;
import com.macro.mall.tiny.common.api.CommonResult;
import com.macro.mall.tiny.nosql.elasticsearch.document.EsProduct;
import com.macro.mall.tiny.service.EsProductService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/** * Created by macro on 2018/6/19. */
@Controller
@Api(tags = "EsProductController", description = "Search product Management")
@RequestMapping("/esProduct")
public class EsProductController {
    @Autowired
    private EsProductService esProductService;

    @ApiOperation(value = "Import all database items into ES")
    @RequestMapping(value = "/importAll", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<Integer> importAllList(a) {
        int count = esProductService.importAll();
        return CommonResult.success(count);
    }

    @ApiOperation(value = "Delete goods by ID")
    @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<Object> delete(@PathVariable Long id) {
        esProductService.delete(id);
        return CommonResult.success(null);
    }

    @ApiOperation(value = "Batch delete goods by ID")
    @RequestMapping(value = "/delete/batch", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<Object> delete(@RequestParam("ids") List<Long> ids) {
        esProductService.delete(ids);
        return CommonResult.success(null);
    }

    @ApiOperation(value = "Create goods based on ID")
    @RequestMapping(value = "/create/{id}", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<EsProduct> create(@PathVariable Long id) {
        EsProduct esProduct = esProductService.create(id);
        if(esProduct ! =null) {
            return CommonResult.success(esProduct);
        } else {
            returnCommonResult.failed(); }}@ApiOperation(value = "Simple search")
    @RequestMapping(value = "/search/simple", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<CommonPage<EsProduct>> search(@RequestParam(required = false) String keyword,
                                                      @RequestParam(required = false, defaultValue = "0") Integer pageNum,
                                                      @RequestParam(required = false, defaultValue = "5") Integer pageSize) {
        Page<EsProduct> esProductPage = esProductService.search(keyword, pageNum, pageSize);
        returnCommonResult.success(CommonPage.restPage(esProductPage)); }}Copy the code

Performing interface tests

Import data from the database into Elasticsearch

Conducting product Search

Project source code address

Github.com/macrozheng/…

The public,

Mall project full set of learning tutorials serialized, attention to the public number the first time access.