问题 也许有人有如何按月或天过滤/查询 ElasticSearch 数据的解决方案?假设我需要获取今天庆祝生日的所有用户。
映射
mappings:
dob: { type: date, format: "dd-MM-yyyy HH:mm:ss||yyyy-MM-dd'T'HH:mm:ss'Z'||yyyy-MM-dd'T'HH:mm:ss+SSSS"}
并以这种方式存储:
dob: 1950-06-03T00:00:00Z
main problem is how to search users by month and day only. Ignore the year, because birthday is annually as we know.
SOLUTION I found solution to query birthdays with wildcards. As we know if we want use wildcards, the mapping of field must be a string, so I used multi field mapping.
mappings:
dob:
type: multi_field
fields:
dob: { type: date, format: "yyyy-MM-dd'T'HH:mm:ss'Z'}
string: { type: string, index: not_analyzed }
仅按月和日获取用户的查询是:
{
"query": {
"wildcard": {
"dob.string": "*-06-03*"
}
}
}
注意 此查询可能会很慢,因为它需要遍历许多术语。
结论 这不是很好的方法,但它是我找到的唯一一种并且有效!
最佳答案
您应该将要搜索的值存储在 Elasticsearch 中。字符串/通配符解决方案只完成了一半,但存储数字会更好(更快):
mappings:
dob:
type: date, format: "yyyy-MM-dd'T'HH:mm:ss'Z'
dob_day:
type: byte
dob_month:
type: byte
例子:
dob: 1950-03-06
dob_day: 06
dob_month: 03
过滤(或查询)纯数字很容易:匹配两个字段。
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"dob_day": 06,
}
},
{
"term": {
"dob_month": 03,
}
},
]
}
}
}
}
PS:在考虑解决方案时:将日期存储为自合并数字,如“06-03”->“603”或“6.03”不太明显,但允许使用范围查询。但请记住,531 (05-31) 加上一天就是 601 (06-01)。
手动计算的儒略日期也可能很方便,但计算必须始终假定 2 月为 29 天,并且如果范围包括 2 月 29 日,则范围查询有可能偏离 1。
关于Elasticsearch 按部分日期过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24010876/