[英]Spring Data Elasticsearch: Multiple Index with same Document
I'm using spring-data-elasticsearch and for the beginning everything works fine.我正在使用 spring-data-elasticsearch,一开始一切正常。
@Document( type = "products", indexName = "empty" )
public class Product
{
...
}
public interface ProductRepository extends ElasticsearchRepository<Product, String>
{
...
}
In my model i can search for products.在我的模型中,我可以搜索产品。
@Autowired
private ProductRepository repository;
...
repository.findByIdentifier( "xxx" ).getCategory() );
So, my problem is - I've the same Elasticsearch type in different indices and I want to use the same document for all queries.所以,我的问题是 - 我在不同的索引中有相同的 Elasticsearch 类型,我想对所有查询使用相同的文档。 I can handle more connections via a pool - but I don't have any idea how I can implement this.
我可以通过池处理更多连接 - 但我不知道如何实现这一点。
I would like to have, something like that:我想要这样的东西:
ProductRepository customerRepo = ElasticsearchPool.getRepoByCustomer("abc", ProductRepository.class);
repository.findByIdentifier( "xxx" ).getCategory();
Is it possible to create a repository at runtime, with an different index ?是否可以在运行时使用不同的索引创建存储库?
Thanks a lot Marcel非常感谢马塞尔
Yes.是的。 It's possible with Spring.
使用 Spring 是可能的。 But you should use ElasticsearchTemplate instead of
Repository
.但是您应该使用ElasticsearchTemplate而不是
Repository
。
For example.例如。 I have two products.
我有两个产品。 They are stored in different indices.
它们存储在不同的索引中。
@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
}
Suppose if they have the same type, so they have the same fields.假设如果它们具有相同的类型,那么它们具有相同的字段。 But it's not necessary.
但这不是必需的。 Two products can have totally different fields.
两种产品可以有完全不同的领域。
I have two repositories:我有两个存储库:
public interface ProductARepository extends ElasticsearchRepository<ProductA, String> {
}
public interface ProductBRepository
extends ElasticsearchRepository<ProductB, String> {
}
It's not necessary too.也没有必要。 Only for testing.
仅用于测试。 The fact that
ProductA
is stored in "product-a" index and ProductB
is stored in "product-b" index. ProductA
存储在“product-a”索引中, ProductB
存储在“product-b”索引中。
How to query two(ten, dozen) indices with the same type?如何查询两个(十,打)相同类型的索引?
Just build custom repository like this只需像这样构建自定义存储库
@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;
});
}
}
You can search as many indices as you want and you can transparently inject this behavior into ProductARepository
adding custom behavior to single repositories您可以根据需要搜索任意数量的索引,并且可以透明地将此行为注入
ProductARepository
将自定义行为添加到单个存储库
Second solution is to use indices aliases , but you had to create custom model or custom repository too.第二种解决方案是使用索引 aliases ,但您也必须创建自定义模型或自定义存储库。
We can use the withIndices
method to switch the index if needed:如果需要,我们可以使用
withIndices
方法来切换索引:
NativeSearchQueryBuilder nativeSearchQueryBuilder = nativeSearchQueryBuilderConfig.getNativeSearchQueryBuilder();
// Assign the index explicitly.
nativeSearchQueryBuilder.withIndices("product-a");
// Then add query as usual.
nativeSearchQueryBuilder.withQuery(allQueries)
The @Document
annotation in entity will only clarify the mapping, to query against a specific index, we still need to use above method.实体中的
@Document
注解只会澄清映射,要查询特定的索引,我们仍然需要使用上述方法。
@Document(indexName="product-a", type="_doc")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.