Sorting “如何指定”;“精确性”;在Elasticsearch中按日期字段排序时?
在我的Elasticsearch映射中,我有一个类型为Sorting “如何指定”;“精确性”;在Elasticsearch中按日期字段排序时?,sorting,elasticsearch,Sorting,elasticsearch,在我的Elasticsearch映射中,我有一个类型为date(输入格式epoch\u second)的字段(我使用的是ES 2.1)。我知道我可以在这个领域像 { "sort": [ { "myDateField" : { "order": "desc" } } ] } 但这种排序以秒为单位。我想按“周间隔”(从现在起按7天间隔)排序,并在同一周内再次按分数排序,如下(psedoocode): 因此,过去7天内的所有点击
date
(输入格式epoch\u second
)的字段(我使用的是ES 2.1)。我知道我可以在这个领域像
{
"sort": [
{
"myDateField" : {
"order": "desc"
}
}
]
}
但这种排序以秒为单位。我想按“周间隔”(从现在起按7天间隔)排序,并在同一周内再次按分数排序,如下(psedoocode):
因此,过去7天内的所有点击都应该平均排列,在下一个“排序组”中,所有大于7天且小于14天的点击都应该平均排列,以此类推。每个“周组”应再次按分数排序
换句话说:“过去7天中(与当前查询)最相关的文档是什么(但不要完全过滤掉旧文档)?”
背景:一个事件搜索,显然最近的事件应该是最重要的
我怎样才能做到这一点呢?在你的情况下,你可能会发现一个有用的方法。它专门用于调整文档的分数,其中一个字段的“距离”是从某个定义的起点开始的
这适用于日期、数字和地理点字段。它接受一个origin
选项,该选项设置比较其他文档的参考日期。方便的是,如果您没有为日期字段提供原点,则默认为当前日期(该日期适用于您的场景)
您可能希望将偏移量设置为7天。这样,过去7天的所有文件都将获得同等分数。在该范围之外,分数开始下降,具体取决于您使用的衰减函数
试着这样做:
{
"query": {
"function_score": {
"query": {
"match": {
"field1": "search goes here"
}
},
"functions": [
{
"exp": {
"myDateField": {
"offset": "7d",
"scale": "14d",
"decay": 0.5
}
}
}
]
}
}
}
我阅读了有关脚本排序的内容,这是我的解决方案,对我来说很有用:
{
"sort": [
"_script": {
"lang": "expression",
"type": "number",
"script": "doc['myDateField'].value - doc['myDateField'].value % 604800000"
"order": "desc"
},
"_score"
]
}
我在这里所做的是将我的日期字段除以以毫秒表示的所需跨度(Elasticsearch在内部将日期字段存储为long
,映射为毫秒),然后取剩余部分。然后从实际日期中减去余数。这样,所有日期都会被截断为“0到6天前的上午0点”。这样,相同7天间隔内的所有文档都将具有相同的时间戳,并根据时间戳进行同等排序。最后,我附加常规分数排序作为二阶条件
我不确定此解决方案的性能如何扩展,但对于需要进行此排序的数千个文档,我没有注意到任何与不排序相关的延迟。看起来您正在尝试在sql中创建类似Group BY的内容,它在弹性搜索中同样具有聚合性。检查一下这个怎么样?但是聚合不支持分页,因为性能原因()。这确实是一个解决方法,通过排序可能有更好的解决方案,但是如果它吸引了您,只需检查注释是否看起来很好我的案例是否可以通过脚本实现?我从未使用过脚本,所以我不知道这是否可行,也不知道整个脚本功能提供了多少功能。我记得看到过这样的例子,人们根据脚本对字段进行排序,而不是直接对该字段进行排序。当然,通过编写脚本,即使有特定的细节,也可以解决问题。您还可以将日期添加为ES中的周指针。然后,您可以使用所使用的语言每周聚合数据。我认为分组是不能通过排序来实现的。因此,如果出于性能考虑,数据不太大,无法在内部循环,那么脚本就可以解决这个问题。
{
"sort": [
"_script": {
"lang": "expression",
"type": "number",
"script": "doc['myDateField'].value - doc['myDateField'].value % 604800000"
"order": "desc"
},
"_score"
]
}