如何在elasticsearch中使用Query DSL查找最近/最近的数字

时间:2016-05-03 13:36:15

标签: elasticsearch

我正在寻找在elasticsearch的帮助下找到最接近的价格/数字的可能性。问题是我没有范围。 我想要实现的是结果按最近距离排序。根据示例搜索查询,我的索引包含3个文档,其中包含以下价格(数字):45,27,32

"距离"从我的搜索值29到给定的数字是 45 - 29 = 16 | 27 - 29 = -2 | 32 - 29 = 3所以我所期望的是搜索结果是由"距离"这个数字远离给定的价格。

搜索查询示例:

GET myawesomeindex/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "description": "this is the text i want to find"
          }
        },
        {
          "match": {
            "price": 29
          }
        }
      ]
    }
  }
}

我认为我的问题与这个类似的问题有关:Elasticsearch scoring based on how close a number is to a query

2 个答案:

答案 0 :(得分:4)

你去了:

  "sort": {
    "_script": {
      "type": "number",
      "script": "return doc['price'].value-distance",
      "params": {
        "distance": 29
      },
      "lang": "groovy",
      "order": "desc"
    }
  }

您需要启用dynamic scripting

你也可以这样做

  "query": {
    "function_score": {
      "query": {
        "bool": {
          "should": [
            {
              "match": {
                "description": "this is the text i want to find"
              }
            },
            {
              "match": {
                "price": 29
              }
            }
          ]
        }
      },
      "functions": [
        {
          "exp": {
            "price": {
              "origin": "29",
              "scale": "1",
              "decay": 0.999
            }
          }
        }
      ]
    }
  }

但这会改变score本身。如果你想要按距离进行纯粹的排序(没有别的),那么我相信第一个选择是最好的。

答案 1 :(得分:0)

这对我有用。在此示例中,我使用了以UTC秒为单位的时间戳。

{
    "query": {
      "function_score": {
         "functions": [
            {
               "linear": {
                   "timestamp" : {
                        "origin": 1601227629,
                        "scale": "30m"
                   }
               }
            }
         ],
         "score_mode" : "multiply",
         "boost_mode": "multiply",
         "query": {
            "match_all": {}
         }
      }
   },
    "size": 1
}