原标题:Spring认证中国教育管理中心-Spring Data Elasticsearch教程一(Spring中国教育管理中心)
5.1传输客户端
将TransportClient被弃用Elasticsearch 7的,并会在Elasticsearch 8被移除(见Elasticsearch文档)。Spring Data Elasticsearch 将支持它TransportClient,只要它在使用的 Elasticsearch版本中可用,但自 4.0 版以来已弃用使用它的类。
我们强烈建议使用高级 REST 客户端而不是TransportClient.
示例 52. 传输客户端
代码语言:javascript复制@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 {
ElasticsearchTemplate template = new ElasticsearchTemplate(elasticsearchClient, elasticsearchConverter);
template.setRefreshPolicy(refreshPolicy());
return template;
}
}
// ...
IndexRequest request = new IndexRequest("spring-data")
.id(randomID())
.source(someObject);
IndexResponse response = client.index(request);
在TransportClient必须与群集名称进行配置。
连接客户端的主机和端口。
RefreshPolicy 必须设置在ElasticsearchTemplate(覆盖refreshPolicy()不使用默认值)
5.2.高级 REST 客户端
Java High Level REST Client 是 Elasticsearch 的默认客户端,它提供了直接的替代,TransportClient因为它接受并返回完全相同的请求/响应对象,因此依赖于 Elasticsearch 核心项目。异步调用在客户端管理的线程池上进行操作,并且需要在请求完成时通知回调。
示例 53. 高级 REST 客户端
代码语言:javascript复制@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")
.id(randomID())
.source(singletonMap("feature", "high-level-rest-client"))
.setRefreshPolicy(IMMEDIATE);
IndexResponse response = highLevelClient.index(request,RequestOptions.DEFAULT);
使用构建器提供集群地址、设置默认值HttpHeaders或启用 SSL。
创建 RestHighLevelClient。
也可以获取lowLevelRest()客户端。
5.3.反应式客户端
这 ReactiveElasticsearchClient是一个基于WebClient. 它使用 Elasticsearch 核心项目提供的请求/响应对象。调用直接在响应式堆栈上操作,而不是将异步(线程池绑定)响应包装到响应式类型中。
示例 54. 反应式 REST 客户端
代码语言:javascript复制@Configuration
public class ReactiveRestClientConfig extends AbstractReactiveElasticsearchConfiguration {
@Override
@Bean
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200") //
.build();
return ReactiveRestClients.create(clientConfiguration);
}
}
// ...
Mono<IndexResponse> response = client.index(request ->
request.index("spring-data")
.id(randomID())
.source(singletonMap("feature", "reactive-client"));
);
使用构建器提供集群地址、设置默认值HttpHeaders或启用 SSL。
ReactiveClient 响应,特别是对于搜索操作,绑定到请求的from(offset) & size(limit) 选项。
5.4.客户端配置
客户端行为可以通过ClientConfiguration允许设置 SSL、连接和套接字超时、标头和其他参数的选项来更改。
示例 55. 客户端配置
代码语言:javascript复制HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("some-header", "on every request")
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200", "localhost:9291")
.usingSsl()
.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;
})
.withClientConfigurer(
ReactiveRestClients.WebClientConfigurationCallback.from(webClient -> {
// ...
return webClient;
}))
.withClientConfigurer(
RestClients.RestClientConfigurationCallback.from(clientBuilder -> {
// ...
return clientBuilder;
}))
. // ... other options
.build();
定义默认标题(如果需要自定义)
使用构建器提供集群地址、设置默认值HttpHeaders或启用 SSL。
可选择启用 SSL。
(可选)设置代理。
可选地设置路径前缀,主要用于在某些反向代理后面的不同集群时。
设置连接超时。默认值为 10 秒。
设置套接字超时。默认值为 5 秒。
可选地设置标题。
添加基本身份验证。
Supplier<Header>可以指定一个函数,在每次将请求发送到 Elasticsearch 之前调用该函数 - 例如,当前时间写入标头中。
对于反应性设置一个功能配置 WebClient
对于非反应式设置,配置 REST 客户端的功能
如上例所示添加 Header 供应商允许注入可能随时间变化的标头,例如身份验证 JWT 令牌。如果在反应设置中使用它,则供应商功能不得阻塞!
5.5.客户端日志
要查看实际发送到服务器和从服务器接收的内容Request/Response需要打开传输级别的日志记录,如下面的片段中所述。
启用传输层日志记录
代码语言:javascript复制<logger name="org.springframework.data.elasticsearch.client.WIRE" level="trace"/>
以上同时适用于RestHighLevelClient和 ReactiveElasticsearchClient通过获得时RestClients分别ReactiveRestClients,是不能用于TransportClient。
6. 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,不再 MappingElasticsearchConverter使用基于 Jackson 的映射器,而是使用了。
移除基于 Jackson 的映射器的主要原因是:
- 字段的自定义映射需要使用@JsonFormat或 之类的注释来完成@JsonInclude。当相同的对象用于不同的基于 JSON 的数据存储或通过基于 JSON 的 API 发送时,这通常会导致问题。
- 自定义字段类型和格式也需要存储到 Elasticsearch 索引映射中。基于 Jackson 的注释没有完全提供表示 Elasticsearch 类型所需的所有信息。
- 字段不仅在从实体转换到实体时必须映射,而且在查询参数、返回数据和其他地方也必须映射。
使用 MappingElasticsearchConverternow 涵盖了所有这些情况。
6.1。元模型对象映射
基于元模型的方法使用域类型信息来读取/写入 Elasticsearch。这允许Converter为特定域类型映射注册实例。
6.1.1.映射注释概述
在 MappingElasticsearchConverter使用元数据驱动的对象的映射文件。元数据取自可以注释的实体属性。
可以使用以下注释:
- @Document:在类级别应用以指示该类是映射到数据库的候选对象。最重要的属性是:indexName:存储此实体的索引的名称。这可以包含一个 SpEL 模板表达式,如 "log-#{T(java.time.LocalDate).now().toString()}"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。请参阅Elasticsearch 映射类型。如果未指定字段类型,则默认为FieldType.Auto。这意味着,不会为该属性写入任何映射条目,并且 Elasticsearch 将在存储该属性的第一个数据时动态添加一个映射条目(查看 Elasticsearch 文档以了解动态映射规则)。format:一种或多种内置日期格式,请参阅下一节日期格式映射。pattern:一种或多种自定义日期格式,请参阅下一节日期格式映射。store: 标记原始字段值是否应该存储在 Elasticsearch 中,默认值为false。analyzer, searchAnalyzer,normalizer用于指定自定义分析器和规范器。
- @GeoPoint:将字段标记为geo_point数据类型。如果字段是GeoPoint类的实例,则可以省略。
- @ValueConverter定义一个用于转换给定属性的类。与已注册的 Spring 不同,Converter这只转换了带注释的属性,而不是给定类型的每个属性。
映射元数据基础设施在一个独立的 spring-data-commons 项目中定义,该项目与技术无关。
日期格式映射
派生自TemporalAccessor或属于类型的属性java.util.Date必须具有@Field类型注释,FieldType.Date或者必须为此类型注册自定义转换器。本段描述了 FieldType.Date.
@Field注释的两个属性定义了将哪些日期格式信息写入映射(另请参阅Elasticsearch Built In Formats和Elasticsearch Custom Date Formats)
的format属性是用来定义预定义的格式中的至少之一。如果未定义,则使用默认值_date_optional_time和epoch_millis。
该pattern属性可用于添加其他自定义格式字符串。如果您只想使用自定义日期格式,则必须将该format属性设置为 empty {}。
下表显示了不同的属性以及从它们的值创建的映射:
范围类型
当字段使用Integer_Range、Float_Range、Long_Range、Double_Range、Date_Range或Ip_Range 中的一种类型进行注释时,该字段必须是将映射到 Elasticsearch 范围的类的实例,例如:
代码语言:javascript复制class SomePersonData {
@Field(type = FieldType.Integer_Range)
private ValidAge validAge;
// getter and setter
}
class ValidAge {
@Field(name="gte")
private Integer from;
@Field(name="lte")
private Integer to;
// getter and setter
}
作为替代方案,Spring Data Elasticsearch 提供了一个Range<T>类,因此前面的示例可以写成:
代码语言:javascript复制class SomePersonData {
@Field(type = FieldType.Integer_Range)
private Range<Integer> validAge;
// getter and setter
}
该类型支持类<T>是Integer,Long,Float,Double,Date和类实现该 TemporalAccessor接口。
映射的字段名称
无需进一步配置,Spring Data Elasticsearch 将使用对象的属性名称作为 Elasticsearch 中的字段名称。这可以通过使用该@Field属性上的注释来更改单个字段。
也可以FieldNamingStrategy在客户端的配置中定义一个(Elasticsearch Clients)。例如 SnakeCaseFieldNamingStrategy,如果配置了a,则对象的属性sampleProperty将映射到Elasticsearch 中的sample_property。AFieldNamingStrategy适用于所有实体;可以通过@Field在属性上设置特定名称来覆盖它。