乐趣区

关于elasticsearch:Elasticsearch-按照标签匹配个数优先排序查询

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

先上代码,这里我用的是 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/…

退出移动版