我刚刚开始使用 Elasticsearch,想对映射为 date
、格式为 hour_minute
的字段使用基于脚本的排序。每个文档中可以有多个字段实例。
在介绍表达式之前,作为第一步,我尝试了一个简单的排序(使用 Sense 插件):
POST myIndex/_search
{
"query": {
"match_all": {}
},
"sort": {
"_script": {
"script": "doc[\"someTime\"].value",
"lang": "groovy",
"type": "date",
"order": "asc"
}
}
}
我收到此错误(片段):
SearchPhaseExecutionException[Failed to execute phase [query], all shards failed;
shardFailures {[tjWL-zV5QXmGjNlXzLvrzw][myIndex][0]:
SearchParseException[[myIndex][0]:
query[ConstantScore(*:*)],from[-1],size[-1]: Parse Failure [Failed to parse source…
如果我使用 "type": "number"
发布上述查询,则没有错误,尽管这当然不是按日期排序。以下工作正常:
POST myIndex/_search
{
"query": {
"match_all": {}
},
"sort": {
"someTime": {
"order": "asc"
}
}
}
最终我想使用基于脚本的排序,因为我将尝试使用日期和时间条件进行查询、过滤或排序,例如查询具有今天日期的文档,然后按日期之后的最短时间对它们进行排序现在时间等
如有任何建议,我们将不胜感激。
最佳答案
使用脚本对文档进行排序并不是真正有效的,尤其是当您的文档库预计会随着时间的推移而增长时。因此,我将提供一种解决方案,然后提出另一种选择。
为了使用脚本进行排序,您需要将日期转换为毫秒,以便您的排序可以在一个简单的数字上运行(排序类型只能是number
或string
).
POST myIndex/_search
{
"query": {
"match_all": {}
},
"sort": {
"_script": {
"script": "doc[\"someTime\"].date.getMillisOfDay()",
"lang": "groovy",
"type": "number", <----- make sure this is number
"order": "asc"
}
}
}
请注意,根据您想要的粒度,您还可以使用 getSecondOfDay()
或 getMinuteOfDay()
。这样,如果您的查询和过滤器选择了正确日期的文档,您的排序脚本将根据当天的毫秒数(或秒或分钟)对文档进行排序。
第二种解决方案意味着还将自那天开始以来的毫秒数(或秒或分钟)索引到另一个字段中,并简单地使用它进行排序,这样您就不需要脚本了。最重要的是,无论您在搜索时需要什么信息,只要在索引时就知道,都应该编入索引,而不是实时计算。
例如,如果您的 someTime
字段包含日期 2015-10-05T05:34:12.276Z
那么您将索引 millisOfDay
值为 20052276
的字段,即
- 5 小时 * 3600000 毫秒
- +34 分钟 * 60000 毫秒
- +12 秒 * 1000 毫秒
- +276 毫秒
然后你可以使用排序
POST myIndex/_search
{
"query": {
"range": {
"someTime": {
"gt": "now"
}
}
},
"sort": {
"millisOfDay": {
"order": "asc"
}
}
}
请注意,我添加了一个查询以仅选择 someTime
日期晚于现在的文档,因此您将获得 future 的所有文档,但按 millisOfDay< 升序排序
,这意味着您将首先获得离现在
最近的日期。
更新
如果 someTime
的格式为 HH:mm
,那么您还可以存储它的 millisOfDay
值,例如如果 someTime = 17:30
那么 millisOfDay
将是 (17h * 3600000 ms) + (30 min * 60000 ms) = 63000000
然后,您的查询需要使用 script
过滤器稍微修改一下,如下所示:
{
"query": {
"filtered": {
"filter": {
"script": {
"script": "doc.millisOfDay.value > new DateTime().millisOfDay"
}
}
}
},
"sort": {
"millisOfDay": {
"order": "asc"
}
}
}
关于sorting - 基于脚本的 Elasticsearch 日期字段排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32933085/