Spring认证中国教育管理中心-Spring Data Elasticsearch教程二

2022-01-13 15:10:24 浏览数 (1)

原标题:Spring认证中国教育管理中心-Spring Data Elasticsearch教程二(Spring中国教育管理中心)

6.1.2.映射规则

类型提示

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

示例 56. 类型提示

代码语言:javascript复制
public class Person {              

  @Id String id;
  String firstname;
  String lastname;
}
代码语言:javascript复制
{
  "_class" : "com.example.Person", 
  "id" : "cb7bef",
  "firstname" : "Sarah",
  "lastname" : "Connor"
}

默认情况下,域类型类名用于类型提示。

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

确保@TypeAlias在初始实体集 ( AbstractElasticsearchConfiguration#getInitialEntitySet) 中添加类型,以便在首次从存储中读取数据时已经拥有可用的实体信息。

示例 57. 带别名的类型提示

代码语言:javascript复制
@TypeAlias("human")                
public class Person {

  @Id String id;
  // ...
}
代码语言:javascript复制
{
  "_class" : "human",              
  "id" : ...
}

写入实体时使用配置的别名。

除非属性类型是Object、接口或实际值类型与属性声明不匹配,否则不会为嵌套对象编写类型提示。

禁用类型提示

当应该使用的索引已经存在而没有在其映射中定义类型提示并且映射模式设置为严格时,可能需要禁用类型提示的写入。在这种情况下,写入类型提示会产生错误,因为该字段无法自动添加。

通过覆盖writeTypeHints()派生自的配置类中的方法,可以为整个应用程序禁用类型提示 AbstractElasticsearchConfiguration(请参阅Elasticsearch 客户端)。

作为替代方案,可以使用@Document注释为单个索引禁用它们:

代码语言:javascript复制
@Document(indexName = "index", writeTypeHint = WriteTypeHint.FALSE)

我们强烈建议不要禁用类型提示。只有在被迫时才这样做。禁用类型提示可能会导致无法从 Elasticsearch 正确检索文档,以防多态数据或文档检索可能完全失败。

地理空间类型

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

示例 58. 地理空间类型

代码语言:javascript复制
public class Address {

  String city, street;
  Point location;
}
代码语言:javascript复制
{
  "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编写索引映射时一样。(也请查看Elasticsearch 文档)

示例 59. GeoJson 类型

代码语言:javascript复制
public class Address {

  String city, street;
  GeoJsonPoint location;
}
代码语言:javascript复制
{
  "city": "Los Angeles",
  "street": "2800 East Observatory Road",
  "location": {
    "type": "Point",
    "coordinates": [-118.3026284, 34.118347]
  }
}

实现了以下 GeoJson 类型:

  • GeoJsonPoint
  • GeoJsonMultiPoint
  • GeoJsonLineString
  • GeoJsonMultiLineString
  • GeoJsonPolygon
  • GeoJsonMultiPolygon
  • GeoJsonGeometryCollection

收藏品

对于集合中的值,在类型提示和自定义转换方面应用与聚合根相同的映射规则。

示例 60. 集合

代码语言:javascript复制
public class Person {

  // ...

  List<Person> friends;

}
代码语言:javascript复制
{
  // ...

  "friends" : [ { "firstname" : "Kyle", "lastname" : "Reese" } ]
}

地图

对于 Maps 中的值,在类型提示和自定义转换方面应用与聚合根相同的映射规则。但是,映射键需要一个字符串才能由 Elasticsearch 处理。

示例 61. 集合

代码语言:javascript复制
public class Person {

  // ...

  Map<String, Address> knownLocations;

}
代码语言:javascript复制
{
  // ...

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

6.1.3.自定义转化

望着Configuration从上一节 ElasticsearchCustomConversions允许注册映射域和简单类型的具体规则。

示例 62. 元模型对象映射配置

代码语言:javascript复制
@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;
    }
  }
}
代码语言:javascript复制
{
  "ciudad" : "Los Angeles",
  "calle" : "2800 East Observatory Road",
  "localidad" : { "lat" : 34.118347, "lon" : -118.3026284 }
}

添加Converter实现。

设置Converter用于写入DomainTypeElasticsearch。

设置Converter用于DomainType从搜索结果中读取。

7. Elasticsearch 操作

Spring Data Elasticsearch 使用多个接口来定义可以针对 Elasticsearch 索引调用的操作(有关响应式接口的描述,请参阅Reactive Elasticsearch Operations)。

  • IndexOperations 定义索引级别的操作,例如创建或删除索引。
  • DocumentOperations 定义基于 id 存储、更新和检索实体的操作。
  • SearchOperations 定义使用查询搜索多个实体的操作
  • ElasticsearchOperations结合DocumentOperations和SearchOperations接口。

这些接口对应于Elasticsearch API的结构。

接口的默认实现提供:

  • 索引管理功能。
  • 对域类型的读/写映射支持。
  • 丰富的查询和标准 api。
  • 资源管理和异常翻译。

索引管理和自动创建索引和映射。

IndexOperations可以从ElasticsearchOperations实例中获取的接口和提供的实现(例如通过调用operations.indexOps(clazz))使用户能够在 Elasticsearch 集群中创建索引、放置映射或存储模板和别名信息。可以使用@Setting注释设置将要创建的索引的详细信息,请参阅索引设置以获取更多信息。

这些操作都不是由IndexOperationsor的实现自动完成的ElasticsearchOperations。调用方法是用户的责任。

使用 Spring Data Elasticsearch 存储库时支持自动创建索引和编写映射

7.1弹性搜索模板

自 4.0 版起,不推荐使用 ElasticsearchTemplate,请改用 ElasticsearchRestTemplate。

这ElasticsearchTemplate是ElasticsearchOperations使用传输客户端的接口实现。

示例 63. ElasticsearchTemplate 配置

代码语言: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 { 
  	return new ElasticsearchTemplate(elasticsearchClient());
  }
}

设置传输客户端。自 4.0 版起已弃用。

创建ElasticsearchTemplatebean,同时提供名称、elasticsearchOperations和elasticsearchTemplate。

7.2.ElasticsearchRestTemplate

这ElasticsearchRestTemplate是ElasticsearchOperations使用High Level REST Client的接口实现。

示例 64. ElasticsearchRestTemplate 配置

代码语言:javascript复制
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
  @Override
  public RestHighLevelClient elasticsearchClient() {       
    return RestClients.create(ClientConfiguration.localhost()).rest();
  }

  // no special bean creation needed                       
}

设置高级 REST 客户端。

基类 AbstractElasticsearchConfiguration已经提供了elasticsearchTemplatebean。

7.3.使用示例

由于两个ElasticsearchTemplate和ElasticsearchRestTemplate实现ElasticsearchOperations接口,使用它们的代码是没有不同的。该示例展示了如何ElasticsearchOperations在 Spring REST 控制器中使用注入的实例。通过为相应的 Bean 提供上面显示的配置之一来做出决定,如果这是使用TransportClient或RestClient。

示例 65. ElasticsearchOperations 使用

代码语言:javascript复制
@RestController
@RequestMapping("/")
public class TestController {

  private  ElasticsearchOperations elasticsearchOperations;

  public TestController(ElasticsearchOperations elasticsearchOperations) { 
    this.elasticsearchOperations = elasticsearchOperations;
  }

  @PostMapping("/person")
  public String save(@RequestBody Person person) {                         

    IndexQuery indexQuery = new IndexQueryBuilder()
      .withId(person.getId().toString())
      .withObject(person)
      .build();
    String documentId = elasticsearchOperations.index(indexQuery);
    return documentId;
  }

  @GetMapping("/person/{id}")
  public Person findById(@PathVariable("id")  Long id) {                   
    Person person = elasticsearchOperations
      .queryForObject(GetQuery.getById(id.toString()), Person.class);
    return person;
  }
}

让 SpringElasticsearchOperations在构造函数中注入提供的bean。

在 Elasticsearch 集群中存储一些实体。

通过 id 检索具有查询的实体。

要查看完整的可能性,ElasticsearchOperations请参阅 API 文档。

7.4.反应式 Elasticsearch 操作

ReactiveElasticsearchOperations是使用ReactiveElasticsearchClient.

的 ReactiveElasticsearchTemplate是默认的实现ReactiveElasticsearchOperations。

7.4.1。反应式 Elasticsearch 模板

要开始, ReactiveElasticsearchTemplate需要了解要与之合作的实际客户。有关客户端的详细信息,请参阅Reactive Client。

反应式模板配置

建立的最简单的方法 ReactiveElasticsearchTemplate是通过AbstractReactiveElasticsearchConfiguration用于提供专用配置方法钩base package,所述initial entity set等

示例 66. AbstractReactiveElasticsearchConfiguration

代码语言:javascript复制
@Configuration
public class Config extends AbstractReactiveElasticsearchConfiguration {

  @Bean 
  @Override
  public ReactiveElasticsearchClient reactiveElasticsearchClient() {
      // ...
  }
}

配置要使用的客户端。这可以通过ReactiveRestClients或直接通过来完成 DefaultReactiveElasticsearchClient。

如果适用的默认设置HttpHeaders通过ClientConfiguration的 ReactiveElasticsearchClient。请参阅客户端配置。

如果需要的话 ReactiveElasticsearchTemplate可以用默认的配置RefreshPolicy,并IndicesOptions是那些获得通过覆盖的默认应用到相关请求refreshPolicy()和indicesOptions()。

但是,人们可能希望更好地控制实际组件并使用更详细的方法。

示例 67.配置 ReactiveElasticsearchTemplate

代码语言:javascript复制
@Configuration
public class Config {

  @Bean 
  public ReactiveElasticsearchClient reactiveElasticsearchClient() {
    // ...
  }
  @Bean 
  public ElasticsearchConverter elasticsearchConverter() {
    return new MappingElasticsearchConverter(elasticsearchMappingContext());
  }
  @Bean 
  public SimpleElasticsearchMappingContext elasticsearchMappingContext() {
    return new SimpleElasticsearchMappingContext();
  }
  @Bean 
  public ReactiveElasticsearchOperations reactiveElasticsearchOperations() {
    return new ReactiveElasticsearchTemplate(reactiveElasticsearchClient(), elasticsearchConverter());
  }
}

配置要使用的客户端。这可以通过ReactiveRestClients或直接通过来完成 DefaultReactiveElasticsearchClient。

设置了ElasticsearchConverter用于利用由映射上下文提供的元数据域类型映射。

域类型元数据的 Elasticsearch 特定映射上下文。

基于客户端和转换基础架构的实际模板。

反应式模板使用

ReactiveElasticsearchTemplate 允许您保存、查找和删除您的域对象并将这些对象映射到存储在 Elasticsearch 中的文档。

考虑以下:

示例 68. 使用 ReactiveElasticsearchTemplate

代码语言:javascript复制
@Document(indexName = "marvel")
public class Person {

  private @Id String id;
  private String name;
  private int age;
  // Getter/Setter omitted...
}
代码语言:javascript复制
template.save(new Person("Bruce Banner", 42))                    
  .doOnNext(System.out::println)
  .flatMap(person -> template.findById(person.id, Person.class)) 
  .doOnNext(System.out::println)
  .flatMap(person -> template.delete(person))                    
  .doOnNext(System.out::println)
  .flatMap(id -> template.count(Person.class))                   
  .doOnNext(System.out::println)
  .subscribe(); 

以上在控制台上输出以下序列。

代码语言:javascript复制
> Person(id=QjWCWWcBXiLAnp77ksfR, name=Bruce Banner, age=42)
> Person(id=QjWCWWcBXiLAnp77ksfR, name=Bruce Banner, age=42)
> QjWCWWcBXiLAnp77ksfR
> 0

在字符类型下将新Person文档插入奇迹索引中。该是在服务器端和一套生成到返回的实例。id

在字符类型下的奇迹索引中查找Person与匹配。id

删除从给定实例中提取的Person匹配字符id,在奇迹索引中的字符类型下。

在字符类型下计算奇迹索引中的文档总数。

0 人点赞