ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。

1、SpringBoot整合ElasticSearch

1.1 核心依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  4. <version>${spring-boot.version}</version>
  5. </dependency>

1.2 配置文件

  1. spring:
  2. application:
  3. name: ware-elastic-search
  4. data:
  5. elasticsearch:
  6. # 默认 elasticsearch
  7. cluster-name: elasticsearch
  8. # 9200作为Http协议,主要用于外部通讯
  9. # 9300作为Tcp协议,jar之间就是通过tcp协议通讯
  10. cluster-nodes: 192.168.72.130:9300

1.3 实体类配置

Document 配置

  1. 加上了@Document注解之后,默认情况下这个实体中所有的属性都会被建立索引、并且分词。
  2. indexName索引名称 理解为数据库名 限定小写
  3. type 理解为数据库的表名称
  4. shards = 5 默认分区数
  5. replicas = 1 每个分区默认的备份数
  6. refreshInterval = "1s" 刷新间隔
  7. indexStoreType = "fs" 索引文件存储类型

源码配置

  1. @Document(indexName = "requestlogindex",type = "requestlog")
  2. public class RequestLog {
  3. //Id注解Elasticsearch里相应于该列就是主键,查询时可以使用主键查询
  4. @Id
  5. private Long id;
  6. private String orderNo;
  7. private String userId;
  8. private String userName;
  9. private String createTime;
  10. }

1.4 数据交互层

实现ElasticsearchRepository接口。

  1. public interface RequestLogRepository
  2. extends ElasticsearchRepository<RequestLog,Long> {
  3. }

1.5 演示案例

数据增加,修改,查询,排序,多条件查询。

  1. @Service
  2. public class RequestLogServiceImpl implements RequestLogService {
  3. @Resource
  4. private RequestLogRepository requestLogRepository ;
  5. @Override
  6. public String esInsert(Integer num) {
  7. for (int i = 0 ; i < num ; i++){
  8. RequestLog requestLog = new RequestLog() ;
  9. requestLog.setId(System.currentTimeMillis());
  10. requestLog.setOrderNo(DateUtil.formatDate(new Date(),DateUtil.DATE_FORMAT_02)+System.currentTimeMillis());
  11. requestLog.setUserId("userId"+i);
  12. requestLog.setUserName("张三"+i);
  13. requestLog.setCreateTime(DateUtil.formatDate(new Date(),DateUtil.DATE_FORMAT_01));
  14. requestLogRepository.save(requestLog) ;
  15. }
  16. return "success" ;
  17. }
  18. @Override
  19. public Iterable<RequestLog> esFindAll (){
  20. return requestLogRepository.findAll() ;
  21. }
  22. @Override
  23. public String esUpdateById(RequestLog requestLog) {
  24. requestLogRepository.save(requestLog);
  25. return "success" ;
  26. }
  27. @Override
  28. public Optional<RequestLog> esSelectById(Long id) {
  29. return requestLogRepository.findById(id) ;
  30. }
  31. @Override
  32. public Iterable<RequestLog> esFindOrder() {
  33. // 用户名倒序
  34. // Sort sort = new Sort(Sort.Direction.DESC,"userName.keyword") ;
  35. // 创建时间正序
  36. Sort sort = new Sort(Sort.Direction.ASC,"createTime.keyword") ;
  37. return requestLogRepository.findAll(sort) ;
  38. }
  39. @Override
  40. public Iterable<RequestLog> esFindOrders() {
  41. List<Sort.Order> sortList = new ArrayList<>() ;
  42. Sort.Order sort1 = new Sort.Order(Sort.Direction.ASC,"createTime.keyword") ;
  43. Sort.Order sort2 = new Sort.Order(Sort.Direction.DESC,"userName.keyword") ;
  44. sortList.add(sort1) ;
  45. sortList.add(sort2) ;
  46. Sort orders = Sort.by(sortList) ;
  47. return requestLogRepository.findAll(orders) ;
  48. }
  49. @Override
  50. public Iterable<RequestLog> search() {
  51. // 全文搜索关键字
  52. /*
  53. String queryString="张三";
  54. QueryStringQueryBuilder builder = new QueryStringQueryBuilder(queryString);
  55. requestLogRepository.search(builder) ;
  56. */
  57. /*
  58. * 多条件查询
  59. */
  60. QueryBuilder builder = QueryBuilders.boolQuery()
  61. // .must(QueryBuilders.matchQuery("userName.keyword", "历张")) 搜索不到
  62. .must(QueryBuilders.matchQuery("userName", "张三")) // 可以搜索
  63. .must(QueryBuilders.matchQuery("orderNo", "20190613736278243"));
  64. return requestLogRepository.search(builder) ;
  65. }
  66. }

2、Spring Boot 集成 Elasticsearch 实战

原文作者:武培轩

来源:微信公众号

完整代码Github仓库

Spring Boot 集成 ES 主要分为以下三步:

  1. 加入 ES 依赖
  2. 配置 ES
  3. 演示 ES 基本操作

2.1 加入依赖

  1. <dependency>
  2. <groupId>org.elasticsearch</groupId>
  3. <artifactId>elasticsearch</artifactId>
  4. <version>7.1.0</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.elasticsearch.client</groupId>
  8. <artifactId>elasticsearch-rest-high-level-client</artifactId>
  9. <version>7.1.0</version>
  10. </dependency>

2.2 创建ES配置

在配置文件 application.properties 中配置 ES 的相关参数,具体内容如下:

  1. elasticsearch.host=localhost
  2. elasticsearch.port=9200
  3. elasticsearch.connTimeout=3000
  4. elasticsearch.socketTimeout=5000
  5. elasticsearch.connectionRequestTimeout=500

其中指定了 ES 的 host 和端口以及超时时间的设置,另外我们的 ES 没有添加任何的安全认证,因此 username 和 password 就没有设置。

然后在 config 包下创建 ElasticsearchConfiguration 类,会从配置文件中读取到对应的参数,接着申明一个 initRestClient 方法,返回的是一个 RestHighLevelClient,同时为它添加 @Bean(destroyMethod = “close”) 注解,当 destroy 的时候做一个关闭,这个方法主要是如何初始化并创建一个 RestHighLevelClient。

  1. @Configuration
  2. public class ElasticsearchConfiguration {
  3. @Value("${elasticsearch.host}")
  4. private String host;
  5. @Value("${elasticsearch.port}")
  6. private int port;
  7. @Value("${elasticsearch.connTimeout}")
  8. private int connTimeout;
  9. @Value("${elasticsearch.socketTimeout}")
  10. private int socketTimeout;
  11. @Value("${elasticsearch.connectionRequestTimeout}")
  12. private int connectionRequestTimeout;
  13. @Bean(destroyMethod = "close", name = "client")
  14. public RestHighLevelClient initRestClient() {
  15. RestClientBuilder builder = RestClient.builder(new HttpHost(host, port))
  16. .setRequestConfigCallback(requestConfigBuilder -> requestConfigBuilder
  17. .setConnectTimeout(connTimeout)
  18. .setSocketTimeout(socketTimeout)
  19. .setConnectionRequestTimeout(connectionRequestTimeout));
  20. return new RestHighLevelClient(builder);
  21. }
  22. }

2.3 定义文档实体类

首先在 constant 包下定义常量接口,在接口中定义索引的名字为 user:

  1. public interface Constant {
  2. String INDEX = "user";
  3. }

然后在 document 包下创建一个文档实体类:

  1. public class UserDocument {
  2. private String id;
  3. private String name;
  4. private String sex;
  5. private Integer age;
  6. private String city;
  7. // 省略 getter/setter
  8. }

2.4 ES基本操作

在这里主要介绍 ES 的索引、文档、搜索相关的简单操作,在 service 包下创建 UserService 类。

索引操作

在这里演示创建索引和删除索引:

2.4.1 创建索引

在创建索引的时候可以在 CreateIndexRequest 中设置索引名称、分片数、副本数以及 mappings,在这里索引名称为 user,分片数 number_of_shards 为 1,副本数 number_of_replicas 为 0,具体代码如下所示:

  1. public boolean createUserIndex(String index) throws IOException {
  2. CreateIndexRequest createIndexRequest = new CreateIndexRequest(index);
  3. createIndexRequest.settings(Settings.builder()
  4. .put("index.number_of_shards", 1)
  5. .put("index.number_of_replicas", 0)
  6. );
  7. createIndexRequest.mapping("{\n" +
  8. " \"properties\": {\n" +
  9. " \"city\": {\n" +
  10. " \"type\": \"keyword\"\n" +
  11. " },\n" +
  12. " \"sex\": {\n" +
  13. " \"type\": \"keyword\"\n" +
  14. " },\n" +
  15. " \"name\": {\n" +
  16. " \"type\": \"keyword\"\n" +
  17. " },\n" +
  18. " \"id\": {\n" +
  19. " \"type\": \"keyword\"\n" +
  20. " },\n" +
  21. " \"age\": {\n" +
  22. " \"type\": \"integer\"\n" +
  23. " }\n" +
  24. " }\n" +
  25. "}", XContentType.JSON);
  26. CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
  27. return createIndexResponse.isAcknowledged();
  28. }

通过调用该方法,就可以创建一个索引 user,索引信息如下:

2.4.2 删除索引

在 DeleteIndexRequest 中传入索引名称就可以删除索引,具体代码如下所示:

  1. public Boolean deleteUserIndex(String index) throws IOException {
  2. DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(index);
  3. AcknowledgedResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
  4. return deleteIndexResponse.isAcknowledged();
  5. }

2.5 文档操作

2.5.1 创建文档

创建文档的时候需要在 IndexRequest 中指定索引名称,id 如果不传的话会由 ES 自动生成,然后传入 source,具体代码如下:

  1. public Boolean createUserDocument(UserDocument document) throws Exception {
  2. UUID uuid = UUID.randomUUID();
  3. document.setId(uuid.toString());
  4. IndexRequest indexRequest = new IndexRequest(Constant.INDEX)
  5. .id(document.getId())
  6. .source(JSON.toJSONString(document), XContentType.JSON);
  7. IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
  8. return indexResponse.status().equals(RestStatus.OK);
  9. }

下面通过调用这个方法,创建两个文档,具体内容如下:

2.5.2 批量创建文档

在一个 REST 请求中,重新建立网络开销是十分损耗性能的,因此 ES 提供 Bulk API,支持在一次 API 调用中,对不同的索引进行操作,从而减少网络传输开销,提升写入速率。

下面方法是批量创建文档,一个 BulkRequest 里可以添加多个 Request,具体代码如下:

  1. public Boolean bulkCreateUserDocument(List<UserDocument> documents) throws IOException {
  2. BulkRequest bulkRequest = new BulkRequest();
  3. for (UserDocument document : documents) {
  4. String id = UUID.randomUUID().toString();
  5. document.setId(id);
  6. IndexRequest indexRequest = new IndexRequest(Constant.INDEX)
  7. .id(id)
  8. .source(JSON.toJSONString(document), XContentType.JSON);
  9. bulkRequest.add(indexRequest);
  10. }
  11. BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
  12. return bulkResponse.status().equals(RestStatus.OK);
  13. }

下面通过该方法创建些文档,便于下面的搜索演示。

2.5.3 查看文档

查看文档需要在 GetRequest 中传入索引名称和文档 id,具体代码如下所示:

  1. public UserDocument getUserDocument(String id) throws IOException {
  2. GetRequest getRequest = new GetRequest(Constant.INDEX, id);
  3. GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
  4. UserDocument result = new UserDocument();
  5. if (getResponse.isExists()) {
  6. String sourceAsString = getResponse.getSourceAsString();
  7. result = JSON.parseObject(sourceAsString, UserDocument.class);
  8. } else {
  9. logger.error("没有找到该 id 的文档");
  10. }
  11. return result;
  12. }

下面传入文档 id 调用该方法,结果如下所示:

2.5.4 更新文档

更新文档则是先给 UpdateRequest 传入索引名称和文档 id,然后通过传入新的 doc 来进行更新,具体代码如下:

  1. public Boolean updateUserDocument(UserDocument document) throws Exception {
  2. UserDocument resultDocument = getUserDocument(document.getId());
  3. UpdateRequest updateRequest = new UpdateRequest(Constant.INDEX, resultDocument.getId());
  4. updateRequest.doc(JSON.toJSONString(document), XContentType.JSON);
  5. UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
  6. return updateResponse.status().equals(RestStatus.OK);
  7. }

下面将文档 id 为 9b8d9897-3352-4ef3-9636-afc6fce43b20 的文档的城市信息改为 handan,调用方法结果如下:

2.5.5 除文档

删除文档只需要在 DeleteRequest 中传入索引名称和文档 id,然后执行 delete 方法就可以完成文档的删除,具体代码如下:

  1. public String deleteUserDocument(String id) throws Exception {
  2. DeleteRequest deleteRequest = new DeleteRequest(Constant.INDEX, id);
  3. DeleteResponse response = client.delete(deleteRequest, RequestOptions.DEFAULT);
  4. return response.getResult().name();
  5. }

介绍完文档的基本操作,接下来对搜索进行简单介绍:

2.5.6 搜索操作

简单的搜索操作需要在 SearchRequest 中设置将要搜索的索引名称(可以设置多个索引名称),然后通过 SearchSourceBuilder 构造搜索源,下面将 TermQueryBuilder 搜索查询传给 searchSourceBuilder,最后将 searchRequest 的搜索源设置为 searchSourceBuilder,执行 search 方法实现通过城市进行搜索,具体代码如下所示:

  1. public List<UserDocument> searchUserByCity(String city) throws Exception {
  2. SearchRequest searchRequest = new SearchRequest();
  3. searchRequest.indices(Constant.INDEX);
  4. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  5. TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("city", city);
  6. searchSourceBuilder.query(termQueryBuilder);
  7. searchRequest.source(searchSourceBuilder);
  8. SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  9. return getSearchResult(searchResponse);
  10. }

该方法的执行结果如图所示:

2.5.7 聚合搜索

聚合搜索就是给 searchSourceBuilder 添加聚合搜索,下面方法是通过 TermsAggregationBuilder 构造一个先通过城市就行分类聚合,其中还包括一个子聚合,是对年龄求平均值,然后在获取聚合结果的时候,可以使用通过在构建聚合时的聚合名称获取到聚合结果,具体代码如下所示:

  1. public List<UserCityDTO> aggregationsSearchUser() throws Exception {
  2. SearchRequest searchRequest = new SearchRequest(Constant.INDEX);
  3. SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
  4. TermsAggregationBuilder aggregation = AggregationBuilders.terms("by_city")
  5. .field("city")
  6. .subAggregation(AggregationBuilders
  7. .avg("average_age")
  8. .field("age"));
  9. searchSourceBuilder.aggregation(aggregation);
  10. searchRequest.source(searchSourceBuilder);
  11. SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
  12. Aggregations aggregations = searchResponse.getAggregations();
  13. Terms byCityAggregation = aggregations.get("by_city");
  14. List<UserCityDTO> userCityList = new ArrayList<>();
  15. for (Terms.Bucket buck : byCityAggregation.getBuckets()) {
  16. UserCityDTO userCityDTO = new UserCityDTO();
  17. userCityDTO.setCity(buck.getKeyAsString());
  18. userCityDTO.setCount(buck.getDocCount());
  19. // 获取子聚合
  20. Avg averageBalance = buck.getAggregations().get("average_age");
  21. userCityDTO.setAvgAge(averageBalance.getValue());
  22. userCityList.add(userCityDTO);
  23. }
  24. return userCityList;
  25. }

下面是执行该方法的结果:

(九)整合 ElasticSearch框架,实现高性能搜索引擎的更多相关文章

  1. SpringBoot2.0 整合 ElasticSearch框架,实现高性能搜索引擎

    本文源码:GitHub·点这里 || GitEE·点这里 一.安装和简介 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful ...

  2. java框架之SpringBoot(13)-检索及整合Elasticsearch

    ElasticSearch介绍 简介 我们的应用经常需要使用检索功能,开源的 Elasticsearch 是目前全文搜索引擎的首选.它可以快速的存储.搜索和分析海量数据.SpringBoot 通过整合 ...

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

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

  4. Spring Boot 整合 Elasticsearch,实现 function score query 权重分查询

    摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 预见未来最好的方式就是亲手创造未来 – <史蒂夫·乔布斯传> 』 运行环境: ...

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

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

  6. Spring Boot整合Elasticsearch

    Spring Boot整合Elasticsearch   Elasticsearch是一个全文搜索引擎,专门用于处理大型数据集.根据描述,自然而然使用它来存储和搜索应用程序日志.与Logstash和K ...

  7. Spring Boot 整合 elasticsearch

    一.简介 我们的应用经常需要添加检索功能,开源的 ElasticSearch 是目前全文搜索引擎的 首选.他可以快速的存储.搜索和分析海量数据.Spring Boot通过整合Spring Data E ...

  8. SpringBoot整合elasticsearch

    在这一篇文章开始之前,你需要先安装一个ElasticSearch,如果你是mac或者linux可以参考https://www.jianshu.com/p/e47b451375ea,如果是windows ...

  9. spring-boot-starter-data-elasticsearch 整合elasticsearch 5.x详解

    1.使用原因 近期公司在开发新的项目用到了elasticsearch ,因为项目框架用的spring Cloud所以依赖全用的是starter,从网上找的信息比较旧,并没有整合elasticsearc ...

随机推荐

  1. 自定义ClassLoader的使用

    1 import java.io.ByteArrayOutputStream; 2 import java.io.File; 3 import java.io.FileInputStream; 4 i ...

  2. select机制

    select机制 函数作用: 在一段时间指定的时间内,监听用户感兴趣的文件描述符上可读.可写和异常事件. 函数原型: #include <sys/time.h> #include < ...

  3. 24位PCM采样数据转成16位算法,已实现PCM转WAV在线工具源码支持24bits、16bits、8bits

    目录 算法来源 js版24位PCM转8位.16位代码 js版8位.16位PCM转成24位 附:浏览器控制台下载数据文件代码 相关实现 最近收到几个24位的PCM录音源文件,Recoder库原有的PCM ...

  4. C#中存储过程和DataTable的应用

    存储过程p_OperatorDetails,有四个参数@sDatetime,@eDatetime,@operatorNo,@transdesc.其中@operatorNo和@transdesc为两个可 ...

  5. git-廖雪峰版教程学习笔记

  6. 性能超四倍的高性能.NET二进制序列化库

    二进制序列化在.NET中有很多使用场景,如我们使用分布式缓存时,通常将缓存对象序列化为二进制数据进行缓存,在ASP.NET中,很多中间件(如认证等)也都是用了二进制序列化. 在.NET中我们通常使用S ...

  7. 剑指offer 树的基本操作:四种遍历方式

    前序遍历 递归版 编程思想 即借助系统栈,效率较低.二叉树的前序遍历规则:1. 访问根结点: 2. 遍历左子树: 3. 遍历右子树 编程实现 //树的定义 struct TreeNode { int ...

  8. Svm算法原理及实现

    Svm(support Vector Mac)又称为支持向量机,是一种二分类的模型.当然如果进行修改之后也是可以用于多类别问题的分类.支持向量机可以分为线性核非线性两大类.其主要思想为找到空间中的一个 ...

  9. Docker学习笔记之向服务器部署应用程序

    部署的应用仅仅是简单应用程序,使用的是node管理的web应用,具体我也不是很会,当然也可以配置tomcat服务器.这里主要是学习docker.需要客户机和服务机,其中服务机必须要为Linux操作系统 ...

  10. 【Samba】共享服务器的搭建和相关权限设置

    1.查看防护墙 [root@zhang~ ]# /etc/init.d/iptables status   iptables:Firewall is not running.   如果没有关闭的话将他 ...