java - 将 spring-data-elasticsearch 注释与 Jackson ObjectMapper 一起使用?

标签 java elasticsearch jackson spring-data-elasticsearch

假设有一些 POJO 要写入 Elasticsearch 索引。根据我有限的 ES 经验,每个字段都有一个类型(例如文本、关键字……)。是否可以使用 spring-data-elasticsearch 的注释配置 Jackson ObjectMapper 来自定义序列化 Json 的类型?举个例子:

@Document(indexName = "books", type = "book")
public class Book {
    @Id
    @Field(type = FieldType.Keyword)
    String isbn;
    @Field(type = FieldType.Text)
    String title;
}

那么映射应该包括类似的内容

{
  "mappings":
    {
        "book": {
            "properties": {
                "id": {
                    "type": "keyword"
                },
                "title": {
                    "type": "text"
                }
            }
        }
    }
}

如果我的想法有误,请告诉我!

最佳答案

使用 Elasticsearch,您可以让它使用 Dynamic Mapping 自动定义映射。 (您保留文档,ES 根据其输入构建映射),或者您可以在索引之前定义架构通过发送带有相关映射/模板的 ES(.json 文件)。

不推荐使用动态映射选项,并且可能会导致映射问题(错误的日期格式、整数/浮点问题等)

我通常在不使用动态功能的情况下设置映射 - 将其设置为“严格”,这将由 ES 自动引发异常(并将与您使用的任何库一起传播)

"dynamic": "strict",

strict: If new fields are detected, an exception is thrown and the document is rejected. New fields must be explicitly added to the mapping.

使用 Spring-Data-Elasticsearch,您可以按照您发布的方式定义您的对象 - 用想要的类型注释您的字段 - 这将导致 ElasticsearchTemplate.java 解析您的对象(看一下at public <T> boolean putMapping(Class<T> clazz) and public ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz) )并将其输入 ES。

您可以使用 ElasticsearchTemplate 根据您的注释验证 spring-es 索引/映射创建: (测试取自 Spring-Data-ES project )

@Test
public void shouldReturnMappingForGivenEntityClass() {

    // given

    // when
    boolean created = elasticsearchTemplate.createIndex(SampleEntity.class);
    elasticsearchTemplate.putMapping(SampleEntity.class);
    Map<String, Object> mapping = elasticsearchTemplate.getMapping(SampleEntity.class);

    // then
    assertThat(created).isTrue();
    assertThat(mapping).isNotNull();
    assertThat(((Map<String, Object>) ((Map<String, Object>) mapping.get("properties")).get("message")).get("type"))
            .isEqualTo("text");
}

和 SampleEntity:

@Document(indexName = "test-index-sample-mapping", type = "mapping")
static class SampleMappingEntity {

    @Id private String id;

    @Field(type = Text, index = false, store = true, analyzer = "standard")
    private String message;
}

我建议将索引构建与应用程序分开,并且不要使用隐式 POJO 注释选项 - 这在以后会更容易控制。

关于java - 将 spring-data-elasticsearch 注释与 Jackson ObjectMapper 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56794479/

相关文章:

java - 如何为我的jax-rs rest Web服务添加超时

java - Elasticsearch 与 Java API 集成和 SpringBoot 异常

elasticsearch - 带有查找表的Elasticsearch查询

java - 使用自定义构造函数将 JsonNode 转换为 POJO

java - 反序列化映射 Jackson

java - Jackson JSON 流 API : Read an entire object directly to String

java - 更改 JBorderLayout 内 JTextField 的大小

java - 使用mockito测试servlet的NullPointer异常

java - Clojure:输入流比阅读器慢

elasticsearch - ElasticSearch搜索时返回数组的匹配元素