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标签个数结果分排序位置
文档A4021602
文档B3032701

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

当然,至于放大形式,比如说,评分一样,以标签数优先,那么不用进行标签平方处理,另外所期望的放大结果根据具体情况可以自行处理。

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

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


Kumfo 的杂货铺
做一些经验总结和一些学习心得分享,主要围绕PHP。 现在正在学习机器学习,会增加一些机器学习的思考分享。
avatar头饰
kumfo
SegmentFault 后端工程师

程序生存法则:

6.6k 声望
4.1k 粉丝
0 条评论
推荐阅读
php实现只需要一个QQ号就可以获得用户信息
{代码...} DEMO:[链接]此处输入你的QQ号

TANKING27阅读 7.3k评论 5

花了几个月时间把 MySQL 重新巩固了一遍,梳理了一篇几万字 “超硬核” 的保姆式学习教程!(持续更新中~)
MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一。

民工哥14阅读 2k

封面图
终于卷完了!Redis 打怪升级进阶成神之路(2023 最新版)!
是一种非关系型数据库服务,它能解决常规数据库的并发能力,比如传统的数据库的IO与性能的瓶颈,同样它是关系型数据库的一个补充,有着比较好的高效率与高性能。专注于key-value查询的redis、memcached、ttserver。

民工哥11阅读 917

封面图
算法可视化:一文弄懂 10 大排序算法
在本文中,我们将通过动图可视化加文字的形式,循序渐进全面介绍不同类型的算法及其用途(包括原理、优缺点及使用场景)并提供 Python 和 JavaScript 两种语言的示例代码。除此之外,每个算法都会附有一些技术说...

破晓L7阅读 926

封面图
硬卷完了!MongoDB 打怪升级进阶成神之路( 2023 最新版 )!
前面我们学习:MySQL 打怪升级进阶成神之路、Redis 打怪升级进阶成神之路,然后我们还在继续 NoSQL 的卷王之路。从第一篇文章开始,我们逐步详细介绍了 MogoDB 基础概念、安装和最基本的CURD操作、索引和聚合、工...

民工哥6阅读 505

封面图
「刷起来」Go必看的进阶面试题详解
逃逸分析是Go语言中的一项重要优化技术,可以帮助程序减少内存分配和垃圾回收的开销,从而提高程序的性能。下面是一道涉及逃逸分析的面试题及其详解。

王中阳Go4阅读 1.9k评论 1

封面图
架构设计-高性能篇
大家好,我是易安!今天我们谈一谈架构设计中的高性能架构涉及到的底层思想。本文分为缓存架构,单服务器高性能模型,集群下的高性能模型三个部分,内容很干,希望你仔细阅读。

架构狂人4阅读 783

avatar头饰
kumfo
SegmentFault 后端工程师

程序生存法则:

6.6k 声望
4.1k 粉丝
宣传栏