#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 который, увы, не соответствует необходимым соглашениям о вкладе, поэтому до сих пор не был объединен.