有一种类似度匹配需要,须要以匹配到的标签个数优先,这种状况就须要用到自定义查问语句。
先上代码,这里我用的是 PHP 的数组构造,最终提交的时候是会转成 json 格局的,暂且不表:
'query' => [
'script_score' => ["query" => [],
'script' => [
'source' => '
def matches = 0;
for (t in params.tags) {if(doc["tags"].contains(t)) {matches += 1;}
}
return _score * matches * matches;
',"params"=> ["tags" => $tags,],
]
],
]
首先最外层的数组就是咱们通常写的 query
语句,放在 body
中进行申请的,次要看 query
外面的构造,这种须要自定义脚本解决评分的,query
中只放了一个script_score
:
script_score
蕴含了两个局部,一部分是 query
,另外一部分是自定义的script
,这外面的query
,就是失常本来写在外层的query
中的查问构造,本来怎么写还是怎么写,比方这外面可能还会须要一个标签匹配的,那么持续加一个 terms
来查问。
而后来看 script
局部,这外面又分为两个货色:
- source 自定义的评分排序脚本
- params 自定义的评分脚本参数
首先看 params
,这里我传递了$tags
,这是一个标签数组,最终会在source
里进行调用,source
局部会放到 elasticsearch
中进行编译,造成相似于函数的货色,而后 params
就是一个参数,在 source
的代码中须要调用 tags
这个参数,采纳 params.tags
来进行调用。
而后再看 source
代码局部,这外面会把搜寻到的后果 doc
中的 tags
字段(这 doc 中的 tags
也是一个数组)与所冀望的 tags
进行校验比照,最初失去理论匹配的个数:matches
。
最初看 source
中的 return 局部,这里会返回评分后果,这里的 _score
是搜寻自身计算的类似度评分,而后这个中央_score * matches * matches
,这里是采纳标签个数对评分后果进行放大,标签数匹配越多,天然放大后果就越大。
举个例子:
匹配文档 | _score | 标签个数 | 后果分 | 排序地位 |
---|---|---|---|---|
文档 A | 40 | 2 | 160 | 2 |
文档 B | 30 | 3 | 270 | 1 |
可见最终受到标签影响更大,实现了标签后果数优先的排序。
当然,至于放大模式,比如说,评分一样,以标签数优先,那么不必进行 标签平方
解决,另外所冀望的放大后果依据具体情况能够自行处理。
另外,在文章开端帖上 elasticsearch
的脚本语法链接:
https://www.elastic.co/guide/…