有一种类似度匹配需要,须要以匹配到的标签个数优先,这种状况就须要用到自定义查问语句。

先上代码,这里我用的是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标签个数后果分排序地位
文档A4021602
文档B3032701

可见最终受到标签影响更大,实现了标签后果数优先的排序。

当然,至于放大模式,比如说,评分一样,以标签数优先,那么不必进行标签平方解决,另外所冀望的放大后果依据具体情况能够自行处理。

另外,在文章开端帖上elasticsearch的脚本语法链接:

https://www.elastic.co/guide/...