集成Elasticsearch实现简单搜索

  • 目录
    • 前言
    • es版本说明
    • 整合es
      • 线程池管理
      • api说明
    • 码上有戏
      • 测试
      • 源码地址
      • 参考文章

目录

前言

Elasticsearch是一个基于Lucene的服务器。它提供了在分布式环境下多用户能力的全文搜索引擎,并且它是基于Restful-web接口进行操作。而它的社区地址为中文社区,相应官网地址为客户端,而本次使用的服务器版本为7.6.0

es版本说明

es的版本迭代是非常快的,而其中大的变化如下所示
5.x 一个index->多个type
6.x 一个index->一个type
7.x 移除type,直接操作index
笔者以前工作中使用的是6.x版本,主要基于TransportClient基于连接,采用门面模式去集成es和封装,如下

而此次将集成7.x版本,并采用同样的策略,集成es和使用门面模式,是调用者不需要关心实现细节

整合es

最终实现的功能为创建索引,同步与异步批量操作,删除索引以及高亮查询和最基本的CRUD操作

线程池管理

I 增加核心依赖

<properties><es.version>7.8.0</es.version></properties><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>${es.version}</version></dependency><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>${es.version}</version><scope>compile</scope></dependency>

II RestHighLevelClient连接类

 private static RestHighLevelClient client;/*** 服务器地址*/private static String host = "your es ip";/*** 端口*/private static int port = 9200;/*** 用户名*/private static String user = "";/*** 密码*/private static String password = "";public EsModel() {try {RestClientBuilder clientBuilder = RestClient.builder(new HttpHost(host, port, "http"));if (StringUtils.isNotBlank(user) && StringUtils.isNotBlank(password)) {CredentialsProvider credentialsProvider = new BasicCredentialsProvider();credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(user, password));clientBuilder.setHttpClientConfigCallback(httpAsyncClientBuilder -> {httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);httpAsyncClientBuilder.setKeepAliveStrategy((resp, context) -> 30);return httpAsyncClientBuilder;});} else {clientBuilder.setHttpClientConfigCallback(httpAsyncClientBuilder -> {httpAsyncClientBuilder.setKeepAliveStrategy((resp, context) -> 30);return httpAsyncClientBuilder;});}client = new RestHighLevelClient(clientBuilder);} catch (Exception e) {e.printStackTrace();}}

有了连接之后,就可以实现各种底层api,供上层直接调用

III 创建工厂EsFactory

public class EsFactory extends BasePooledObjectFactory<EsModel> {@Overridepublic EsModel create() throws Exception {return new EsModel();}@Overridepublic PooledObject<EsModel> wrap(EsModel arg0) {return new DefaultPooledObject<EsModel>(arg0);}@Overridepublic void destroyObject(PooledObject<EsModel> p) throws Exception {p.getObject().close();super.destroyObject(p);}}

IV 门面工具类EsUtil
最后的效果通过线程池管理连接,该工具类对外提供封装方法,如下图

api说明

1 自定义注解
通过自定义注解从而实现配置实体类型,分词规则等

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ES {/*** @string text ,keyword* @Number long, integer, short, byte, double, float, half_float, scaled_float* @date date* @date_nanos date_nanos* @Range integer_range, float_range, long_range, double_range, date_range* @binary binary* @Nested nested*/String type() default "string";/*** 分词器选择  0. not_analyzed   1. ik_smart 2. ik_max_word*/int participle() default 0;
}

其它如EsMapping用来存放解析后的实体对象,EsMappingUtils用来解析实体上的注解信息

2 封装查询条件
将可能用到的参数封装到EsParamDto

@Data
public class EsParamDto implements Serializable {/*** 数据总条数*/private Long total;/*** 当前页*/private int page = 1;/*** 每页大小*/private int size = 1;/*** 是否分页*/private Boolean isPage = true;/*** 区间查询参数*/private Map<String, RangConditionDTO> rangConditionMap = new HashMap<>();/*** 时间区间查询参数*/private Map<String, RangConditionsToTimeModelDTO> rangConditionsToTimeModelMap = new HashMap<>();/*** 模糊相等查询条件,多个查询条件","进行切割*/private Map<String, Object> likeSearchCondition = new HashMap<>();/*** or条件查询*/private Map<String, Object> orSearchCondition = new HashMap<>();/*** or条件查询*/private Map<String, Object> orLikeSearchCondition = new HashMap<>();/*** or条件查询集合类操作*/private List<Map<String, Object>> orSearchConditionList = new ArrayList<>();/*** 相等查询条件,多个查询条件","进行切割*/private Map<String, Object> equalsSearchCondition = new HashMap<>();/*** in 查询*/private Map<String, List> inSearchCondition = new HashMap<>();/*** 模糊不相等的条件,多个查询条件","进行切割*/private Map<String, Object> noLikeSearchConditioin = new HashMap<>();/*** 不相等的条件,多个查询条件","进行切割*/private Map<String, Object> noEqualsSearchConditioin = new HashMap<>();/*** 为空过滤*/private List<String> isNullConditioin = new ArrayList<>();/*** 不为空过滤*/private List<String> isNotNullConditioin = new ArrayList<>();/*** 排序字段,关键字asc,desc*/private Map<String, String> sortFileds = new LinkedHashMap<>();/*** 排序字段集合,方便对排序顺序的控制 关键字asc,desc*/private List<Map<String, String>> sortFiledsList = new ArrayList<>();/*** 高亮字段*/private List<String> hightFieldList = new ArrayList<>();/*** 去重字段*/private String collapseField;/*** 指定查询结果包含的字段*/private String[] fetchSourceIncludes;/*** 指定查询结果不包含的字段*/private String[] fetchSourceExcludes;/*** 分词字段*/private Map<String, Object> analyzersField = new HashMap<>();public String getSortFileds(String key) {return sortFileds.get(key);}public RangConditionDTO getRangConditionMap(String key) {return rangConditionMap.get(key);}public RangConditionsToTimeModelDTO getRangConditionsToTimeModelMap(String key) {return rangConditionsToTimeModelMap.get(key);}}

其中RangConditionDTO用来区间查询,而RangConditionsToTimeModelDTO用来时间区间查询

3 封装返回数据

@Data
public class PageResult<T> {/*** 数据总条数*/private Long total;/*** 当前页*/private int page;/*** 每页大小*/private int size;/*** 数据*/private List<T> rows;
}

而底层api实现细节可参考EsModel的方法实现细节

码上有戏

测试

新建EsTestModel作为mapping的类

@Data
public class EsTestModel implements Serializable {private String id;private String userName;private String password;@ES(type = "integer")private int age;
}

可通过注解@ES去建立映射关系

1 测试批量新增
浏览器输入http://localhost:8080/init

 @RequestMapping("/init")public boolean init() {String index = "test";List<EsTestModel> list = new ArrayList<>();EsTestModel po = null;for (int i = 0; i < 10; i++) {po = new EsTestModel();po.setId(i + "");po.setUserName("admin" + i);po.setAge(i);list.add(po);}String paramListJson = JSON.toJSONString(list);boolean b = EsUtil.addBatch(index, "id", paramListJson, EsTestModel.class);return b;}

执行上述代码,打开kabana里的dev模式,进行数据查看
输入GET test/_search?pretty

结果

{"took" : 0,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 10,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "test","_type" : "_doc","_id" : "0","_score" : 1.0,"_source" : {"id" : "0","userName" : "admin0","age" : 0}},{"_index" : "test","_type" : "_doc","_id" : "1","_score" : 1.0,"_source" : {"id" : "1","userName" : "admin1","age" : 1}},{"_index" : "test","_type" : "_doc","_id" : "2","_score" : 1.0,"_source" : {"id" : "2","userName" : "admin2","age" : 2}},{"_index" : "test","_type" : "_doc","_id" : "3","_score" : 1.0,"_source" : {"id" : "3","userName" : "admin3","age" : 3}},{"_index" : "test","_type" : "_doc","_id" : "4","_score" : 1.0,"_source" : {"id" : "4","userName" : "admin4","age" : 4}},{"_index" : "test","_type" : "_doc","_id" : "5","_score" : 1.0,"_source" : {"id" : "5","userName" : "admin5","age" : 5}},{"_index" : "test","_type" : "_doc","_id" : "6","_score" : 1.0,"_source" : {"id" : "6","userName" : "admin6","age" : 6}},{"_index" : "test","_type" : "_doc","_id" : "7","_score" : 1.0,"_source" : {"id" : "7","userName" : "admin7","age" : 7}},{"_index" : "test","_type" : "_doc","_id" : "8","_score" : 1.0,"_source" : {"id" : "8","userName" : "admin8","age" : 8}},{"_index" : "test","_type" : "_doc","_id" : "9","_score" : 1.0,"_source" : {"id" : "9","userName" : "admin9","age" : 9}}]}
}

2 测试更新操作
浏览器输入http://localhost:8080/update

  @RequestMapping("/update")public boolean update() {String index = "test";String id = "0";EsTestModel po = new EsTestModel();po.setAge(100);po.setUserName("slycmiaoxi");String paramJson = JSON.toJSONString(po);boolean b = EsUtil.update(index, id, paramJson);return b;}

客户端输入图示请求,结果如下所示


3 测试高亮显示
浏览器输入http://localhost:8080/query

 @RequestMapping("/query")public String query() {EsParamDto dto = new EsParamDto();dto.setIsPage(true);dto.setTotal(3L);Map<String, Object> equalsSearchCondition = new HashMap<>();equalsSearchCondition.put("id", 1);dto.setEqualsSearchCondition(equalsSearchCondition);List<String> hightFieldList = new ArrayList<>();hightFieldList.add("age");dto.setHightFieldList(hightFieldList);PageResult result = EsUtil.query(dto, "test");return result.toString();}

返回结果

PageResult(total=1, page=0, size=1, rows=[{item=1, id=1, userName=admin1, age=1}])

源码地址

github地址

参考文章

  • https://www.cnblogs.com/java-spring/p/11721615.html
  • https://blog.csdn.net/li521wang/article/details/103522824

springboot之整合Elasticsearch实现搜索相关推荐

  1. SpringBoot Data整合ElasticSearch

    SpringBoot Data整合ElasticSearch pom依赖 <!-- spring data和es的start依赖,会引入关联的elasticsearch-rest-high-le ...

  2. 【SpringBoot】整合Elasticsearch 操作索引及文档

    官网操作文档:Elasticsearch Clients | Elastic 踩坑太多了...这里表明一下Spring Boot2.4以上版本可能会出现问题,所以我降到了2.2.1.RELEASE.对 ...

  3. SpringBoot进阶教程(七十三)整合elasticsearch

    Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/cou ...

  4. Springboot 整合 ElasticSearch 入门教学必看

    ElasticSearch 相比搜到这篇文章的人,都已经有过对它的了解, 一种流行的企业级搜索引擎,是一个分布式,高性能.高可用.可伸缩的搜索和分析系统. 那么用我粗俗的言语来说,它就是提供一个存储数 ...

  5. 微服务商城系统(六)商品搜索 SpringBoot 整合 Elasticsearch

    文章目录 一.Elasticsearch 和 IK 分词器的安装 二.Kibana 使用 三.数据导入 Elasticsearch 1.SpringData Elasticsearch 介绍 2.搜索 ...

  6. es springboot 不设置id_原创 | 一篇解决Springboot 整合 Elasticsearch

    ElasticSearch 结合业务的场景,在目前的商品体系需要构建搜索服务,主要是为了提供用户更丰富的检索场景以及高速,实时及性能稳定的搜索服务. ElasticSearch是一个基于Lucene的 ...

  7. SpringBoot 2.x (12):整合Elasticsearch

    Elasticsearch:一个优秀的搜索引擎框架 搜索方面最基本的是SQL的like语句 进一步的有Lucene框架 后来有企业级的Solr框架 而Elasticsearch框架尤其适合于数据量特别 ...

  8. springboot整合elasticsearch_Spring Boot学习10_整合Elasticsearch

    一.Elasticsearch概念 •以 员工文档 的形式存储为例:一个文档代表一个员工数据.存储数据到 ElasticSearch 的行为叫做 索引 ,但在索引一个文档之前,需要确定将文档存储在哪里 ...

  9. SpringBoot整合ElasticSearch实现多版本的兼容

    前言 在上一篇学习SpringBoot中,整合了Mybatis.Druid和PageHelper并实现了多数据源的操作.本篇主要是介绍和使用目前最火的搜索引擎ElastiSearch,并和Spring ...

最新文章

  1. 基于MTCNN的人脸自动对齐技术原理及其Tensorflow实现测试
  2. 小雷郑重承诺:在2017年之前,对大学毕业4年以来的所有努力和探索,做一个全面客观的总结,技术研究、工作创业、投资理财、朋友感情等...
  3. 智慧赋能黔货出山 丰收节交易会·李喜贵:贵州农业数字化
  4. R开发(part1)--R语言知识体系结构
  5. 尤雨溪推荐神器 ni ,能替代 npm/yarn/pnpm ?简单好用!源码揭秘!
  6. 嵌入式开发linux工具,嵌入式Linux开发入门之MfgTool工具的使用
  7. 初一模拟赛(4.27)
  8. npm link run npm script
  9. JavaScript 稳居第一、C# 连续下跌,调查 17000 名程序员后有了这些新发现!
  10. 阿里开源物联网操作系统 AliOS Things 3.0 发布,集成平头哥 AI 芯片架构!
  11. c# 进程间的通信实现之一简单字符串收发
  12. SWAT模型气象数据处理(一)
  13. Android network基础知识 — IPv4和IPv6的区别
  14. 如何形成自己的的绘画风格?/ Bookness插画教程分享
  15. 知乎周源微信_每周源代码16-风管磁带版
  16. csv文件转换成xlsx文件方法
  17. 点微同城小程序配置教程及提交审核包过审经验分享
  18. 手机版本android升级包下载,ColorOS8.0升级包下载安装-oppo手机系统ColorOS8.0正式版升级包下载 安卓版 v1.0- 游娱下载站...
  19. 和LinkedSee灵犀一起备战GITC全球互联网技术大会
  20. nltk安装,语料库nltk下载

热门文章

  1. 最好的OCR识别(图片转换文字)工具:ABBYY FineReader
  2. 图层样式之:内发光、外发光
  3. 【Puppeteer】基于Puppeteer采集网页图片资源
  4. 小虎电商浏览器:多多打单电子面单怎么开通
  5. 如何合并音频文件图文教程
  6. 为subclipse配置http代理,解决“RA layer request failed, Unable to connect to a repository at URL ... 错误
  7. django之数据库操作
  8. EditPlus设置保存时不生成bak文件
  9. PPT技能速成班学习笔记
  10. 是什么让区块链游戏变的“好玩”