SpringBoot e-commerce project mall (20k+star) address: https://github.com/macrozheng/mall
abstract
This paper mainly explains the process of mall integrating Elastic search to realize the import, query, modification and deletion of commodity information in Elastic search.
Introduction to Project Usage Framework
Elasticsearch
Elastic search is a distributed, scalable, real-time search and data analysis engine. It gives you the ability to search, analyze and explore data from the beginning of the project, and can be used to achieve full-text search and real-time data statistics.
Installation and Use of Elasticsearch
- Download the zip package of Elastic search 6.2.2 and extract it to the specified directory. Download the address: https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-2-2
- Install the Chinese word segmentation plug-in and execute the following commands in the elastic search-6.2.2bin directory: elastic search-plugin install https://github.com/medcl/elas...
- Run elastic search. bat under bin directory to start Elastic search
- Download Kibana as a client to access Elastic search. Download the 6.2.2 zip package and extract it to the specified directory. Download the address: https://artifacts.elastic.co/downloads/kibana/kibana-6.2.2-windows-x86_64.zip
- Run kibana.bat under bin directory to start Kibana's user interface
- Visit http://localhost:5601 You can open Kibana's user interface
Spring Data Elasticsearch
Spring Data Elastic search is a Spring-provided way to manipulate data storage in Spring Data style, which can avoid writing a lot of template code.
Common Notes
@Document
//Marking Domain Objects Mapped to Elastic Search Documents public @interface Document { //Index database ranking, the concept of database in mysql String indexName(); //Document type, the concept of tables in mysql String type() default ""; //Default number of fragments short shards() default 5; //Default number of copies short replicas() default 1; }
@Id
//Representation is the id of the document, which can be considered the concept of table rows in mysql public @interface Id { }
@Field
public @interface Field { //Types of fields in documents FieldType type() default FieldType.Auto; //Whether to establish inverted index boolean index() default true; //Storage or not boolean store() default false; //Segmenter rank String analyzer() default ""; }
//Automatically specify metadata types for documents public enum FieldType { Text,//Word segmentation is performed and the character type of the index is established. Integer, Long, Date, Float, Double, Boolean, Object, Auto,//Automatically determine field type Nested,//Nested object types Ip, Attachment, Keyword//Types of indexing that do not perform word segmentation }
Data Operation in Sping Data Mode
Common data manipulation methods can be obtained by inheriting Elastic search Repository interface
Derivative queries can be used
The query method name can be directly specified in the interface. Without implementation, such as commodity name, title and keyword in the commodity table, the following query can be directly defined, and the three fields can be searched in full text.
/** * Search query * * @param name Name of commodity * @param subTitle Commodity Title * @param keywords Commodity keywords * @param page Paging information * @return */ Page<EsProduct> findByNameOrSubTitleOrKeywords(String name, String subTitle, String keywords, Pageable page);
The corresponding fields are prompted directly in the idea
Using the @Query annotation, you can query with the DSL statement of Elastic search
@Query("{"bool" : {"must" : {"field" : {"name" : "?0"}}}}") Page<EsProduct> findByName(String name,Pageable pageable);
Description of Project Use Table
- pms_product: Commodity Information Table
- pms_product_attribute: Commodity attribute parameter table
- pms_product_attribute_value: A table that stores product parameter values
Integrating Elastic search to realize commodity search
Adding dependencies to pom.xml
<!--Elasticsearch Relevant dependency--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch<artifactId> </dependency>
Modify SpringBoot configuration file
Modify the application.yml file and add Elastic search related configuration under the spring node.
data: elasticsearch: repositories: enabled: true cluster-nodes: 127.0.0.1:9300 # Connecting address and port number of es cluster-name: elasticsearch # Name of es cluster
Add commodity document object EsProduct
Fields without Chinese word segmentation need to be set to the @Field(type = FieldType.Keyword) type, and Chinese word segmentation needs to be set to the @Field (analyzer = ik_max_word), type = FieldType. Text) type.
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; /** * Commodity Information in Search * 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; //All getter and setter methods are omitted }
Add the EsProduct Repository interface to operate Elastic search
By inheriting the Elastic search Repository interface, we have some basic data manipulation methods for Elastic search and define a derivative query method.
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; /** * Commodity ES Operating Class * Created by macro on 2018/6/19. */ public interface EsProductRepository extends ElasticsearchRepository<EsProduct, Long> { /** * Search query * * @param name Name of commodity * @param subTitle Commodity Title * @param keywords Commodity keywords * @param page Paging information * @return */ Page<EsProduct> findByNameOrSubTitleOrKeywords(String name, String subTitle, String keywords, Pageable page); }
Add the EsProduct Service 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; /** * Commodity Search Management Service * Created by macro on 2018/6/19. */ public interface EsProductService { /** * Import all items from the database to ES */ int importAll(); /** * Delete goods according to id */ void delete(Long id); /** * Create goods based on id */ EsProduct create(Long id); /** * Bulk Delete Goods */ void delete(List<Long> ids); /** * Search for names or subtitles based on keywords */ Page<EsProduct> search(String keyword, Integer pageNum, Integer pageSize); }
Implementing class EsProduct Service Impl with EsProduct Service 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; /** * Commodity Search Management Service Implementation Class * 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() { 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 = new EsProduct(); 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); return productRepository.findByNameOrSubTitleOrKeywords(keyword, keyword, keyword, pageable); } }
Adding EsProduct Controller 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; /** * Search Commodity Management Controller * Created by macro on 2018/6/19. */ @Controller @Api(tags = "EsProductController", description = "Search Commodity Management") @RequestMapping("/esProduct") public class EsProductController { @Autowired private EsProductService esProductService; @ApiOperation(value = "Import all items in the database to ES") @RequestMapping(value = "/importAll", method = RequestMethod.POST) @ResponseBody public CommonResult<Integer> importAllList() { int count = esProductService.importAll(); return CommonResult.success(count); } @ApiOperation(value = "according to id Delete goods") @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET) @ResponseBody public CommonResult<Object> delete(@PathVariable Long id) { esProductService.delete(id); return CommonResult.success(null); } @ApiOperation(value = "according to id Bulk Delete Goods") @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 = "according to id Creating Commodities") @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 { return CommonResult.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); return CommonResult.success(CommonPage.restPage(esProductPage)); } }
Interface testing
Import data from the database into Elastic search
Goods Search
Project source address
https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-06
Public Number
mall project In the whole series of learning courses, we pay attention to the first time acquisition of the public number.