如何配置 ElasticsearchRepositoryFactory 以在带有 ElasticsearchCustomConversions 的独立程序中使用 ElasticsearchRepository

How to configure ElasticsearchRepositoryFactory to use a ElasticsearchRepository in a standalone program with ElasticsearchCustomConversions

我有一个 Spring 引导应用程序,其工作配置使用了 ElasticsearchCustomConversions。工作正常。

在此应用程序中,我想创建一些独立的 src/test/java 类,我可以在其中测试我的 ElasticsearchRepository 逻辑。单机因为每次启动Spring 开机太费时间了。

我可以在独立的 java 程序中使用 ElasticsearchRepository,例如:

public class ExampleRepositoryStandaloneTester {

private static ElasticsearchRepositoryFactory factoryBean;

static {
    ClientConfiguration clientConfiguration = ClientConfiguration.builder().connectedTo("localhost:9200").build();
    RestHighLevelClient client = RestClients.create(clientConfiguration).rest();
    ElasticsearchOperations elasticsearchOperations = new ElasticsearchRestTemplate(client);
    factoryBean = new ElasticsearchRepositoryFactory(elasticsearchOperations);
}

public static ProductRepository getProductRepository() {
    return factoryBean.getRepository(ProductRepository.class);
}

public static void main(String[] args) {
    System.out.println("Product count: " + getProductRepository().count());
}}

计数函数实际上是在我的本地 docker 弹性实例上打印产品计数。所以这有效。

但是,我的模型需要 ElasticsearchCustomConversions,但我找不到正确设置 ElasticsearchRepositoryFactory 以便配置和使用转换的方法。

有人知道怎么做吗?

版本是通过 RedHat fuse 版本进行依赖管理的,因此我无法(轻松)升级到更新的版本。

以下尝试失败并显示“找不到能够从类型 [java.lang.Boolean] 转换为类型 [com.my.TrueFalseType] 的转换器”:

public class ExampleCustomConversionsTester {

static class ExampleConfigurator extends AbstractElasticsearchConfiguration {
    private RestHighLevelClient client;
    
    public ExampleConfigurator(RestHighLevelClient client) {
        ExampleConfigurator.this.client = client;
    }
    
    @Override
    public RestHighLevelClient elasticsearchClient() {
        return client;
    }
    
    @Override
    public ElasticsearchCustomConversions elasticsearchCustomConversions() {
        return new ElasticsearchCustomConversions(Collections.singletonList(new TrueFalseTypeConverter()));
    }

    @ReadingConverter
    static class TrueFalseTypeConverter implements Converter<Boolean, TrueFalseType> {
        @Override
        public TrueFalseType convert(Boolean value) {
            return TrueFalseType.fromValue(value.toString());
        }
    }
}

static {
    ClientConfiguration clientConfiguration = ClientConfiguration.builder().connectedTo("localhost:9200").build();
    RestHighLevelClient client = RestClients.create(clientConfiguration).rest();
    ExampleConfigurator cfg = new ExampleConfigurator(client);

    ElasticsearchOperations elasticsearchOperations = new ElasticsearchRestTemplate(cfg.elasticsearchClient());
    MappingElasticsearchConverter elasticsearchConverter = (MappingElasticsearchConverter) elasticsearchOperations.getElasticsearchConverter();
    elasticsearchConverter.setConversions(cfg.elasticsearchCustomConversions());
    factoryBean = new ElasticsearchRepositoryFactory(cfg.elasticsearchOperations(elasticsearchConverter));
}

private static ElasticsearchRepositoryFactory factoryBean;

public static ProductRepository getProductRepository() {
    return factoryBean.getRepository(ProductRepository.class);
}

public static void main(String[] args) {
    System.out.println("Product count: " + getProductRepository().count());
    Page<Product> page = getProductRepository().findProducts(PageRequest.of(0, 10));
}

}

使用

设置转化后
    elasticsearchConverter.setConversions(cfg.elasticsearchCustomConversions());

你需要打电话

elasticsearchConverter.afterPropertiesSet()

setConversions 方法的 Javadoc 中所述。通常 Spring 会这样做,但由于您没有使用 Spring 来设置 bean,因此您需要在代码中这样做。