elasticsearch,Sorting,elasticsearch" /> elasticsearch,Sorting,elasticsearch" />

Sorting “如何指定”;“精确性”;在Elasticsearch中按日期字段排序时?

Sorting “如何指定”;“精确性”;在Elasticsearch中按日期字段排序时?,sorting,elasticsearch,Sorting,elasticsearch,在我的Elasticsearch映射中,我有一个类型为date(输入格式epoch\u second)的字段(我使用的是ES 2.1)。我知道我可以在这个领域像 { "sort": [ { "myDateField" : { "order": "desc" } } ] } 但这种排序以秒为单位。我想按“周间隔”(从现在起按7天间隔)排序,并在同一周内再次按分数排序,如下(psedoocode): 因此,过去7天内的所有点击

在我的Elasticsearch映射中,我有一个类型为
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"
  ]
}