Spring Data访问Elasticsearch----Elasticsearch操作

发布于:2024-03-21 ⋅ 阅读:(89) ⋅ 点赞:(0)


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

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

这些接口对应于Elasticsearch API的结构。
接口的默认实现提供:

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

索引管理以及索引和映射的自动创建
IndexOperations接口和提供的实现可以从ElasticsearchOperations实例中获得,例如通过调用operations.indexOps(clazz),用户可以在Elasticsearch集群中创建索引、放置映射或存储模板和别名信息。将要创建的索引的详细信息可以使用@Setting注解进行设置,有关详细信息,请参阅索引设置
这些操作都不是由IndexOperations或ElasticsearchOperations的实现自动完成的。调用这些方法是用户的责任。
使用Spring Data Elasticsearch存储库时,支持自动创建索引和编写映射,请参阅使用相应映射自动创建索引

一、用法示例

这个例子展示了如何在Spring REST控制器中使用注入的ElasticsearchOperations实例。这个例子假设Person是一个带有@Document、@Id等注解的类(参见映射注解概述)。
例1:ElasticsearchOperations用法

@RestController
@RequestMapping("/")
public class TestController {

  private  ElasticsearchOperations elasticsearchOperations;

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

  @PostMapping("/person")
  public String save(@RequestBody Person person) {                         --------2
    Person savedEntity = elasticsearchOperations.save(person);
    return savedEntity.getId();
  }

  @GetMapping("/person/{id}")
  public Person findById(@PathVariable("id")  Long id) {                   --------3
    Person person = elasticsearchOperations.get(id.toString(), Person.class);
    return person;
  }
}

1.Spring在构造函数中注入提供的ElasticsearchOperations bean。
2.Elasticsearch集群中存储一些实体。id是从返回的实体中读取的,因为它在person对象中可能为null,并且是由Elasticsearch创建的。
3. 用get检索具有id的实体。

要查看ElasticsearchOperations的全部可能性,请参考API文档。

二、搜索结果类型

当使用DocumentOperations接口的方法检索文档时,只返回找到的实体。当使用SearchOperations接口的方法进行搜索时,每个实体都可以获得其他信息,例如找到的实体的score或sortValues。
为了返回此信息,每个实体都封装在一个SearchHit对象中,该对象包含此实体特定的附加信息。这些SearchHit对象本身在SearchHits对象中返回,该对象还包含有关整个搜索的信息,如maxScore或请求的聚合。现在可以使用以下类和接口:
SearchHit<T>包含以下信息:

  • Id
  • Score
  • Sort Values
  • Highlight fields
  • Inner hits(这是一个嵌入的SearchHits对象,包含最终返回的inner hits)
  • 检索到的类型为<T>的实体

SearchHits<T>包含以下信息:

  • 总点击次数
  • 总命中率关系
  • 最高得分
  • SearchHit<T>对象的列表
  • 返回的聚合
  • 返回的建议结果

SearchPage<T>定义一个包含SearchHits<T>元素的Spring Data Page,该页可用于使用存储库方法进行分页访问。
SearchScrollHits<T>由ElasticsearchRestTemplate中的低级滚动API函数返回,它使用Elasticsearch滚动id丰富了SearchHits<T>。
SearchHitsIterator<T> SearchOperations接口的流式函数返回的迭代器。
ReactiveSearchHits
ReactiveSearchOperations有返回Mono<ReactiveSearchHits<T>>的方法,它包含与SearchHits<T>对象相同的信息,但将提供包含的SearchHit<T>对象作为Flux<SearchHit<T>>而不是列表。

三、查询

在SearchOperations和ReactiveSearchOperations接口中定义的几乎所有方法都接受一个Query参数,该参数定义了要执行的搜索查询。Query是一个接口,Spring Data Elasticsearch提供了三种实现:CriteriaQuery、StringQuery和NativeQuery。

3.1 CriteriaQuery

基于CriteriaQuery的查询允许创建查询来搜索数据,而不需要了解Elasticsearch查询的语法或基础知识。它们允许用户通过简单地链接和组合指定搜索文档必须满足的条件的Criteria对象来构建查询。
当谈到AND或OR时,当组合条件时,请记住,在Elasticsearch中,AND被转换为必须条件,OR被转换为应该条件
Criteria及其用法最好通过示例来解释(假设我们有一个具有价格属性的Book实体):
例2:以给定的价格购买书籍

Criteria criteria = new Criteria("price").is(42.0);
Query query = new CriteriaQuery(criteria);

同一字段的条件可以链接,它们将以一个逻辑AND组合:
例3:以给定的价格购买书籍

Criteria criteria = new Criteria("price").greaterThan(42.0).lessThan(34.0);
Query query = new CriteriaQuery(criteria);

当链接Criteria时,默认使用AND逻辑:
例4:找出所有名字是James,姓氏是Miller的人:

Criteria criteria = new Criteria("lastname").is("Miller") --------1
  .and("firstname").is("James")                           --------2
Query query = new CriteriaQuery(criteria);

1. 第一个条件
2. and() 创建一个新的条件并将其链接到第一个Criteria

如果要创建嵌套查询,则需要为此使用子查询。假设我们想找到所有姓Miller、名为Jack或John的人:
例5:嵌套的子查询

Criteria miller = new Criteria("lastName").is("Miller") --------1 
  .subCriteria(                                         --------2 
    new Criteria().or("firstName").is("John")           --------3 
      .or("firstName").is("Jack")                       --------4 
  );
Query query = new CriteriaQuery(criteria);

1. 为姓氏创建第一个条件
2. 使用AND组合为一个子条件
3. 此子条件是名字为JohnOR组合
4. 还有名字为Jack

有关不同可用操作的完整概述,请参阅Criteria类的API文档。

3.2 StringQuery

这个类接受一个Elasticsearch查询作为JSON字符串。下面的代码显示了一个查询,它搜索名字为“Jack”的人:

Query query = new StringQuery("{ \"match\": { \"firstname\": { \"query\": \"Jack\" } } } ");
SearchHits<Person> searchHits = operations.search(query, Person.class);

如果你已经有一个Elasticsearch查询要使用,那么使用StringQuery可能是合适的。

3.3 NativeQuery

NativeQuery是在具有复杂查询或无法使用Criteria API表示的查询时使用的类,例如在构建查询和使用聚合时。它允许使用Elasticsearch库中所有不同的“co.elastic.clients.elasticsearch._types.query_dsl.Query”实现,因此命名为“native”。
以下代码显示了如何搜索具有给定firstName的人员,对于找到的文档,有一个术语聚合,用于统计这些人员的lastName出现次数:

Query query = NativeQuery.builder()
	.withAggregation("lastNames", Aggregation.of(a -> a
		.terms(ta -> ta.field("lastName").size(10))))
	.withQuery(q -> q
		.match(m -> m
			.field("firstName")
			.query(firstName)
		)
	)
	.withPageable(pageable)
	.build();

SearchHits<Person> searchHits = operations.search(query, Person.class);

3.4 SearchTemplateQuery

这是Query接口的特殊实现,将与存储的搜索模板结合使用。有关更多信息,请参阅搜索模板支持

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到