问题也许任何人都有解决方案如何按月或按天过滤/查询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
主要问题是如何按月和日搜索用户。忽略这一年,因为生日是我们所知道的每年。
解 我找到了使用通配符查询生日的解决方案。我们知道如果我们想要使用通配符,则字段的映射必须是字符串,因此我使用了多字段映射。
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*"
}
}
}
注意 此查询可能很慢,因为它需要迭代许多术语。
结论 这不是很好的方式,但它是我发现的唯一一个有效的方法!
答案 0 :(得分:2)
根据您的问题,我假设您需要查询,而不是过滤器(它们不同),您可以使用日期数学/格式与范围查询相结合。
请参阅:range query了解用法
有关日期数学的说明,请参阅以下link
curl -XPOST http://localhost:9200/twitter/tweet/_search -d
{
"query": {
"range": {
"birthday": {
"gte" : "2014-01-01",
"lte" : "2014-01-01"
}
}
}
}
我使用最新的弹性搜索对此进行了测试。
答案 1 :(得分:1)
您应该在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日,则范围查询有可能被忽略。
答案 2 :(得分:0)
如果您不想解析字符串,可以使用简单的脚本。当dateField在任何一年中具有特定月份时,此过滤器将匹配:
"filter": {
"script": {
"lang": "expression",
"script": "doc['dateField'].getMonth() == month",
"params": {
"month": 05,
}
}
}
注意:month参数为0索引。
相同的方法适用于某一天或任何其他日期组件。