Динамическое присвоение имен индексу с помощью имени класса

#java #elasticsearch #spring-data-elasticsearch

#java #elasticsearch #spring-data-эластичный поиск

Вопрос:

Я создаю фреймворк для spring-data-elasticsearch в качестве практического проекта. Мой вопрос касается тега @Document, который создаст индекс на основе имени, указанного в параметре IndexName аннотации.

Тем не менее, я думаю, возможно ли сделать его динамичным! В большинстве моих случаев использования имя индекса будет соответствовать имени класса. Все мои классы индексов будут расширять абстрактный класс, который имеет общую реализацию для всех, и конкретные реализации должны быть выполнены в классе сущностей.

Это означает, что я должен поддерживать аннотацию @Document для каждого объекта. Но поскольку все объекты будут расширять определенный абстрактный класс, возможно ли аннотировать абстрактный класс и каким-то образом указывать spring использовать имя класса в качестве имени индекса.

 import org.springframework.data.elasticsearch.annotations.Document;

@Document(indexName = "BaseClassName OR something like Animal.getName" /*And other index properties of-course*/)
abstract class Animal {
String name;

public String getName() {
    return name;
}

public abstract String makeSomeNoise();
}
  

Весь конкретный класс, который расширяет Animals, будет проиндексирован в Elasticserch.

 abstract class TwoLeggedAnimals extends Animal {}

abstract class FourLeggedAnimals extends Animal {}
  

Вышеупомянутые два являются просто классами группировки. Для примера

 class Duck extends TwoLeggedAnimals {
public Duck() {
    this.name = Duck.class.getSimpleName();
}
@Override
public String makeSomeNoise() {
    return "quack";
}
}
  

Класс Duck расширяет класс TwoLeggedAnimals, который, в свою очередь, расширяет класс «Animals» и, таким образом, Duck имеет право на создание индекса.
То же объяснение для класса Horse

 class Horse extends FourLeggedAnimals {
Horse() {
    this.name = Horse.class.getSimpleName();
}

@Override
public String makeSomeNoise() {
    return "neigh";
}
}
  

Ответ №1:

Вы не написали, в чем заключается ваша конкретная проблема или ошибка и какую версию ES вы используете.

Вы можете поместить @Document аннотацию с именем индекса в абстрактный базовый класс, а затем использовать производный класс для сохранения ваших объектов в индексе без добавления каких-либо аннотаций к вашему производному классу; это работает без проблем.

Но вы не можете хранить разные типы (например TwoLeggedAnimals , и FourLeggedAnimals ) в одном и том же индексе, начиная с Elasticsearch 6.0 (см. Основные изменения ES 6.0). Ваша программа будет работать до тех пор, пока вы используете один тип, как только вы попытаетесь сохранить второй тип, вы получите

Исключение Elasticsearch [тип= illegal_argument_exception, причина = Отклонение обновления сопоставления для [animals], поскольку окончательное сопоставление будет иметь более 1 типа: [twoleggedanimal, fourleggedanimal]]

Последняя версия 5.x 5.6 поддерживалась до 2019-03-11 (эластичные даты окончания срока службы), так что это больше не поддерживается.

Итак, поскольку невозможно хранить в индексе более одного типа, вам придется переосмыслить свои классы и способы их хранения — пожалуйста, проверьте также удаление типов, если описанные там альтернативы могут вам помочь.

Комментарии:

1. Проблема заключается в определении нескольких индексов, а не типов. Итак, в приведенном выше примере мне нужно создать индекс с помощью Horse и Duck, не добавляя никаких аннотаций к классу Horse или Duck.

2. извините, я вас неправильно понял. Для разрешения имени динамического индекса есть две проблемы jira.spring.io/browse/DATAES-387 и jira.spring.io/browse/DATAES-456 а также запрос на извлечение github.com/spring-projects/spring-data-elasticsearch/pull/221 который, увы, не соответствует необходимым соглашениям о вкладе, поэтому до сих пор не был объединен.