整合Elasticsearch实现商品搜索
整合Elasticsearch实现商品搜索
本文主要讲解mall整合Elasticsearch的过程,以实现商品信息在Elasticsearch中的导入、查询、修改、删除为例。
项目使用框架介绍
Elasticsearch
Elasticsearch 是一个分布式、可扩展、实时的搜索与数据分析引擎。 它能从项目一开始就赋予你的数据以搜索、分析和探索的能力,可用于实现全文搜索和实时数据统计。
Elasticsearch的安装和使用
- 下载Elasticsearch6.2.2的zip包,并解压到指定目录,下载地址:https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-2-2
- 安装中文分词插件,在elasticsearch-6.2.2\bin目录下执行以下命令:elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.2.2/elasticsearch-analysis-ik-6.2.2.zip
- 运行bin目录下的elasticsearch.bat启动Elasticsearch
- 下载Kibana,作为访问Elasticsearch的客户端,请下载6.2.2版本的zip包,并解压到指定目录,下载地址:https://artifacts.elastic.co/downloads/kibana/kibana-6.2.2-windows-x86_64.zip
- 运行bin目录下的kibana.bat,启动Kibana的用户界面
- 访问http://localhost:5601 即可打开Kibana的用户界面
Spring Data Elasticsearch
Spring Data Elasticsearch是Spring提供的一种以Spring Data风格来操作数据存储的方式,它可以避免编写大量的样板代码。
常用注解
@Document
//标示映射到Elasticsearch文档上的领域对象
public @interface Document {//索引库名次,mysql中数据库的概念String indexName();//文档类型,mysql中表的概念String type() default "";//默认分片数short shards() default 5;//默认副本数量short replicas() default 1;}
Copy to clipboardErrorCopied
@Id
//表示是文档的id,文档可以认为是mysql中表行的概念
public @interface Id {
}
Copy to clipboardErrorCopied
@Field
public @interface Field {//文档中字段的类型FieldType type() default FieldType.Auto;//是否建立倒排索引boolean index() default true;//是否进行存储boolean store() default false;//分词器名次String analyzer() default "";
}
Copy to clipboardErrorCopied
//为文档自动指定元数据类型
public enum FieldType {Text,//会进行分词并建了索引的字符类型Integer,Long,Date,Float,Double,Boolean,Object,Auto,//自动判断字段类型Nested,//嵌套对象类型Ip,Attachment,Keyword//不会进行分词建立索引的类型
}
Copy to clipboardErrorCopied
Sping Data方式的数据操作
继承ElasticsearchRepository接口可以获得常用的数据操作方法
可以使用衍生查询
在接口中直接指定查询方法名称便可查询,无需进行实现,如商品表中有商品名称、标题和关键字,直接定义以下查询,就可以对这三个字段进行全文搜索。
/*** 搜索查询** @param name 商品名称* @param subTitle 商品标题* @param keywords 商品关键字* @param page 分页信息* @return*/Page<EsProduct> findByNameOrSubTitleOrKeywords(String name, String subTitle, String keywords, Pageable page);
Copy to clipboardErrorCopied
在idea中直接会提示对应字段
使用@Query注解可以用Elasticsearch的DSL语句进行查询
@Query("{"bool" : {"must" : {"field" : {"name" : "?0"}}}}")
Page<EsProduct> findByName(String name,Pageable pageable);
Copy to clipboardErrorCopied
项目使用表说明
pms_product
:商品信息表pms_product_attribute
:商品属性参数表pms_product_attribute_value
:存储产品参数值的表
整合Elasticsearch实现商品搜索
在pom.xml中添加相关依赖
<!--Elasticsearch相关依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch<artifactId>
</dependency>
Copy to clipboardErrorCopied
修改SpringBoot配置文件
修改application.yml文件,在spring节点下添加Elasticsearch相关配置。
data:elasticsearch:repositories:enabled: truecluster-nodes: 127.0.0.1:9300 # es的连接地址及端口号cluster-name: elasticsearch # es集群的名称
Copy to clipboardErrorCopied
添加商品文档对象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;@Idprivate 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;//省略了所有getter和setter方法
}
Copy to clipboardErrorCopied
添加EsProductRepository接口用于操作Elasticsearch
继承ElasticsearchRepository接口,这样就拥有了一些基本的Elasticsearch数据操作方法,同时定义了一个衍生查询方法。
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;/*** 商品ES操作类* Created by macro on 2018/6/19.*/
public interface EsProductRepository extends ElasticsearchRepository<EsProduct, Long> {/*** 搜索查询** @param name 商品名称* @param subTitle 商品标题* @param keywords 商品关键字* @param page 分页信息* @return*/Page<EsProduct> findByNameOrSubTitleOrKeywords(String name, String subTitle, String keywords, Pageable page);}
Copy to clipboardErrorCopied
添加EsProductService接口
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 {/*** 从数据库中导入所有商品到ES*/int importAll();/*** 根据id删除商品*/void delete(Long id);/*** 根据id创建商品*/EsProduct create(Long id);/*** 批量删除商品*/void delete(List<Long> ids);/*** 根据关键字搜索名称或者副标题*/Page<EsProduct> search(String keyword, Integer pageNum, Integer pageSize);}
Copy to clipboardErrorCopied
添加EsProductService接口的实现类EsProductServiceImpl
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;/*** 商品搜索管理Service实现类* Created by macro on 2018/6/19.*/
@Service
public class EsProductServiceImpl implements EsProductService {private static final Logger LOGGER = LoggerFactory.getLogger(EsProductServiceImpl.class);@Autowiredprivate EsProductDao productDao;@Autowiredprivate EsProductRepository productRepository;@Overridepublic 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;}@Overridepublic void delete(Long id) {productRepository.deleteById(id);}@Overridepublic 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;}@Overridepublic 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);}}@Overridepublic Page<EsProduct> search(String keyword, Integer pageNum, Integer pageSize) {Pageable pageable = PageRequest.of(pageNum, pageSize);return productRepository.findByNameOrSubTitleOrKeywords(keyword, keyword, keyword, pageable);}}
Copy to clipboardErrorCopied
添加EsProductController定义接口
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;/*** 搜索商品管理Controller* Created by macro on 2018/6/19.*/
@Controller
@Api(tags = "EsProductController", description = "搜索商品管理")
@RequestMapping("/esProduct")
public class EsProductController {@Autowiredprivate EsProductService esProductService;@ApiOperation(value = "导入所有数据库中商品到ES")@RequestMapping(value = "/importAll", method = RequestMethod.POST)@ResponseBodypublic CommonResult<Integer> importAllList() {int count = esProductService.importAll();return CommonResult.success(count);}@ApiOperation(value = "根据id删除商品")@RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)@ResponseBodypublic CommonResult<Object> delete(@PathVariable Long id) {esProductService.delete(id);return CommonResult.success(null);}@ApiOperation(value = "根据id批量删除商品")@RequestMapping(value = "/delete/batch", method = RequestMethod.POST)@ResponseBodypublic CommonResult<Object> delete(@RequestParam("ids") List<Long> ids) {esProductService.delete(ids);return CommonResult.success(null);}@ApiOperation(value = "根据id创建商品")@RequestMapping(value = "/create/{id}", method = RequestMethod.POST)@ResponseBodypublic CommonResult<EsProduct> create(@PathVariable Long id) {EsProduct esProduct = esProductService.create(id);if (esProduct != null) {return CommonResult.success(esProduct);} else {return CommonResult.failed();}}@ApiOperation(value = "简单搜索")@RequestMapping(value = "/search/simple", method = RequestMethod.GET)@ResponseBodypublic 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));}}
Copy to clipboardErrorCopied
进行接口测试
将数据库中数据导入到Elasticsearch
进行商品搜索
项目源码地址
https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-06
整合Elasticsearch实现商品搜索相关推荐
- 商城项目(五)整合Elasticsearch实现商品搜索
商城项目(五)整合Elasticsearch实现商品搜索 环境配置 Elasticsearch Elasticsearch 是一个分布式.可扩展.实时的搜索与数据分析引擎. 它能从项目一开始就赋予你的 ...
- ik分词器实现原理_SpringBoot整合Elasticsearch实现商品搜索
本文主要介绍在Elasticsearch中实现商品搜索功能 中文分词器 Elasticsearch有默认的分词器,默认分词器只是将中文逐词分隔,并不符合我们的需求. get hanzo/_analyz ...
- 谷粒商城--整合Elasticsearch和商品的上架
整合Elasticsearch和商品的上架 一.整合ES ES常用概念 索引,类型,文档是什么? 倒排索引 相关度分数score的计算 安装ES和Kibana 快速安装 ES kibana 初步检索_ ...
- ElasticSearch实现商品搜索与聚合分析
ElasticSearch实现商品搜索与聚合分析 Gitee地址:https://gitee.com/yuyuuyuy/micro-mall 文章目录 ElasticSearch实现商品搜索与聚合分析 ...
- 畅购商城(五):Elasticsearch实现商品搜索
好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 畅购商城(一):环境搭建 畅购商 ...
- Elasticsearch实现商品搜索(关键字查询 条件筛选 规格过滤 价格区间搜索 分页查询 排序查询 高亮查询)
Elasticsearch实现商品搜索 商品搜索 1.根据关键字查询 2.条件筛选 2.1 品牌筛选 2.1.1 需求分析 2.1.2 代码实现 2.2 规格过滤 2.2.1 需求分析 2.2.2 代 ...
- ElasticSearch商城商品搜索实战
在前面文章中主要是对ES的一个入门,那么在生产环境中结合业务ES到底是如何使用的呢? 本文将讲解电商品平台商城系统如何使用ES做商品搜索功能. 如何达到更高效的分词 : 怎么分词 : 分词器的使用 : ...
- Elasticsearch构建商品搜索系统
搜索这个特性可以说是无处不在,现在很少有网站或者系统不提供搜索功能了,所以,即使你不是一个专业做搜索的程序员,也难免会遇到一些搜索相关的需求.搜索这个东西,表面上看功能很简单,就是一个搜索框,输入关键 ...
- Elasticsearch项目实战,商品搜索功能设计与实现!
推荐大家去看原文博主的文章,条理清晰阅读方便,转载是为了方便以后个人查阅 https://juejin.im/post/5e94587f51882573be11cb83?utm_source=gold ...
最新文章
- c语言链表容易犯的错误,急求大牛啊这个容易的链表到底在哪出错了
- 589-N叉树的前序遍历
- HTML+CSS+JS实现 ❤️美女拼图游戏❤️
- 软件测试完后,还有bug,责任全在于测试吗?
- MySQL binlog相关分析
- 【目标检测】(12) 非极大值抑制 NMS 和 Soft-NMS,附TensorFlow完整代码
- CRACK小试牛刀:关于GALGAME银色遥远爆破记录
- Mac 无法打开淘宝,天猫,京东等
- 关于eml邮件解压使用
- 同步消息和异步消息传递的区别?
- 物联网的好处_物联网的应用前景
- python爬虫和数据分析的书籍_豆瓣书籍数据爬取与分析
- SSL证书的加密算法都有哪些?
- 深入探索Win32结构化异常处理
- 正则表达式30分钟入门
- matlab学习-大小写字符转发
- Elixir: 魔术符号
- 概率论期末基础复习要点
- 关于在软件开发过程中建立三道风险防线的想法
- 分布式光伏发电计及气象因子及出力预测方法研究(Matlab代码实现)