Java – spring data elasticsearch: multiple indexes with the same document
I used spring data elastic search and everything was normal at first
@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 use the same elasticsearch type in different indexes, and I want to use the same document for all queries I can handle more connections through the pool - but I don't know how to do that
I think so, like this:
ProductRepository customerRepo = ElasticsearchPool.getRepoByCustomer("abc",ProductRepository.class); repository.findByIdentifier( "xxx" ).getCategory();
Is it possible to create a repository at run time with different indexes?
Thank you very much, Marcel
Solution
Yes It may be different from spring However, you should use elasticsearchtemplate instead of repository
For example I have two products They are stored in different indexes
@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 they have the same fields if they have the same type But it's not necessary Two products can have completely different areas
I have two repositories:
public interface ProductARepository extends ElasticsearchRepository<ProductA,String> { } public interface ProductBRepository extends ElasticsearchRepository<ProductB,String> { }
It's not necessary For testing purposes only The fact that ProductA is stored in the "product-a" index and productb is stored in the "product-b" index
How do I query two (ten, ten) indexes of the same type?
Just build such a custom repository
@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 any number of indexes, and you can transparently inject this behavior into the product repository adding custom behavior to single repositories
The second solution is to use indices aliases, but you must also create custom models or custom repositories