原标题:Spring认证中国教育管理中心-Spring Data Elasticsearch教程三(Spring中国教育管理中心)
7.5搜索结果类型
当使用接口的方法检索文档时DocumentOperations,只会返回找到的实体。使用接口的方法进行搜索时SearchOperations,每个实体都可以获得附加信息,例如找到的实体的分数或sortValues。
为了返回此信息,每个实体都包装在一个SearchHit对象中,该对象包含此实体特定的附加信息。这些SearchHit对象本身在一个SearchHits对象中返回,该对象还包含有关整个搜索的信息,例如maxScore或请求的聚合。现在可以使用以下类和接口:
搜索命中<T>
包含以下信息:
- ID
- 分数
- 排序值
- 突出显示字段
- SearchHits内部命中(这是一个包含最终返回的内部命中的嵌入对象)
- 检索到的 <T> 类型实体
搜索点击<T>
包含以下信息:
- 总点击数
- 总点击量关系
- 最高分
- SearchHit<T>对象列表
- 返回的聚合
- 返回的建议结果
搜索页面<T>
定义一个 Spring DataPage包含一个SearchHits<T>元素,并且可以用于使用存储库方法进行分页访问。
SearchScrollHits<T>
由 中的低级滚动 API 函数返回,它使用 Elasticsearch 滚动
idElasticsearchRestTemplate丰富了 a 。SearchHits<T>
SearchHitsIterator<T>
接口的流函数返回的迭代器SearchOperations。
7.6.查询
SearchOperations和ReactiveSearchOperations接口中定义的几乎所有方法都带有一个Query参数,该参数定义要执行的查询以进行搜索。Query是一个接口,Spring Data Elasticsearch 提供了三种实现CriteriaQuery:StringQuery和NativeSearchQuery。
7.6.1.条件查询
CriteriaQuery基于查询允许创建查询以搜索数据,而无需了解 Elasticsearch 查询的语法或基础知识。Criteria它们允许用户通过简单地链接和组合指定搜索文档必须满足的条件的对象来构建查询。
在谈论 AND 或 OR 组合条件时请记住,在 Elasticsearch 中 AND 被转换为必须条件,而 OR被转换为应该
Criteria并且它们的用法最好通过示例来解释(假设我们有一个Book具有属性的实体price):
示例 69. 获取给定价格的书籍
Criteria criteria = new Criteria("price").is(42.0);
Query query = new CriteriaQuery(criteria);
可以链接相同字段的条件,它们将与逻辑 AND 组合:
示例 70. 获取给定价格的书籍
Criteria criteria = new Criteria("price").greaterThan(42.0).lessThan(34.0L);
Query query = new CriteriaQuery(criteria);
链接Criteria时,默认情况下使用 AND 逻辑:
示例 71. 获取所有名字为James和姓为Miller的人:
Criteria criteria = new Criteria("lastname").is("Miller")
.and("firstname").is("James")
Query query = new CriteriaQuery(criteria);
首先 Criteriaand() 创建一个新的Criteria并将其链接到第一个。
如果要创建嵌套查询,则需要为此使用子查询。假设我们要查找姓氏为Miller且名字为Jack或John的所有人:
例 72. 嵌套子查询
Criteria miller = new Criteria("lastName").is("Miller")
.subCriteria(
new Criteria().or("firstName").is("John")
.or("firstName").is("Jack")
);
Query query = new CriteriaQuery(criteria);
Criteria为姓氏创建第一个
这与与子标准相结合
此子标准是名字John的 OR 组合
和名字杰克
Criteria有关不同可用操作的完整概述,请参阅该类的 API 文档。
7.6.2.字符串查询
此类将 Elasticsearch 查询作为 JSON 字符串。以下代码显示了一个搜索名字为“Jack”的人的查询:
Query query = new SearchQuery("{ \"match\": { \"firstname\": { \"query\": \"Jack\" } } } ");
SearchHits<Person> searchHits = operations.search(query, Person.class);
StringQuery如果您已经有 Elasticsearch 查询要使用,则使用可能是合适的。
7.6.3.本机搜索查询
NativeSearchQuery是当您有复杂查询或无法使用CriteriaAPI 表达的查询时使用的类,例如在构建查询和使用聚合时。它允许使用QueryBuilderElasticsearch 库中的所有不同实现,因此命名为“native”。
以下代码显示了如何搜索具有给定名字的人,并且找到的文档有一个术语聚合,用于计算这些人的姓氏出现次数:
Query query = new NativeSearchQueryBuilder()
.addAggregation(terms("lastnames").field("lastname").size(10)) //
.withQuery(QueryBuilders.matchQuery("firstname", firstName))
.build();
SearchHits<Person> searchHits = operations.search(query, Person.class);
8. Elasticsearch 存储库
本章包括 Elasticsearch 存储库实现的详细信息。
示例 73. 示例Book实体
@Document(indexName="books")
class Book {
@Id
private String id;
@Field(type = FieldType.text)
private String name;
@Field(type = FieldType.text)
private String summary;
@Field(type = FieldType.Integer)
private Integer price;
// getter/setter ...
}
8.1使用相应映射自动创建索引
@Document注释有一个createIndex参数。如果此参数设置为 true - 这是默认值 - Spring Data Elasticsearch 将在应用程序启动时引导存储库支持期间检查@Document注释定义的索引是否存在。
如果它不存在,则将创建索引并将从实体注释派生的映射(请参阅Elasticsearch 对象映射)写入新创建的索引。可以使用@Setting注释设置将要创建的索引的详细信息,请参阅索引设置以获取更多信息。
8.2.查询方法
8.2.1查询查找策略
Elasticsearch 模块支持所有基本查询构建功能,如字符串查询、本机搜索查询、基于条件的查询或从方法名称派生。
声明的查询
从方法名称派生查询并不总是足够的和/或可能导致不可读的方法名称。在这种情况下,可能会使用@Query注释(请参阅使用 @Query 注释)。
8.2.2.查询创建
通常,Elasticsearch 的查询创建机制如Query Methods中所述工作。以下是 Elasticsearch 查询方法转换为的简短示例:
示例 74. 从方法名称创建查询
interface BookRepository extends Repository<Book, String> {
List<Book> findByNameAndPrice(String name, Integer price);
}
上面的方法名会被翻译成下面的 Elasticsearch json 查询
{
"query": {
"bool" : {
"must" : [
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } },
{ "query_string" : { "query" : "?", "fields" : [ "price" ] } }
]
}
}
}
Elasticsearch 支持的关键字列表如下所示。
GeoJson不支持使用参数 构建地理形状查询的方法名称。如果您需要在存储库中具有这样的功能,请在自定义存储库实现中 使用
ElasticsearchOperationswith 。CriteriaQuery
8.2.3.方法返回类型
可以将存储库方法定义为具有以下返回类型以返回多个元素:
- List<T>
- Stream<T>
- SearchHits<T>
- List<SearchHit<T>>
- Stream<SearchHit<T>>
- SearchPage<T>
8.2.4.使用@Query 注解
示例 75. 在使用@Query注解的方法处声明查询。
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("{\"match\": {\"name\": {\"query\": \"?0\"}}}")
Page<Book> findByName(String name,Pageable pageable);
}
设置为注释参数的字符串必须是有效的 Elasticsearch JSON 查询。它将作为查询元素的值发送到 Easticsearch;例如,如果使用参数John调用该函数,它将产生以下查询体:
{
"query": {
"match": {
"name": {
"query": "John"
}
}
}
}
8.3.反应式 Elasticsearch 存储库
Reactive Elasticsearch 存储库支持建立在使用 Spring Data Repositories中解释的核心存储库支持之上,利用由Reactive Client执行的Reactive Elasticsearch Operations提供的操作。
Spring Data Elasticsearch 响应式存储库支持使用Project Reactor作为其选择的响应式组合库。
有3个主要接口可供使用:
- ReactiveRepository
- ReactiveCrudRepository
- ReactiveSortingRepository
8.3.1.用法
要使用 访问存储在 Elasticsearch 中的域对象Repository,只需为其创建一个接口。在您真正继续并这样做之前,您将需要一个实体。
示例 76. 示例Person实体
public class Person {
@Id
private String id;
private String firstname;
private String lastname;
private Address address;
// … getters and setters omitted
}
请注意,该id属性必须是类型String。
示例 77. 持久化 Person 实体的基本存储库接口
interface ReactivePersonRepository extends ReactiveSortingRepository<Person, String> {
Flux<Person> findByFirstname(String firstname);
Flux<Person> findByFirstname(Publisher<String> firstname);
Flux<Person> findByFirstnameOrderByLastname(String firstname);
Flux<Person> findByFirstname(String firstname, Sort sort);
Flux<Person> findByFirstname(String firstname, Pageable page);
Mono<Person> findByFirstnameAndLastname(String firstname, String lastname);
Mono<Person> findFirstByLastname(String lastname);
@Query("{ \"bool\" : { \"must\" : { \"term\" : { \"lastname\" : \"?0\" } } } }")
Flux<Person> findByLastname(String lastname);
Mono<Long> countByFirstname(String firstname)
Mono<Boolean> existsByFirstname(String firstname)
Mono<Long> deleteByFirstname(String firstname)
}
该方法显示对所有具有给定lastname.
Finder 方法等待输入Publisher以绑定firstname.
Finder 方法按lastname.
Finder 方法通过Sort参数定义的表达式对匹配文档进行排序。
用于Pageable将偏移量和排序参数传递给数据库。
Finder 方法使用And/Or关键字连接条件。
找到第一个匹配的实体。
该方法通过运行带有给定参数lastname的注释来显示对所有具有给定查找的人的查询。@Query
计算所有匹配的实体firstname。
检查是否存在至少一个匹配的实体firstname。
删除所有匹配的实体firstname。
8.3.2.配置
对于 Java 配置,请使用@
EnableReactiveElasticsearchRepositories注解。如果未配置基本包,则基础结构会扫描带注释的配置类的包。
以下清单显示了如何为存储库使用 Java 配置:
示例 78. 存储库的 Java 配置
@Configuration
@EnableReactiveElasticsearchRepositories
public class Config extends AbstractReactiveElasticsearchConfiguration {
@Override
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
return ReactiveRestClients.create(ClientConfiguration.localhost());
}
}
因为上一个示例中的存储库 extends ReactiveSortingRepository,所以所有 CRUD 操作以及对实体进行排序访问的方法都是可用的。使用存储库实例是将依赖注入到客户端的问题,如以下示例所示:
示例 79. 对 Person 实体的排序访问
public class PersonRepositoryTests {
@Autowired ReactivePersonRepository repository;
@Test
public void sortsElementsCorrectly() {
Flux<Person> persons = repository.findAll(Sort.by(new Order(ASC, "lastname")));
// ...
}
}