续
二、Elasticsearch Repositories
2.1、简介
2.1.1、Spring命名空间
Spring Data Elasticsearch模块包含一个允许定义存储库bean的自定义名称空间以及用于实例化ElasticsearchServer的元素。使用repositories元素查找Spring Data存储库
示例、使用名称空间设置Elasticsearch存储库
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd"> <elasticsearch:repositories base-package="com.acme.repositories" /> </beans>
使用传输客户端或节点客户端元素在上下文中注册Elasticsearch服务器的实例。
传输客户端使用命名空间
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd"> <elasticsearch:transport-client id="client" cluster-nodes="localhost:9300,someip:9300" /> </beans>
节点客户端使用命名空间
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/data/elasticsearch http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd"> <elasticsearch:node-client id="client" local="true"" /> </beans>
2.1.2、基于注释的配置
Spring Data Elasticsearch存储库支持不仅可以通过XML命名空间激活,还可以通过JavaConfig使用注释。
示例、使用JavaConfig激活Elasticsearch数据储存库
@Configuration
@EnableElasticsearchRepositories(basePackages = "org/springframework/data/elasticsearch/repositories")
static class Config {
@Bean
public ElasticsearchOperations elasticsearchTemplate() {
return new ElasticsearchTemplate(nodeBuilder().local(true).node().client());
}
}
上面的配置设置了ElasticsearchTemplate使用的嵌入式Elasticsearch服务器。Spring Data Elasticsearch Repositories使用@EnableElasticsearchRepositories注释来激活,它本质上具有与XML名称空间相同的属性。如果没有配置基础软件包,它将使用配置类所在的软件包。
2.1.3、Elasticsearch使用CDI进行存储
Spring Data Elasticsearch存储库也可以使用CDI功能进行设置。
示例
class ElasticsearchTemplateProducer { @Produces @ApplicationScoped public ElasticsearchOperations createElasticsearchTemplate() { return new ElasticsearchTemplate(nodeBuilder().local(true).node().client()); } } class ProductService { private ProductRepository repository; public Page<Product> findAvailableBookByName(String name, Pageable pageable) { return repository.findByAvailableTrueAndNameStartingWith(name, pageable); } @Inject public void setRepository(ProductRepository repository) { this.repository = repository; } }
2.2、查询方法
2.2.1、查询策略
Elasticsearch模块支持所有基本的查询构建功能,如String,Abstract,Criteria或从方法名派生。
声明的查询
从方法名称派生查询并不总是足够的和/或可能导致不可读的方法名称。在这种情况下,可以使用@Query注解(请参阅使用@Query注释)。
2.2.2、query创建
示例
public interface BookRepository extends Repository<Book, String>{ List<Book> findByNameAndPrice(String name, Integer price); }
上面的方法名称将被转换为以下Elasticsearch json查询
{ "bool" : { "must" : [ { "field" : {"name" : "?"} }, { "field" : {"price" : "?"} } ] } }
下面显示了Elasticsearch支持的关键字列表。
Keyword | Sample | Elasticsearch Query String |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2.2.3、使用@Query注解
public interface BookRepository extends ElasticsearchRepository<Book, String> { @Query("{"bool" : {"must" : {"field" : {"name" : "?0"}}}}") Page<Book> findByName(String name,Pageable pageable); }
三、其他Elasticsearch操作支持
无法通过存储库接口直接访问的Elasticsearch操作的额外支持。建议将这些操作添加为自定义实现,如Spring Data存储库的自定义实现中所述。
3.1、Filter Builder
private ElasticsearchTemplate elasticsearchTemplate; SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(matchAllQuery()) .withFilter(boolFilter().must(termFilter("id", documentId))) .build(); Page<SampleEntity> sampleEntities = elasticsearchTemplate.queryForPage(searchQuery,SampleEntity.class);
3.2、使用Scan And Scroll查看大结果集
Elasticsearch具有扫描和滚动功能,可以获取大块结果集。 ElasticsearchTemplate具有可用于以下的扫描和滚动方法。
SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(matchAllQuery()) .withIndices("test-index") .withTypes("test-type") .withPageable(new PageRequest(0,1)) .build(); String scrollId = elasticsearchTemplate.scan(searchQuery,1000,false); List<SampleEntity> sampleEntities = new ArrayList<SampleEntity>(); boolean hasRecords = true; while (hasRecords){ Page<SampleEntity> page = elasticsearchTemplate.scroll(scrollId, 5000L , new ResultsMapper<SampleEntity>() { @Override public Page<SampleEntity> mapResults(SearchResponse response) { List<SampleEntity> chunk = new ArrayList<SampleEntity>(); for(SearchHit searchHit : response.getHits()){ if(response.getHits().getHits().length <= 0) { return null; } SampleEntity user = new SampleEntity(); user.setId(searchHit.getId()); user.setMessage((String)searchHit.getSource().get("message")); chunk.add(user); } return new PageImpl<SampleEntity>(chunk); } }); if(page != null) { sampleEntities.addAll(page.getContent()); hasRecords = page.hasNextPage(); } else{ hasRecords = false; } } }
整体spring配置参看