通过文本匹配和到点

时间:2016-06-24 14:05:31

标签: elasticsearch scoring

我有一个ElasticSearch索引,其中包含"商店"的列表。

我希望允许客户通过geo_distance搜索这些商店(因此,搜索点并在该位置附近找到商店)和文本匹配,例如商店名称/地址上的匹配。

我希望获得与这两个标准的 相匹配的结果,并且我希望这些结果的顺序是两者的组合。文本匹配越强,越接近搜索点,结果越高。 (显然,这将是一个将这两者结合起来的公式,这需要调整,而不是太担心那部分)。

我的问题/我尝试过的事情:

  • geo_distancefilter,而不是query,因此我无法在请求的query部分进行组合。

  • 可以使用匹配名称或位置的bool => should过滤器(而不是查询)。这给了我想要的结果,但没有按顺序。

  • 我也可以将_geo_distance作为sort子句的一部分,以便更接近该点的文档排名更高。

我没想到的是我将如何选择"常规" _score ElasticSearch在进行文本匹配时为文档提供,并将其与geo_distance分数相结合。

通过在过滤器中进行文本匹配,它似乎不会影响文档的分数(这是有意义的)。而且我不知道如何将query部分和geo_distance filter中的文字匹配结合起来,以便OR而不是AND

我想我最好的选择就是相当于:

{
  function_score: {
    query: {  ... },
    functions: [
      { geo_distance function },
      { multi_match_result score },
    ],
    score_mode: 'multiply'
  }
}

但我不确定你可以geo_distance作为分数函数,而且我不知道如何将multi_match_result score作为分数函数,或者如果它是&#39甚至可能。

任何指针都将非常感激。

我正在使用ElasticSearch v1.4,但我可以根据需要进行升级。

1 个答案:

答案 0 :(得分:6)

  

但我不确定你可以将geo_distance作为分数函数,而且我不知道如何将multi_match_result分数作为分数函数,或者甚至可能。或者它是否可能。

你不能按照你要求的方式做到这一点,但你可以轻松地做你想做的事。对于更简单的情况,只需使用普通查询即可获得评分。

过滤器的问题在于它们是/否是问题,因此如果您在function_score中使用它们,那么它可以提高分数,也可以不提高分数。您可能想要的是随着距离原点的距离增加而得分的降低。它是肯定/否定性质,阻止他们完全影响分数。通过匹配过滤器隐含的相关性没有任何改善 - 它只是意味着它是答案的一部分,但是说它应该更接近顶部/它没有意义结果就是这样。

这是Decay function score有帮助的地方。它适用于数字date,以及 - 最有用的 - geo_point。除了它接受的数据类型之外,它还可以使用高斯,指数或线性衰减函数进行衰减。你想要选择的那个是诚实的任意,你应该给那个选择最佳"体验"。我建议从gauss开始。

"function_score": {
  "functions": [
    "gauss": {
      "my_geo_point_field": {
        "origin": "0, 1",
        "scale": "5km",
        "offset": "500m",
        "decay": 0.5
      }
    }
  ]
}

请注意,origin采用x, y格式(由于标准GeoJSON),longitude, latitude

Decay

每个值都会影响分数如何根据图表衰减(从文档中批发)。如果您使用0的偏移量,则一旦在原点 ,分数就会开始下降。通过偏移,它允许一些缓冲区被认为是一样好。

scale是直接与decay,所述得分将由decay值砍倒关联一旦scale - 从远处的{{ 1}}(+/- origin)。在上面示例中的我的中,来自offset的任何5km都会得到origin上任意分数的一半。

再次注意,不同类型的衰变函数会改变评分的形状。

  

我希望这些结果的顺序是两者的结合。

这是origin / bool复合查询的目的。根据每场比赛,您可以获得改进得分的OR行为。将此与上述相结合,您需要以下内容:

should

注意:如果添加{ "query": { "bool": { "should": [ { "multi_match": { ... } }, { "function_score": { "functions": [ "gauss": { "my_geo_point_field": { "origin": "0, 1", "scale": "5km", "offset": "500m", "decay": 0.5 } } ] } } ] } } } ,则must行为会从字面上的OR行为(至少1必须匹配)更改为完全可选行为(none必须匹配)。

  

我正在使用ElasticSearch v1.4,但我可以根据需要进行升级。

从Elasticsearch 2.0开始,每个过滤器都是一个查询,每个查询也都是一个过滤器。唯一的区别是它使用的上下文。这里没有改变我的答案,但它可以帮助你将来除了接下来我说的是什么。

Geo-related performance increased dramatically in ES 2.2+。您应该升级(并重新创建与地理相关的索引)以利用这些更改。 ES 5.0也会有类似的好处!