Поиск в спящем режиме и elasticsearch: mapper_parsing_exception + analyzer [] не найден для поля []

Я использую поиск в спящем режиме для автоматического создания индексов для определенного объекта

@Entity
@Indexed
public class Entity extends BaseEntity {

    private static final long serialVersionUID = -6465422564073923433L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    @Field(bridge = @FieldBridge(impl = PropertyFieldBridge.class))
    private List<PropertyValue> properties = new ArrayList<>(); // PropertyValue is an abstract

}

Мост полей создает строковые поля в формате: pt_ [a-zA-Z0-9] + _ i18n.

И после этого я создаю динамический шаблон для работы с переведенными полями:

PUT {{elasticsearch}}/com.orm.entity.entity.entity/com.orm.entity.entity.Entity/_mapping
{
  "com.gamila.api.orm.entity.entity.Entity": {
    "dynamic_templates": [
      {
        "my_analyzer": {
          "match_mapping_type": "string",
          "match_pattern": "regex",
          "match": "^pt_[a-zA-Z0-9]+_i18n",
          "mapping": {
            "type": "text",
            "analyzer": "portugueseAnalyzer"
          }
        }
      }
    ]
  }
}

Но когда я создаю объект, он всегда возвращает ошибку:

Response: 400 'Bad Request' with body 
{
  "error": {
    "root_cause": [
      {
        "type": "mapper_parsing_exception",
        "reason": "analyzer [portugueseAnalyzer] not found for field [pt_name_i18n]"
      }
    ],
    "type": "mapper_parsing_exception",
    "reason": "analyzer [portugueseAnalyzer] not found for field [pt_name_i18n]"
  },
  "status": 400
}

Португальский анализатор определяется через:

public class Analyzer implements ElasticsearchAnalysisDefinitionProvider {

    @Override
    public void register(ElasticsearchAnalysisDefinitionRegistryBuilder builder) {
        builder.analyzer("portugueseAnalyzer")
                .withTokenizer("standard")
                .withTokenFilters("lowercase", "portugueseStemmer", "portugueseStop", "edge_ngram_3");

        builder.tokenFilter("portugueseStemmer")
                .type("stemmer").param("language", "portuguese");
        builder.tokenFilter("portugueseStop")
                .type("stop").param("stopwords", "_portuguese_");
    }

}

Может кто-нибудь сказать мне, что я делаю не так? Я уже безуспешно просматривал некоторые вопросы здесь, в stackoverflow.

PS: я использую elasticsearch (5.6) от AWS

заранее спасибо


person raffah    schedule 30.03.2020    source источник


Ответы (1)


Когда Hibernate Search 5 отправляет сопоставление в Elasticsearch, он будет включать только определения анализаторов для анализаторов, которые фактически используются где-то в сопоставлении. В вашем случае анализатор не используется в Hibernate Search, поэтому игнорируется.

В качестве обходного пути в Hibernate Search 5 вы можете объявить фиктивное поле, которое использует ваш анализатор, но никогда не будет заполнено. Вы можете найти пример того, как это сделать, здесь.

person yrodiere    schedule 30.03.2020
comment
Спасибо за помощь, это сработало, но как насчет того, чтобы поддерживать несколько языков, а не только португальский? Мне нужно создать фиктивное поле для каждого языка? - person raffah; 30.03.2020
comment
@raffah Да. Вам придется применять @Field несколько раз с другим именем и другим анализатором. - person yrodiere; 30.03.2020