Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Index with SpringData ElasticSearch

How can I parameterize a SpringData ElasticSearch index at runtime?

For example, the data model:

@Document(indexName = "myIndex")
public class Asset {

    @Id
    public String id;

    // ...
}

and the repository:

public interface AssetRepository extends ElasticsearchCrudRepository<Asset, String> {

    Asset getAssetById(String assetId);
}

I know I can replace myIndex with a parameter, but that parameter will be resolved during instantiation / boot. We have the same Asset structure for multiple clients / tenants, which have their own index. What I need is something like this:

public interface AssetRepository extends ElasticsearchCrudRepository<Asset, String> {

    Asset getAssetByIdFromIndex(String assetId, String index);
}

or this

repoInstance.forIndex("myOtherIndex").getAssetById("123");

I know this does not work out of the box, but is there any way to programmatically 'hack' it?

like image 456
Daniel Avatar asked Nov 08 '22 19:11

Daniel


1 Answers

Even though the bean is init at boot time, you can still achieve it by spring expression language:

@Bean
Name name() {
    return new Name();
}

@Document(indexName="#{name.name()}")
public class Asset{}

You can change the bean's property to change the index you want to save/search:

    assetRepo.save(new Asset(...));
    name.setName("newName");
    assetRepo.save(new Asset(...));

What should be noticed is not to share this bean in multiple thread, which may mess up your index.

Here is a working example.

like image 159
Tony Avatar answered Nov 15 '22 10:11

Tony