有一种类似度匹配需要,须要以匹配到的标签个数优先,这种状况就须要用到自定义查问语句。
先上代码,这里我用的是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/...