官网地址:https://spring.io/projects/spring-data-elasticsearch#learn,最新稳定版本为3.2.3。
开发文档地址:https://docs.spring.io/spring-data/elasticsearch/docs/3.2.3.RELEASE/reference/html/#reference
版本标识说明
GA:General Availability,正式发布的版本,官方推荐使用此版本。在国外都是用GA来说明release版本的。
PRE: 预览版,内部测试版. 主要是给开发人员和测试人员测试和找BUG用的,不建议使用;
SNAPSHOT: 快照版,可以稳定使用,且仍在继续改进版本。
Spring Data Elasticsearch 开发文档地址:点击查看
版本新特性
Spring Data Elasticsearch 3.2引入了一下新特性:
@Field
中的字段名自定义。Reactive programming support with Reactive Elasticsearch Operations and Reactive Elasticsearch Repositories.这句话这样翻译:响应式的Elasticsearch Operations和响应式的Elasticsearch Repositories一起提供了响应式编程支持。
版本对应说明
Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Boot |
---|---|---|---|
Moore | 3.2.x | 6.8.4 | 2.2.x |
Lovelace | 3.1.x | 6.2.2 | 2.1.x |
Kay | 3.0.x | 5.5.0 | 2.0.x |
Ingalls | 2.1.x | 2.4.0 | 1.5.x |
Spring data Elasticsearch 可以使用Elasticsearch 客户端连接到单一节点或者集群进行操作。
① Transport Client
在前面Java原生操作Elasticsearch我们就使用的是这个客户端,实话说,确实很难用。
static class Config {
//首先得获取客户端
@Bean
Client client() {
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;
}
}
// ...具体使用诸如下面代码
IndexRequest request = new IndexRequest("spring-data", "elasticsearch", randomID())
.source(someObject)
.setRefreshPolicy(IMMEDIATE);
IndexResponse response = client.index(request);
② High Level REST Client(高级REST客户端)
High Level REST Client现在是Elasticsearch默认客户端,它替换掉了Transport Client。异步调用在客户端管理的线程池上操作,并要求在请求完成时通知回调。
引入pom:
org.springframework.data
spring-data-elasticsearch
3.2.3.RELEASE
配置类:
@Configuration
public class ElasticsearchConfig {
@Bean
RestHighLevelClient client() {
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("192.168.18.128:9200")
// .connectedTo("192.168.18.128:9300", "localhost:9301")
.build();
RestHighLevelClient restHighLevelClient = RestClients.create(clientConfiguration).rest();
System.out.println(restHighLevelClient);
return restHighLevelClient;
}
}
测试代码:
@Autowired
RestHighLevelClient highLevelClient;
@Test
public void test() throws IOException {
GetRequest getRequest=new GetRequest("my-blog","_all","1");
RequestOptions option=RequestOptions.DEFAULT;
GetResponse getResponse = highLevelClient.get(getRequest, option);
System.out.println(getResponse.getIndex());
System.out.println(getResponse.toString());
}
控制台打印:
{
"_index": "my-blog",
"_type": "article",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"id": "1",
"title": "基于Lucene的搜索服务器",
"content": "它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口"
}
}
③ Reactive Client
ReactiveElasticsearchClient 是基于WebClient的非官方驱动程序,使用Elasticsearch 核心项目提供的request/response对象。调用直接在反应堆栈上操作,而不是将异步(线程池绑定)响应包装为反应类型。
示例代码如下:
static class Config {
@Bean
ReactiveElasticsearchClient client() {
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200", "localhost:9291")
.build();
return ReactiveRestClients.create(clientConfiguration);
}
}
// ...
Mono response = client.index(request ->
request.index("spring-data")
.type("elasticsearch")
.id(randomID())
.source(singletonMap("feature", "reactive-client"))
.setRefreshPolicy(IMMEDIATE);
);
④ Client Configuration
上面三个客户端对象都是通过ClientConfiguration对象创建出来的,客户端的行为可以通过该对象改变,也可以选择行的进行其他配置,如ssl。
示例代码:
// optional if Basic Auhtentication is needed
HttpHeaders defaultHeaders = new HttpHeaders();
defaultHeaders.setBasicAuth(USER_NAME, USER_PASS);
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200", "localhost:9291")
.withConnectTimeout(Duration.ofSeconds(5))
.withSocketTimeout(Duration.ofSeconds(3))
.useSsl()
.withDefaultHeaders(defaultHeaders)
.withBasicAuth(username, password)
. // ... other options
.build();
Spring Data Elasticsearch允许在通过EntityMapper接口抽象的两个映射实现之间进行选择:
Jackson Object Mapping
Meta Model Object Mapping
① Jackson Object Mapping
基于Jackson2的方法(默认情况下使用)使用带有spring数据特定模块的自定义ObjectMapper实例。实际映射的扩展需要通过Jackson注释(比如@JsonInclude)进行定制。
示例代码:
@Configuration
public class Config extends AbstractElasticsearchConfiguration {
@Override
public RestHighLevelClient elasticsearchClient() {
return RestClients.create(ClientConfiguration.create("localhost:9200")).rest();
}
}
AbstractElasticsearchConfiguration已经通过ElasticsearchConfigurationSupport定义了一个基于Jackson2的entityMapper。注意这时这些注解不能使用:CustomConversions, @ReadingConverter & @WritingConverter
,并且@Field(name="custom-name")
也不行。
② Meta Model Object Mapping
基于元模型的方法使用域类型信息来读/写Elasticsearch。这允许注册特定域类型映射的转换器实例。
示例代码;
@Configuration
public class Config extends AbstractElasticsearchConfiguration {
@Override
public RestHighLevelClient elasticsearchClient() {
return RestClients.create(ClientConfiguration.create("localhost:9200")).rest()
}
@Bean
@Override
public EntityMapper entityMapper() {
ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper(
elasticsearchMappingContext(), new DefaultConversionService()
);
entityMapper.setConversions(elasticsearchCustomConversions());
return entityMapper;
}
}
说明:
③ 对象映射注解
ElasticsearchEntityMapper可以使用元数据来驱动对象到文档的映射。对象上面可以使用注解进行标识。
@Id
: 目标对象主键,字段级别注解。
@Document
: 类级别注解,标明是个文档对象,有如下重要属性:
indexName: 实体中的索引名字
type: the mapping type.如果未设置,则使用类的小写简单名称。
shards: 索引分片数量
replicas: 索引的副本数
refreshIntervall: 索引的刷新间隔。用于创建索引。默认值为“1s”。
indexStoreType:索引存储类型。用于创建索引。默认值为“fs”。
createIndex: 配置是否在存储库引导时创建索引。默认值为true。
versionType: 版本管理的配置,默认值为 EXTERNAL.
@Transient
: 默认所有字段都映射到document, 添加该注解的字段可以例外。
@PersistenceConstructor
: 从数据库中实例化对象时,标记要使用的给定构造函数(甚至是受包保护的构造函数)。构造函数参数按名称映射到检索到的文档中的键值。
@Field
: 应用于字段级别并定义字段的属性,大多数属性映射到相应的Elasticsearch Mapping定义:
name: field映射到Elasticsearch document中的名称,默认为字段名。
type: 字段类型,可以是如下之一: Text, Integer, Long, Date, Float, Double, Boolean, Object, Auto, Nested, Ip, Attachment, Keyword.
format
and pattern
custom definitions for the Date type.
store: 标记原始字段值是否应存储在Elasticsearch中,默认值为false。
analyzer, searchAnalyzer, normalizer用于指定自定义分析器和规范化器。
copy_to: 拷贝到多个文档字段的目标字段
@GeoPoint
:将字段标记为地理位置数据类型。如果字段是GeoPoint类的实例,则可以忽略。
上述映射元数据注解定义在一个单独的spring-data-commons 项目中,是技术无关的。
④ 映射规则
映射规则主要有四方面:
Custom Conversions
可以使用ElasticsearchCustomConversions 注册自定义的映射规则,示例代码如下:
@Configuration
public class Config extends AbstractElasticsearchConfiguration {
@Override
public RestHighLevelClient elasticsearchClient() {
return RestClients.create(ClientConfiguration.create("localhost:9200")).rest();
}
@Bean
@Override
public EntityMapper entityMapper() {
ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper(
elasticsearchMappingContext(), new DefaultConversionService());
entityMapper.setConversions(elasticsearchCustomConversions());
return entityMapper;
}
@Bean
@Override
public ElasticsearchCustomConversions elasticsearchCustomConversions() {
return new ElasticsearchCustomConversions(
Arrays.asList(new AddressToMap(), new MapToAddress()));
}
@WritingConverter
static class AddressToMap implements Converter> {
@Override
public Map convert(Address source) {
LinkedHashMap target = new LinkedHashMap<>();
target.put("ciudad", source.getCity());
// ...
return target;
}
}
@ReadingConverter
static class MapToAddress implements Converter
在第一部分描述新特性时,有个特性是Reactive programming support with Reactive Elasticsearch Operations and Reactive Elasticsearch Repositorie
,这里不能简单翻译而要深入了解一下什么是Reactive Elasticsearch Operations、Reactive Elasticsearch Repositorie才能知道如何提供响应式编程支持。
Spring Data Elasticsearch使用两个接口来定义可以针对Elasticsearch索引调用的操作。分别是ElasticsearchOperations and ReactiveElasticsearchOperations。前者通常用于经典的同步实现,后者用于响应式编程。
接口的默认实现提供如下三方面功能:
① ElasticsearchTemplate
ElasticsearchTemplate是ElasticsearchOperations 接口的一个实现,是基于Transport Client操作的。
示例代码如下:
@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(), entityMapper());
}
// use the ElasticsearchEntityMapper
@Bean
@Override
public EntityMapper entityMapper() {
ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper(elasticsearchMappingContext(),
new DefaultConversionService());
entityMapper.setConversions(elasticsearchCustomConversions());
return entityMapper;
}
}
② ElasticsearchRestTemplate
ElasticsearchRestTemplate是ElasticsearchOperations 接口的另一个实现,其是基于High Level REST Client.实现的。
配置代码示例如下:
@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
@Override
public RestHighLevelClient elasticsearchClient() {
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("192.168.18.128:9200")
.withSocketTimeout(60000)
.withConnectTimeout(60000)
.build();
RestHighLevelClient restHighLevelClient = RestClients.create(clientConfiguration).rest();
System.out.println("RestClientConfig-elasticsearchClient:"+restHighLevelClient);
return restHighLevelClient;
}
// no special bean creation needed
// use the ElasticsearchEntityMapper
@Bean
@Override
public EntityMapper entityMapper() {
ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper(elasticsearchMappingContext(),
new DefaultConversionService());
entityMapper.setConversions(elasticsearchCustomConversions());
return entityMapper;
}
}
③ Spring REST controller中使用ElasticsearchOperations
具体ElasticsearchOperations 使用哪种实现,主要依据上面两种配置。示例代码如下:
@RestController
public class TestController {
@Autowired
private ElasticsearchOperations elasticsearchOperations;
// public TestController(ElasticsearchOperations elasticsearchOperations) {
// this.elasticsearchOperations = elasticsearchOperations;
// }
@PostMapping("/person")
public String save(@RequestBody Person person) {
System.out.println("elasticsearchOperations:"+elasticsearchOperations);
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;
}
}
Person类实例代码:
@Document(indexName = "person",type = "person")
public class Person {
@Id
private Integer id;
@Field
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
上面两个都是ElasticsearchOperations 的实现,下面讲解Reactive Elasticsearch Operations实现。
④ Reactive Elasticsearch Operations
ReactiveElasticsearchOperations是Elasticsearch集群使用ReactiveElasticsearchClient执行高级命令的网关。ReactiveElasticsearchOperations的默认实现是ReactiveElasticsearchTemplate 。
示例代码如下:
@Configuration
public class Config extends AbstractReactiveElasticsearchConfiguration {
@Bean
@Override
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
// ...
}
}
使用ReactiveElasticsearchClient 最简单方法就是继承AbstractReactiveElasticsearchConfiguration 并覆盖reactiveElasticsearchClient方法,然后作为bean暴露给外部。方法体内部可以使用ReactiveRestClients 定义 Reactive Client或者默认使用DefaultReactiveElasticsearchClient。
如果想对组件有更多自定义控制,可以如下所示进行配置:
@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());
}
}
⑤ ReactiveElasticsearchTemplate实际使用
实例代码如下:
@Document(indexName = "marvel", type = "characters")
public class Person {
private @Id String id;
private String name;
private int age;
// Getter/Setter omitted...
}
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();
控制台打印:
> Person(id=QjWCWWcBXiLAnp77ksfR, name=Bruce Banner, age=42)
> Person(id=QjWCWWcBXiLAnp77ksfR, name=Bruce Banner, age=42)
> QjWCWWcBXiLAnp77ksfR
> 0
可以发现相比于RestHighLevelClient 而言ReactiveElasticsearchTemplate主要就是流式编程,可以直接使用Lamda表达式及隐式函数进行操作。
Repository,了解jpa的应该知道,Spring Data默认定义了一些接口实现了一些常用的增删改查方法,你只需要声明自己接口继承于Spring Data的接口即可使用那些方法且不用自己实现。当然,你可以自己实现自己定义方法。
参考博文专栏:Spring Data JPA使用实践详解
① 查询方法与查询策略
Elasticsearch模块支持所有基本的查询构建功能,如字符串查询、本地索查询、基于条件的查询或从方法名派生。从方法名派生查询并不总是足够的,并且/或者可能导致无法读取方法名。在这种情况下,可以使用@Query注解。
通常,Elasticsearch的查询创建机制的工作方式如查询方法中所述,实例如下:
interface BookRepository extends Repository {
List findByNameAndPrice(String name, Integer price);
}
等同于如下Elasticsearch json 查询串:
{ "bool" :
{ "must" :
[
{ "field" : {"name" : "?"} },
{ "field" : {"price" : "?"} }
]
}
}
Elasticsearch 支持的关键字与对应的json 查询列表如下:
Keyword | Sample | Elasticsearch Query String |
---|---|---|
And | findByNameAndPrice | {“bool” : {“must” : [ {“field” : {“name” : “?”}}, {“field” : {“price” : “?”}} ]}} |
Or | findByNameOrPrice | {“bool” : {“should” : [ {“field” : {“name” : “?”}}, {“field” : {“price” : “?”}} ]}} |
Is | findByName | {“bool” : {“must” : {“field” : {“name” : “?”}}}} |
Not | findByNameNot | {“bool” : {“must_not” : {“field” : {“name” : “?”}}}} |
Between | findByPriceBetween | {“bool” : {“must” : {“range” : {“price” : {“from” : ?,“to” : ?,“include_lower” : true,“include_upper” : true}}}}} |
LessThanEqual | findByPriceLessThan | {“bool” : {“must” : {“range” : {“price” : {“from” : null,“to” : ?,“include_lower” : true,“include_upper” : true}}}}} |
GreaterThanEqual | findByPriceGreaterThan | “bool” : {“must” : {“range” : {“price” : {“from” : ?,“to” : null,“include_lower” : true,“include_upper” : true}}}}} |
Before | findByPriceBefore | {“bool” : {“must” : {“range” : {“price” : {“from” : null,“to” : ?,“include_lower” : true,“include_upper” : true}}}}} |
After | findByPriceAfter | {“bool” : {“must” : {“range” : {“price” : {“from” : ?,“to” : null,“include_lower” : true,“include_upper” : true}}}}} |
Like | findByNameLike | {“bool” : {“must” : {“field” : {“name” : {“query” : “?*”,“analyze_wildcard” : true}}}}} |
StartingWith | findByNameStartingWith | {“bool” : {“must” : {“field” : {“name” : {“query” : “?*”,“analyze_wildcard” : true}}}}} |
EndingWith | findByNameEndingWith | {“bool” : {“must” : {“field” : {“name” : {“query” : “*?”,“analyze_wildcard” : true}}}}} |
Contains/Containing | findByNameContaining | {“bool” : {“must” : {“field” : {“name” : {“query” : “?”,“analyze_wildcard” : true}}}}} |
In | findByNameIn(Collection |
{“bool” : {“must” : {“bool” : {“should” : [ {“field” : {“name” : “?”}}, {“field” : {“name” : “?”}} ]}}}} |
NotIn | findByNameNotIn(Collection |
{“bool” : {“must_not” : {“bool” : {“should” : {“field” : {“name” : “?”}}}}}} |
Near | findByStoreNear | Not Supported Yet ! |
True | findByAvailableTrue | {“bool” : {“must” : {“field” : {“available” : true}}}} |
False | findByAvailableFalse | {“bool” : {“must” : {“field” : {“available” : false}}}} |
OrderBy | findByAvailableTrueOrderByNameDesc | {“sort” : [{ “name” : {“order” : “desc”} }],“bool” : {“must” : {“field” : {“available” : true}}}} |
② @Query注解
如果想自定义查询,可以选择在方法上用注解标识查询条件,实例如下:
interface BookRepository extends ElasticsearchRepository {
@Query("{\"bool\" : {\"must\" : {\"field\" : {\"name\" : \"?0\"}}}}")
Page findByName(String name,Pageable pageable);
}
③ 基于注解的配置
Spring Data Elasticsearch repositories using JavaConfig,for example:
@Configuration
@EnableElasticsearchRepositories(
basePackages = "org.springframework.data.elasticsearch.repositories"
)
static class Config {
@Bean
public ElasticsearchOperations elasticsearchTemplate() {
// ...
}
}
class ProductService {
private ProductRepository repository;
public ProductService(ProductRepository repository) {
this.repository = repository;
}
public Page findAvailableBookByName(String name, Pageable pageable) {
return repository.findByAvailableTrueAndNameStartingWith(name, pageable);
}
}
需要说明的是,EnableElasticsearchRepositories注解激活Repository 支持。如果没有配置基包( base package),则它将使用在任何添加该注解的配置类上。
④ Elasticsearch Repositories using CDI*
Spring Data Elasticsearch repositories同样支持CDI(上下文依赖注入)能力,实例如下:
class ElasticsearchTemplateProducer {
@Produces
@ApplicationScoped
public ElasticsearchOperations createElasticsearchTemplate() {
// ...
}
}
class ProductService {
private ProductRepository repository;
public Page findAvailableBookByName(String name, Pageable pageable) {
return repository.findByAvailableTrueAndNameStartingWith(name, pageable);
}
@Inject
public void setRepository(ProductRepository repository) {
this.repository = repository;
}
}
⑤ Spring applicationContext.xml中配置Elasticsearch
Setting up Elasticsearch repositories using Namespace:
Transport Client using Namespace:
Rest Client using Namespace:
Reactive Elasticsearch repository支持Spring Data Repositories核心接口扩展,通过Reactive Elasticsearch Operations实现(Reactive Client实际执行)。
Reactive Elasticsearch repository是使用Project Reactor作为其组件来实现响应编程。
有三个接口主要被使用:
ReactiveRepository
ReactiveCrudRepository
ReactiveSortingRepository
① 配置ReactiveRepositoryConfig
@Configuration
@EnableReactiveElasticsearchRepositories
public class ReactiveRepositoryConfig extends AbstractReactiveElasticsearchConfiguration {
@Override
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("192.168.18.128:9200")
.withSocketTimeout(60000)
.withConnectTimeout(60000)
.build();
ReactiveElasticsearchClient reactiveElasticsearchClient = ReactiveRestClients.create(clientConfiguration);
System.out.println("reactiveElasticsearchClient is created:"+reactiveElasticsearchClient);
return reactiveElasticsearchClient;
}
}
② Domain Object
@Document(indexName = "person",type = "person")
public class Person {
@Id
private String id;
private String firstname;
private String lastname;
//...
}
③ 自定义Repository接口继承自ReactiveSortingRepository
实例代码如下:
public interface ReactivePersonRepository extends ReactiveSortingRepository {
Flux findByFirstname(String firstname);
Flux findByFirstname(Publisher firstname);
Flux findByFirstnameOrderByLastname(String firstname);
Flux findByFirstname(String firstname, Sort sort);
Flux findByFirstname(String firstname, Pageable page);
Mono findByFirstnameAndLastname(String firstname, String lastname);
Mono findFirstByLastname(String lastname);
@Query("{ \"bool\" : { \"must\" : { \"term\" : { \"lastname\" : \"?0\" } } } }")
Flux findByLastname(String lastname);
Mono countByFirstname(String firstname);
Mono existsByFirstname(String firstname);
Mono deleteByFirstname(String firstname);
}
可以看到ReactiveSortingRepository又继承自ReactiveCrudRepository,故而当前ReactivePersonRepository 可以使用CRUD和Sort等方法。
④ 测试代码
@RestController
public class ReactiveController {
@Autowired
ReactivePersonRepository repository;
@RequestMapping("/testReactive")
public String testReactive() {
Flux persons = repository.findAll();
System.out.println(persons.blockFirst());
Mono> listMono = persons.collectList();
System.out.println("listMono:"+ listMono);
List personList = listMono.block();
System.out.println("personList:"+personList);
return persons.toString();
}
}
Elasticsearch Operation还提供了许多其他支持,而这些支持不能直接通过repository 接口来使用,它更被推荐在自定义接口实现里面使用。
① 查询过滤器
实例如下:
private ElasticsearchTemplate elasticsearchTemplate;
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.withFilter(boolFilter().must(termFilter("id", documentId)))
.build();
Page sampleEntities =
elasticsearchTemplate.queryForPage(searchQuery,SampleEntity.class);
② 滚动输出大结果集
Elasticsearch 针对大数据量结果提供了scroll API,ElasticsearchTemplate 有startScroll and continueScroll 方法可以被使用,如下所示:
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.withIndices(INDEX_NAME)
.withTypes(TYPE_NAME)
.withFields("message")
.withPageable(PageRequest.of(0, 10))
.build();
ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class);
String scrollId = scroll.getScrollId();
List sampleEntities = new ArrayList<>();
while (scroll.hasContent()) {
sampleEntities.addAll(scroll.getContent());
scrollId = scroll.getScrollId();
scroll = elasticsearchTemplate.continueScroll(scrollId, 1000, SampleEntity.class);
}
elasticsearchTemplate.clearScroll(scrollId);
ElasticsearchTemplate 同样提供了流方法使用,如下所示:
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.withIndices(INDEX_NAME)
.withTypes(TYPE_NAME)
.withFields("message")
.withPageable(PageRequest.of(0, 10))
.build();
CloseableIterator stream = elasticsearchTemplate.stream(searchQuery, SampleEntity.class);
List sampleEntities = new ArrayList<>();
while (stream.hasNext()) {
sampleEntities.add(stream.next());
}
相关实例代码GitHub地址:https://github.com/JanusJ/SpringBoot/tree/master/elasticsearch