Spring Data Elasticsearch @Document indexName 可在运行时定义

10

是否可以在运行时动态指定每个@DocumentindexName,例如通过配置文件?或者是否可以使@Document与Spring环境(开发、生产)相关联?

谢谢!


还需要一些基于环境/配置文件的解决方案。在注释中硬编码索引名称并不是最佳选择... - David Marko
我曾试图使用类似于@Value的东西来实现相同的功能,但是目前还没有成功。更多信息请参见此问题 - Victor
你不能以这种方式使用@Value,因为它不是由Spring管理/创建的bean,而是由你使用new MyBean()创建的。我仍然无法理解这个注释设置背后的想法。每个人在使用不同的indexName进行开发和生产时都必须处理这个问题。你是如何解决这个问题的? - David Marko
@DavidMarko,我现在想知道是否有人使用spring-data-elasticsearch达到了生产级别... 有人知道一个例子吗? - Dorian
4个回答

25

@Document注解不允许直接在参数中传递索引名称。不过我找到了一个解决方法。

在我的配置类中,我创建了一个返回字符串的Bean。在这个字符串中,我使用@Value注解注入了索引的名称:

@Value("${etrali.indexname}")
private String indexName;

@Bean
public String indexName(){
    return indexName;
}

然后可以将索引注入到 @Documentation 注释中,如下所示:

@Document(indexName="#{@indexName}",type = "syslog_watcher")

对我来说有效,希望能帮到你。

最好的问候


谢谢,实际上这是SpEL的解决方案。 - Xuanyu
你在哪里注册了你的 Bean?我是在带有 @Configuration 注解的 ElasticsearchConfig 类中进行的。但是,似乎我仍然遇到了 java.lang.NoClassDefFoundError 的问题。有什么建议吗? - nonNumericalFloat

4
Bruno提供的解决方案可能可行,但“我创建了一个返回字符串的Bean”这一部分有点令人困惑。
以下是我的做法:
  • 在一个由"<context:property-placeholder location="classpath:application.properties" />"加载的application.properties文件中,将“index.name”键赋值

  • 创建一个名为ConfigBean的Bean,并用@Named@Component进行注释


    @Named
    public class ConfigBean {

      @Value("${index.name}")
      private String indexName;

      public String getIndexName() {
        return indexName;
      }

      public void setIndexName(String indexName) {
        this.indexName = indexName;
      }      

    }
  • 使用Spring EL将configBean.getIndexName()的值注入到"@Document"注解中:@Document(indexName = "#{ configBean.indexName }", type = "myType")

P.S.:您可以直接使用隐式bean“systemProperties”来实现相同的结果(类似于#{ systemProperties['index.name']}),但对我来说它无法工作,而且很难调试,因为您无法在编程上下文中解析systemProperties (https://jira.spring.io/browse/SPR-6651)。


我不知道如何使其工作,但是"@Named"不能应用于类,并且"@Configuration"没有使indexName可发现。 - Cristian Ciobotea
也许你的“@Named”无法,但是我的javax.inject.Named可以。 - Tristan

2

Bruno的解决方案可行,但是没有必要以这种方式创建一个新的Bean。我的做法是:

  • 创建一个带有@org.springframework.stereotype.Service注释的bean,在其中从数据库中加载索引名称:
@Service
public class ElasticsearchIndexConfigService {

    private String elasticsearchIndexName;

    // some code to update the elasticsearchIndexName variable

    public String getIndexName() {
        return elasticsearchIndexName;
    }
}
  • 使用SpEL从@Document注释中的bean调用getIndexName()方法:
@Document(indexName = "#{@elasticsearchIndexConfigService.getIndexName()}", createIndex = false)
public class MyEntity {

}


关键是要使用@ - #{elasticsearchIndexConfigService.getIndexName()}是无效的。我浪费了一些时间才弄清楚这一点。

0

这对我有用
application.properties

index.prefix=test

然后使用这段代码

@Document(indexName = "#{@environment.getProperty('index.prefix')}")


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接