Spring Data Elasticsearch:具有相同文档的多个索引
Posted
技术标签:
【中文标题】Spring Data Elasticsearch:具有相同文档的多个索引【英文标题】:Spring Data Elasticsearch: Multiple Index with same Document 【发布时间】:2015-04-12 12:33:48 【问题描述】:我正在使用 spring-data-elasticsearch,一开始一切正常。
@Document( type = "products", indexName = "empty" )
public class Product
...
public interface ProductRepository extends ElasticsearchRepository<Product, String>
...
在我的模型中我可以搜索产品。
@Autowired
private ProductRepository repository;
...
repository.findByIdentifier( "xxx" ).getCategory() );
所以,我的问题是 - 我在不同的索引中有相同的 Elasticsearch 类型,我想对所有查询使用相同的文档。我可以通过池处理更多连接 - 但我不知道如何实现这一点。
我想拥有类似的东西:
ProductRepository customerRepo = ElasticsearchPool.getRepoByCustomer("abc", ProductRepository.class);
repository.findByIdentifier( "xxx" ).getCategory();
是否可以在运行时创建具有不同索引的存储库?
非常感谢 马塞尔
【问题讨论】:
【参考方案1】:是的。春天是可能的。但是你应该使用ElasticsearchTemplate 而不是Repository
。
例如。我有两种产品。它们存储在不同的索引中。
@Document(indexName = "product-a", type = "product")
public class ProductA
@Id
private String id;
private String name;
private int value;
//Getters and setters
@Document(indexName = "product-b", type = "product")
public class ProductB
@Id
private String id;
private String name;
//Getters and setters
假设如果它们具有相同的类型,那么它们具有相同的字段。但这不是必需的。两种产品可以有完全不同的领域。
我有两个仓库:
public interface ProductARepository extends ElasticsearchRepository<ProductA, String>
public interface ProductBRepository
extends ElasticsearchRepository<ProductB, String>
也没有必要。仅用于测试。 ProductA
存储在“product-a”索引中,ProductB
存储在“product-b”索引中。
如何查询两个(十、十)同类型的索引?
只需像这样构建自定义存储库
@Repository
public class CustomProductRepositoryImpl
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;
public List<ProductA> findProductByName(String name)
MatchQueryBuilder queryBuilder = QueryBuilders.matchPhrasePrefixQuery("name", name);
//You can query as many indices as you want
IndicesQueryBuilder builder = QueryBuilders.indicesQuery(queryBuilder, "product-a", "product-b");
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build();
return elasticsearchTemplate.query(searchQuery, response ->
SearchHits hits = response.getHits();
List<ProductA> result = new ArrayList<>();
Arrays.stream(hits.getHits()).forEach(h ->
Map<String, Object> source = h.getSource();
//get only id just for test
ProductA productA = new ProductA()
.setId(String.valueOf(source.getOrDefault("id", null)));
result.add(productA);
);
return result;
);
您可以搜索任意数量的索引,并且可以将此行为透明地注入ProductARepository
adding custom behavior to single repositories
第二种解决方案是使用indices aliases,但您也必须创建自定义模型或自定义存储库。
【讨论】:
【参考方案2】:如果需要,我们可以使用the withIndices
method来切换索引:
NativeSearchQueryBuilder nativeSearchQueryBuilder = nativeSearchQueryBuilderConfig.getNativeSearchQueryBuilder();
// Assign the index explicitly.
nativeSearchQueryBuilder.withIndices("product-a");
// Then add query as usual.
nativeSearchQueryBuilder.withQuery(allQueries)
entity中的@Document
注解只会明确映射关系,要查询具体的索引,还是需要使用上面的方法。
@Document(indexName="product-a", type="_doc")
【讨论】:
以上是关于Spring Data Elasticsearch:具有相同文档的多个索引的主要内容,如果未能解决你的问题,请参考以下文章
springboot 集成 spring-data-elasticsearch
Spring BootSpring Boot之使用 Spring Data Elasticsearch 整合elasticsearch