在elasticsearch上查询最接近日期时间的文档的最佳方法是什么?

Gon*_*ita 1 groovy datetime elasticsearch

我需要检索与请求最接近的地理位置和日期时间的文档,因此我不是在寻找日期时间的匹配项,而是在寻找最接近的日期时间项。我使用自定义脚本解决了这个问题,但是我猜测可能有更好的方法来做到这一点,类似于我根据位置和距离过滤地理位置的方式。

这是我的代码(Python):

query = {
        "query": {
            "function_score": {
                "boost_mode": "replace",
                "query": {
                    "filtered": {
                        "query" : {
                            "match_all" : {}
                        },
                        "filter" : {
                            "geo_distance" : {
                                "distance" : "10km",
                                "location" : json.loads(self.request.body)["location"]
                            }
                        }
                    }
                },
                "script_score": {
                    "lang": "groovy",
                    "script_file": "calculate-score",
                    "params": {
                        "stamp": json.loads(self.request.body)["stamp"]
                    }
                }
            }
        },
        "sort": [
                    {"_score": "asc"}
        ],
        "size": 1
    }

    response = requests.get('http://localhost:9200/meteo/meteo/_search', data=json.dumps(query))
Run Code Online (Sandbox Code Playgroud)

自定义的calculate-score.groovy脚本包含以下内容:

abs(new java.text.SimpleDateFormat("yyyy-MM-dd\'T\'HH:mm").parse(stamp).getTime() - doc["stamp"].date.getMillis()) / 60000
Run Code Online (Sandbox Code Playgroud)

该脚本将分数返回为文档日期时间与请求的日期时间之间的绝对差异(以分钟为单位)。

还有其他方法可以实现这一目标吗?

kee*_*ety 5

您应该能够使用function_score来执行此操作。您可以使用文档中提到的衰减函数为更接近原始时间戳的文档提供更大的分数。scale=28800 mins下面是ie的示例20d

例子:

put test
put test/test/_mapping
{
    "properties": {
          "stamp": {
                  "type": "date",
                  "format": "dateOptionalTime"
               }
    }
}
put test/test/1
{
    "stamp":"2015-10-15T00:00"
}

put test/test/2
{
    "stamp":"2015-10-15T12:00"
}


post test/_search
{
   "query": {
      "function_score": {
         "functions": [
            {
               "linear": {
                   "stamp" : {
                        "origin": "now",
                        "scale": "28800m"
                   }
               }
            }
         ],
         "score_mode" : "multiply",
         "boost_mode": "multiply",
         "query": {
            "match_all": {}
         }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)