【问题标题】:ElasticSearch Spring - disable date_detection only for a set of fields and not the entire index using @Mapping annotationElasticSearch Spring - 仅对一组字段而不是使用 @Mapping 注释的整个索引禁用 date_detection
【发布时间】:2022-08-16 22:52:30
【问题描述】:

我试图在索引中的一组字段上禁用 date_detection。下面是映射

{
  \"my-index\" : {
    \"mappings\" : {
      \"properties\" : {
        \"_class\" : {
          \"type\" : \"text\",
          \"fields\" : {
            \"keyword\" : {
              \"type\" : \"keyword\",
              \"ignore_above\" : 256
            }
          }
        },
        \"customFields\" : {
          \"properties\" : {
            \"firstName\" : {
              \"type\" : \"text\",
              \"fields\" : {
                \"keyword\" : {
                  \"type\" : \"keyword\",
                  \"ignore_above\" : 256
                }
              }
            },
            \"lastName\" : {
              \"type\" : \"text\",
              \"fields\" : {
                \"keyword\" : {
                  \"type\" : \"keyword\",
                  \"ignore_above\" : 256
                }
              }
            },
            \"address\" : {
              \"type\" : \"text\",
              \"fields\" : {
                \"keyword\" : {
                  \"type\" : \"keyword\",
                  \"ignore_above\" : 256
                }
              }
            },
            \"dateOfBirth\" : {
              \"type\" : \"date\"
            }
          }
        },
        \"key\" : {
          \"type\" : \"long\"
        },
        \"updatedDate\" : {
          \"type\" : \"date\",
          \"format\" : \"basic_date_time\"
        }
      }
    }
  }
}

我希望dateOfBirth 字段的类型为text,而不是date

所以我做了以下事情:

我创建了一个mappings.json 文件(见下文)并使用了@Mapping(mappingPath = \"mappings.json\") 注释

{
  \"date_detection\": false
}

现在,这确实禁用了date_detection,但它也强制updatedDate 的类型为text,这会导致一些错误。

这些是我的索引类中的 updatedDatecustomFields 变量:

@Field(type = FieldType.Date, format = DateFormat.basic_date_time)
Instant updatedDate;

Map<String, Object> customFields;

有没有办法为customFields 中的字段禁用date_detection,以便只有dateOfBirth 字段的类型更改为text 而不是updatedDate

    标签: elasticsearch elastic-stack spring-data-elasticsearch


    【解决方案1】:

    https://www.elastic.co/guide/en/elasticsearch/reference/8.2/dynamic-field-mapping.html#_disabling_date_detection阅读文档日期检测是每个索引,不能为单个字段配置。

    如果您使用映射文件,Spring Data Elasticsearch 不会从实体创建映射,而仅使用该文件,因此您的 @Field 注释将被忽略。

    updatedDate 上保留@Field 注释并添加

    @Mapping(dateDetection = Mapping.Detection.FALSE)
    

    到您的实体类(带有@Document 注释的实体类)。删除对 mapping.json 的引用。

    【讨论】:

    • 我使用的是较旧的库版本 (4.0.0),它没有带有 date_detection 的 @Mapping 注释。由于 Aggregations & AggregationContainers,更新到较新的版本 (4.3) 会导致项目中出现很多问题。
    • 看来 dateDetected 属性仅适用于较新版本的 Spring Data ElasticSearch。 Spring Data ElasticSearch 4.0.4 是否有类似的方法来完成此任务?
    【解决方案2】:

    P.J. Meisch 提供的答案效果很好。但是旧版本的 Spring Data Elasticsearch 不包含 @Mapping 注释的 dateDetection 属性。如果您无法升级 Spring Data Elasticsearch,您可以使用以下方式注释字段:

    @Field(type = FieldType.Text, store = true)

    这将阻止 Elasticsearch 根据其值推断文本字段的数据类型,如果它包含通用日期格式的数据,则将其映射为日期。如果您有一个字符串字段,其中的记录有时可能包含有效日期格式的数据,而有时则不是,这很有用。在这些情况下,基于值的字段自动映射是有问题的,因为如果 Elastic 索引的第一个值恰好是有效的日期格式,它会将字段映射为日期。不包含有效日期数据的被索引的后续记录将被拒​​绝,因为它们不能被解析为日期。

    根据documentationstore 属性用于“标记原始字段值是否应存储在 Elasticsearch 中,默认值为 false”。因此,虽然属性的名称可能会让人相信它用于将字段标记为瞬态或类似的东西,但它似乎实际上是用来告诉 Elastic 仅逐字索引字段值而不是评估值以推断其类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-22
      • 1970-01-01
      相关资源
      最近更新 更多