如何对LocalDateTime字段实现多字段索引及通配符、范围查询
解决LocalDateTime字段同时支持通配符与范围查询的Elasticsearch配置方案
问题回顾
需要对LocalDateTime类型的submissionDate字段同时执行两种查询:
- 范围查询:依赖Elasticsearch的
date类型特性 - 通配符查询:仅支持
keyword/text/wildcard类型字段
之前的两种配置均存在问题:
- 单独配置
FieldType.Date:字段为date类型,无法执行通配符查询,报错:Can only use wildcard queries on keyword, text and wildcard fields - not on [submission_date] which is of type [date] - 错误的
MultiField配置:主字段被转为long类型(时间戳),导致查询时出现类型转换错误:No converter found capable of converting from type [java.lang.Long] to type [java.time.LocalDateTime]
正确配置方案
使用@MultiField分别配置主字段和子字段,兼顾两种查询需求:
// @formatter:off @MultiField( mainField = @Field( name = "submission_date", type = FieldType.Date, format = DateFormat.date_hour_minute_second_fraction ), otherFields = @InnerField( suffix = "keyword", type = FieldType.Keyword, // 指定日期格式化规则,将日期转为字符串存储为keyword类型 format = DateFormat.date_hour_minute_second_fraction ) ) // @formatter:on private LocalDateTime submissionDate;
配置说明
- 主字段
submission_date:保持date类型,指定date_hour_minute_second_fraction格式,用于执行范围查询,且返回结果能正确映射回LocalDateTime类型。 - 子字段
submission_date.keyword:设为keyword类型,通过相同的日期格式化规则,让Elasticsearch将日期转为格式化后的字符串(如"2022-11-17T00:00:00.000")存储,满足通配符查询的要求。
验证映射
重建索引并重新导入文档后,执行GET https://localhost:9200/my_index/_mapping,应看到:
submission_date类型为date,格式为date_hour_minute_second_fractionsubmission_date.keyword类型为keyword,存储格式化后的日期字符串
查询示例
范围查询(使用主字段)
{ "query": { "range": { "submission_date": { "gte": "2022-11-01T00:00:00.000", "lte": "2022-11-30T23:59:59.999" } } } }
通配符查询(使用子字段)
{ "query": { "wildcard": { "submission_date.keyword": "2022-11-17*" } } }
内容的提问来源于stack exchange,提问作者Tapas Bose
相关产品推荐
相关产品推荐

