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优点
- 分布式的功能
- 数据高可用,集群高可用
- API更简单
- API更高级
- 支持的语言很多
- 支持PB级别的数据
- 完成搜索的功能和分析功能
- 基于Luncene,隐藏了Luncene的复杂性,提供简单的API
- ElasticSearch性能比HBase高,咱们的竞价引擎最后还是要存到ES中的
搜索引擎原理
- 反向索引又叫倒排索引,是根据文章内容中的关键字建立索引。
- 搜索引擎原理就是建立反向索引。
- ES在Luncene的基础上进行封装,实现了分布式搜索引擎。
- ES中的索引、类型和文档的概念比较重要,类似于mysql中的数据库、表和行。
- ES也是Master-slave架构,也实现了数据库的分片和备份。
- ES一个典型的应用就是ELK日志分析系统。
ES支持的语言
Cur/java/c#/python/javascript/hph/perl/ruby
ES的作用
- 全文搜索:类似 select * from product where product_name like '%牙膏%'类似百度效果(电商搜索的效果)
- 结构化搜索:类似 select * from product where product_id = ‘1’
- 数据分析类似 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
元数据来驱动对象到文档的映射。元数据取自可以注释的实体属性
可以使用以下注释:
@Documen
t:在类级别应用以指示该类是映射到数据库的候选对象。其中比较重要的属性是: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]的主要内容,如果未能解决你的问题,请参考以下文章
超详细Postman 操作 ElasticSearch笔记梳理
Linux ELK日志分析系统 | logstash日志收集 | elasticsearch 搜索引擎 | kibana 可视化平台 | 架构搭建 | 超详细