ElasticSearch(超详细解说)[springBoot整合ElasticSearch]

Posted 低调小马(mcy)

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ElasticSearch(超详细解说)[springBoot整合ElasticSearch]相关的知识,希望对你有一定的参考价值。

ElasticSearch简介

ElasticSearch:智能搜索,分布式搜索引擎。

是ELK的一个组成。是一个产品,而且是非常完善的产品,ELK代表的是:E就是ElasticSearch,L就是Logstach,K即使Kibana

E:ElasticSearch 搜索和分析的功能;

L:Logstach 搜索数据的功能,类似于flume(使用方法几乎跟flume一模一样)。是日志收集系统

K:Kibana 数据可视化(分析),可以用图标的方式来去展示,文不如表,表不如图,是可视化平台。

ElasticSearch优点

  1. 分布式的功能
  2. 数据高可用,集群高可用
  3. API更简单
  4. API更高级
  5. 支持的语言很多
  6. 支持PB级别的数据
  7. 完成搜索的功能和分析功能
  8. 基于Luncene,隐藏了Luncene的复杂性,提供简单的API
  9. ElasticSearch性能比HBase高,咱们的竞价引擎最后还是要存到ES中的

搜索引擎原理

  1. 反向索引又叫倒排索引,是根据文章内容中的关键字建立索引。
  2. 搜索引擎原理就是建立反向索引。
  3. ES在Luncene的基础上进行封装,实现了分布式搜索引擎。
  4. ES中的索引、类型和文档的概念比较重要,类似于mysql中的数据库、表和行。
  5. ES也是Master-slave架构,也实现了数据库的分片和备份。
  6. ES一个典型的应用就是ELK日志分析系统。

ES支持的语言

Cur/java/c#/python/javascript/hph/perl/ruby

ES的作用

  1. 全文搜索:类似 select * from product where product_name like '%牙膏%'类似百度效果(电商搜索的效果)
  2. 结构化搜索:类似 select * from product where product_id = ‘1’
  3. 数据分析类似 select count (*) from product

ES的核心概念

  • NRT(Near Realtime)近实时

  • cluster集群,ES是一个分布式的系统:ES直接解压不需要配置就可以使用,在hadoop1上解压一个ES,在hadoop2上解压了一个ES,接下来把这两个ES启动起来。他们就构成了一个集群。在ES里面默认有一个配置,clustername 默认值就是ElasticSearch,如果这个值是一样的就属于同一个集群,不一样的值就是不一样的集群。

  • Node节点,就是集群中的一台服务器

  • Index索引(索引库):我们为什么使用ES?因为想把数据存进去,然后再查询出来。我们在使用Mysql或者Oracle的时候,为了区分数据,我们会建立不同的数据库,库下面还有表的。其实ES功能就像一个关系型数据库,在这个数据库我们可以往里面添加数据,查询数据。ES中的索引非传统索引的含义,ES中的索引是存放数据的地方,是ES中的一个概念词汇index类似于我们Mysql里面的一个数据库 create database user; 好比就是一个索引库

  • type类型:类型是用来定义数据结构的在每一个index下面,可以有一个或者多个type,好比数据库里面的一张表。相当于表结构的描述,描述每个字段的类型。

  • document(文档):文档就是最终的数据了,可以认为一个文档就是一条记录。在ES里面最小的数据单元,就好比表里面的一条数据

  • Field字段:好比关系型数据库中列的概念,一个documenr有一个或者多个filed组成。

  • shard(分片):一台服务器,无法存储大量的数据,ES把一个index里面的数据,分为多个shard,分布式的存储在各个服务器上面。

    kafka:为什么支持分布式的功能,因为里面是有topic,支持分区的概念。所以topic A可以存在不同的节点上面。就可以支持海量数据和高并发,提升性能和吞吐量。

    我们为了保证数据的安全,我们引入了replica的概念,跟hdfs里面的概念是一个意思。

    可以保证我们数据的安全。

    在ES集群中,我们一模一样的数据有多份,能正常提供查询和插入的分片我们叫做 primary shard,其余的我们就管他们叫做 replica shard(备份的分片)

    当我们去查询数据的时候,我们数据是有备份的,它会同时发出命令让我们有数据的机器去查询结果,最后谁的查询结果快,我们就要谁的数据(这个不需要我们去控制,它内部就自己控制了)。

​ 在默认情况下,我们创建一个库的时候,默认会帮我们创建5个主分片(primary shrad)和5个副分片(replica shard),所以说正常情况下是有10个分片的。

同一个节点上面,副本和主分片是一定不会在一台机器上面的,就是拥有相同数据的分片,是不会在同一个节点上面的。

所以当你有一个节点的时候,这个分片是不会把副本存在这仅有的一个节点上的,当你新加入了一台节点,ES会自动的给你在新机器上创建一个之前分片的副本。

ElasticSearch客户端

TransportClient(传输客户端)

​ (强烈建议使用Java High Level REST Clien而不是TransportClient),TransportClient,从 Elasticsearch 7 开始已弃用,并将在 Elasticsearch 8 中删除。(请参阅 Elasticsearch 文档)。Spring Data Elasticsearch 将支持它TransportClient,只要它在使用的 Elasticsearch版本中可用,但自 4.0 版以来已弃用使用它的类

@Configuration
public class TransportClientConfig extends ElasticsearchConfigurationSupport 

    @Bean
    public Client elasticsearchClient() throws UnknownHostException 
        Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build();        
        TransportClient client = new PreBuiltTransportClient(settings);
        client.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300)); 
        return client;
    

    @Bean(name =  "elasticsearchOperations", "elasticsearchTemplate" )
    public ElasticsearchTemplate elasticsearchTemplate() throws UnknownHostException 
        return new ElasticsearchTemplate(elasticsearchClient());
    


// ...

IndexRequest request = new IndexRequest("spring-data", "elasticsearch", randomID())
 .source(someObject)
 .setRefreshPolicy(IMMEDIATE);

IndexResponse response = client.index(request);
//TransportClient必须使用集群名称进行配置。
//连接客户端的主机和端口
Java High Level REST Clien(高级REST客户端)

​ Java High Level REST Clien是ElasticSearch的默认客户端,它提供了直接的代替,TransportClient因为它接受并返回完全相同的请求/响应对象,因此依赖于ElaticSearch核心项目。异步调用在客户端管理的线程池上进行操作,并且需要在请求完成时通知回调。

@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration 

    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() 

        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()  
            .connectedTo("localhost:9200")
            .build();

        return RestClients.create(clientConfiguration).rest();                         
    


// ...

  @Autowired
  RestHighLevelClient highLevelClient;

  RestClient lowLevelClient = highLevelClient.lowLevelClient();                        

// ...

IndexRequest request = new IndexRequest("spring-data", "elasticsearch", randomID())
  .source(singletonMap("feature", "high-level-rest-client"))
  .setRefreshPolicy(IMMEDIATE);

IndexResponse response = highLevelClient.index(request);
//使用构建器提供集群地址、设置默认值httpHeaders或启用SSL。
//创建RestHighLevelClient。
//也可以获取lowLevelRest客户端

测试config配置如下:

@Configuration
public class EsConfig 
//配置本机地址以及端口
    @Value("$spring.elasticsearch.hostname")
    private String hostname;
    @Value("$spring.elasticsearch.port")
    private int port;
    /**
     * LowLevelRestConfig
     */
    @Bean
    public RestClient restClient() 
        // 如果有多个从节点可以持续在内部new多个HttpHost,参数1是IP,参数2是端口,参数3是通信协议
        RestClientBuilder clientBuilder = RestClient.builder(new HttpHost(hostname, port, "http"));
        // 设置Header编码
        Header[] defaultHeaders = new BasicHeader("content-type", "application/json");
        clientBuilder.setDefaultHeaders(defaultHeaders);
        return clientBuilder.build();
    
    /**
     * HighLevelRestConfig
     */
    @Bean
    public RestHighLevelClient restHighLevelClient() 
        // 如果有多个从节点可以持续在内部new多个HttpHost,参数1是IP,参数2是端口,参数3是通信协议
        return new RestHighLevelClient(RestClient.builder(new HttpHost(hostname, port, "http")));
    


ReactiveElasticsearchClient(反应试客户端)

​ ReactiveElaticsearchClient是一个基于WebClient,它使用Elasticsearch核心项目提供的请求/响应对象。调用直接在响应式堆栈上操作,而不是将异步(线程池绑定)响应包装到响应式类型中。

static class Config 

  @Bean
  ReactiveElasticsearchClient client() 

    ClientConfiguration clientConfiguration = ClientConfiguration.builder()   
      .connectedTo("localhost:9200", "localhost:9291")
      .withWebClientConfigurer(webClient ->                                  
        ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder()
            .codecs(configurer -> configurer.defaultCodecs()
                .maxInMemorySize(-1))
            .build();
        return webClient.mutate().exchangeStrategies(exchangeStrategies).build();
       )
      .build();

    return ReactiveRestClients.create(clientConfiguration);
  


// ...

Mono<IndexResponse> response = client.index(request ->

  request.index("spring-data")
    .type("elasticsearch")
    .id(randomID())
    .source(singletonMap("feature", "reactive-client"))
    .setRefreshPolicy(IMMEDIATE);
);
//使用构建器提供集群地址、设置默认值HttpHeaders或启用SSL。
//在配置响应式客户端时,该withWebClientConfigurer钩子可用于自定义WebClient。
客户端配置

客户端行为可以通过ClientConfiguration允许设置 SSL、连接和套接字超时、标头和其他参数的选项来更改

HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("some-header", "on every request")                      

ClientConfiguration clientConfiguration = ClientConfiguration.builder()
  .connectedTo("localhost:9200", "localhost:9291")                      
  .useSsl()                                                             
  .withProxy("localhost:8888")                                          
  .withPathPrefix("ela")                                                
  .withConnectTimeout(Duration.ofSeconds(5))                            
  .withSocketTimeout(Duration.ofSeconds(3))                             
  .withDefaultHeaders(defaultHeaders)                                   
  .withBasicAuth(username, password)                                    
  .withHeaders(() ->                                                   
    HttpHeaders headers = new HttpHeaders();
    headers.add("currentTime", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
    return headers;
  )
  . // ... other options
  .build();
//定义默认标题(如果需要自定义)
//使用构建器提供集群地址、设置默认值HttpHeaders或启用SSL。
//可选择启用SSL。
//(可选)设置代理。
//可选地设置路径前缀,主要用于在某些反向代理后面的不同集群时。
//设置连接超时。默认值为10秒。
//设置套接字超时。默认值为5秒。
//可选的设置标题。
//添加基本身份验证。
//可以指定一个Supplier<Header>函数,在每次将请求发送到Elasticsearch之前调用该函数——例如:当前时间写入标头中。
客户端日志

​ 要查看实际发送到服务器和从服务器接收到的内容Request/Response需要打开传输级别的日志记录,如下面的片段所述。

<logger name="org.springframework.data.elasticsearch.client.WIRE" level="trace"/>

Elasticsearch对象映射

​ Spring Data Elasticsearch 对象映射是将Java对象(域实体)映射到存储在Elasticsearch中并返回Json表示的过程。

​ Spring Data Elasticsearch 的早期版本使用基于 Jackson 的转换,Spring Data Elasticsearch 3.2.x 引入了Meta Model Object Mapping。从 4.0 版开始,仅使用 Meta Object Mapping,不再使用基于 Jackson 的映射器,而是使用了MappingElasticsearchConverter

移除基于Jackson的映射器的主要原因是:

  • 字段的定义映射需要使用@JsonFormat或之类的注释来完成@JsonInclude。当相同的对象用于不同的基于Json的数据存储或通过基于Json的API发送时,这通常会出现问题。
  • 自定义字段类型和格式也需要存储到Elasticsearch索引映射中。基于Jackson的注释没有完全提供表示Elasticsearch类型所需的所有信息。
  • 字段不仅在从实体转换到实体时必须映射,而且在查询参数,返回数据和其他地方也必须映射。

使用MappingElasticsearchConverter now涵盖了使用所有这些情况。

元模型对象映射

基于元模型的方法使用域类型信息来读取/写入ElasticSearch。这允许Converter为特定域类型映射注册实例。

映射注释概述

使用MappingElasticsearchConverter元数据来驱动对象到文档的映射。元数据取自可以注释的实体属性

可以使用以下注释:

  • @Document:在类级别应用以指示该类是映射到数据库的候选对象。其中比较重要的属性是:
    • indexName:存储此实体的索引的名称。这可以包含一个 SpEL 模板表达式,如"log-#T(java.time.LocalDate).now().toString()"
    • type:映射类型。如果未设置,则使用类的小写简单名称。(自 4.0 版起已弃用)
    • shards:索引的分片数。
    • replicas:索引的副本数。
    • refreshIntervall:索引的刷新间隔。用于创建索引。默认值为*“1s”*。
    • indexStoreType:索引的索引存储类型。用于创建索引。默认值为*“1s”*。
    • createIndex: 标记是否在存储库引导时创建索引。默认值为true
    • versionType:版本管理的配置。默认值为外部
  • @Id:应用于字段级别以标记用于标识目的的字段。
  • @Transient:默认情况下,所有字段在存储或检索时都映射到文档,此注释不包括该字段。
  • @PersistenceConstructor:标记一个给定的构造函数–甚至是一个包保护的构造函数–再从数据库中实例化对象时使用。构造函数参数按名称映射到检索到的Document中的键值。
  • @Field:应用于字段级别并定义字段的属性,大部分属性映射到各自的Elasticsearch Mapping定义(以下列表不完整,查看注释Javadoc以获得完整参考):
    • name:将在 Elasticsearch 文档中表示的字段名称,如果未设置,则使用 Java 字段名称。
    • type:字段类型,可以是Text、Keyword、Long、Integer、Short、Byte、Double、Float、Half_Float、Scaled_Float、Date、Date_Nanos、Boolean、Binary、Integer_Range、Float_Range、Long_Range、Double_Range、Date_Range、Ip_Range、Object 之一, 嵌套, Ip, TokenCount, Percolator, Flattened, Search_As_You_Type
    • format以及Date类型pattern的定义。
    • store: 标记原始字段值是否应该存储在 Elasticsearch 中,默认值为false
    • analyzer, searchAnalyzer,normalizer用于指定自定义分析器和规范器。
  • @GeoPoint: 将字段标记为geo_point数据类型。如果字段是类的实例,则可以省略GeoPoint
映射规则

类型

映射使用嵌入在发送到服务器的文档中的类型来允许泛型类型映射。这些类型_class在文档中表示为属性,并为每个聚合跟写入

public class Person               

  @Id String id;
  String firstname;
  String lastname;


  "_class" : "com.example.Person", 
  "id" : "cb7bef",
  "firstname" : "Sarah",
  "lastname" : "Connor"

类型可以配置为保存自定义信息。使用@TypeAlias注释来执行此操作

带别名的类型

@TypeAlias("human")                
public class Person 

  @Id String id;
  // ...


  "_class" : "human",              
  "id" : ...

地理空间类型

Point像&这样的地理空间类型GeoPoint被转换为纬度/经度对。

public class Address 

  String city, street;
  Point location;


  "city" : "Los Angeles",
  "street" : "2800 East Observatory Road",
  "location" :  "lat" : 34.118347, "lon" : -118.3026284 

GeoJson类型

Spring Data Elasticsearch 通过为不同几何提供接口GeoJson和实现来支持 GeoJson 类型。它们根据 GeoJson 规范映射到 Elasticsearch 文档。实体的相应属性在索引映射中指定,就像geo_shape编写索引映射时一样。

public class Address 

  String city, street;
  GeoJsonPoint location;


  "city": "Los Angeles",
  "street": "2800 East Observatory Road",
  "location": 
    "type": "Point",
    "coordinates": [-118.3026284, 34.118347]
  

自定义转化

元模型对象映射配置

@Configuration
public class Config extends AbstractElasticsearchConfiguration 

  @Override
  public RestHighLevelClient elasticsearchClient() 
    return RestClients.create(ClientConfiguration.create("localhost:9200")).rest();
  

  @Bean
  @Override
  public ElasticsearchCustomConversions elasticsearchCustomConversions() 
    return new ElasticsearchCustomConversions(
      Arrays.asList(new AddressToMap(), new MapToAddress()));       
  

  @WritingConverter                                                 
  static class AddressToMap implements Converter<Address, Map<String, Object>> 

    @Override
    public Map<String, Object> convert(Address source) 

      LinkedHashMap<String, Object> target = new LinkedHashMap<>();
      target.put("ciudad", source.getCity());
      // ...

      return target;
    
  

  @ReadingConverter                                                 
  static class MapToAddress implements Converter<Map<String, Object>, Address> 

    @Override
    public Address convert(Map<String, Object> source) 

      // ...
      return address;
    
  

以上是关于ElasticSearch(超详细解说)[springBoot整合ElasticSearch]的主要内容,如果未能解决你的问题,请参考以下文章

分布式全文搜索引擎ElasticSearch—超详细

超详细Postman 操作 ElasticSearch笔记梳理

Linux ELK日志分析系统 | logstash日志收集 | elasticsearch 搜索引擎 | kibana 可视化平台 | 架构搭建 | 超详细

《SpringBoot篇》16.SpringBoot整合Elasticsearch超详细教程

开源项目47K+ Star的电商项目 附带超详细的文档!

2022win11系统 MySQL下载安装配置全解(超详细哟)