elasticsearch 7.0 新特性之Script Score query

首先这个特性处于实验阶段,在之后发布的release版本中可能会被移除,Elastic官方会尽最大努力去修复可能出现的各种问题,因为不受GA保护,所以前期大家尽量不要在生产环境中使用

1、介绍

script_score 是 function score 2.0版本, 允许用户在检索中灵活修改文档score,来实现自己干预结果排名的目的,另外script score性能要高于function score
下面我们通过一个简单的例子来加深理解,通过script score将文档score值修改为“like”字段值的十分之一:

GET /_search
{
    "query" : {
        "script_score" : {
            "query" : {
                "match": { "message": "elasticsearch" }
            },
            "script" : {
                "source" : "doc['likes'].value / 10 "
            }
        }
     }
}

2、操作

  • 在script 中访问当前文档_score值
    用户可以在script中访问变量_score ,还是上面的例子,我们给当前score加上“like”值:
{
    "query" : {
        "script_score" : {
            "query" : {
                "match": { "message": "elasticsearch" }
            },
            "script" : {
                "source" : "doc['likes'].value + _score "
            }
        }
     }
}
  • Vector查询支持
    这类查询目前有cosineSimilarity 和 dotProduct两类函数支持,只能应用在dense_vecotor 和 sparse_vector数据类型上。
    例如,通过cosineSimilarity函数计算query文档与索引库里文档的dense_vector相似度:
{
  "query": {
    "script_score": {
      "query": {
        "match_all": {}
      },
      "script": {
        "source": "cosineSimilarity(params.queryVector, doc['my_dense_vector'])",
        "params": {
          "queryVector": [4, 3.4, -0.2]  
        }
      }
    }
  }
}

如果是计算sparse_vector field的cosine相似度:

{
  "query": {
    "script_score": {
      "query": {
        "match_all": {}
      },
      "script": {
        "source": "cosineSimilaritySparse(params.queryVector, doc['my_sparse_vector'])",
        "params": {
          "queryVector": {"2": 0.5, "10" : 111.3, "50": -1.3, "113": 14.8, "4545": 156.0}
        }
      }
    }
  }
}

再如,在dense_vector field上计算给定文档与索引库文档点积的距离时:

{
  "query": {
    "script_score": {
      "query": {
        "match_all": {}
      },
      "script": {
        "source": "dotProduct(params.queryVector, doc['my_dense_vector'])",
        "params": {
          "queryVector": [4, 3.4, -0.2]
        }
      }
    }
  }
}

同理,在sparse_vector上进行点积计算,需要使用dotProductSparse 函数:

{
  "query": {
    "script_score": {
      "query": {
        "match_all": {}
      },
      "script": {
        "source": "dotProductSparse(params.queryVector, doc['my_sparse_vector'])",
        "params": {
          "queryVector": {"2": 0.5, "10" : 111.3, "50": -1.3, "113": 14.8, "4545": 156.0}
        }
      }
    }
  }
}

上述vector查询需要注意的时,如果vector field缺失数值时,或者查询语句中vector规格与索引库字段的vector规格不一致,那么该文档的计算结果会是0

  • 调用自定义Painless script
    用户可以灵活的使用Painless语法编写自己的Function ,并在script中进行调用,另外值得注意的是,本身es提供了大量的预定义Function可供调用,这些都是经过优化的,执行效率比较高。
sigmoid(value, k, a) = value^a/ (k^a + value^a)  
"script" : {
    "source" : "sigmoid(doc['likes'].value, 2, 1)"
}
  • 对数字类型字段添加衰减函数
    常用到的衰减函数有decayNumericLinear(线性),decayNumericExp(指数),decayNumericGauss(高斯)
"script" : {
    "source" : "decayNumericLinear(params.origin, params.scale, params.offset, params.decay, doc['dval'].value)",
    "params": { 
        "origin": 20,
        "scale": 10,
        "decay" : 0.5,
        "offset" : 0
    }
}
  • 对geo类型字段添加衰减函数
    常用到的衰减函数有decayGeoLinear(线性),decayGeoExp(指数),decayGeoGauss(高斯)
"script" : {
    "source" : "decayGeoExp(params.origin, params.scale, params.offset, params.decay, doc['location'].value)",
    "params": {
        "origin": "40, -70.12",
        "scale": "200km",
        "offset": "0km",
        "decay" : 0.2
    }
}
  • 对日期类型字段添加衰减函数
    常用到的衰减函数有decayDateLinear(线性),decayDateExp(指数),decayDateGauss(高斯),不支持 mow 函数。
"script" : {
    "source" : "decayDateGauss(params.origin, params.scale, params.offset, params.decay, doc['date'].value)",
    "params": {
        "origin": "2008-01-01T01:00:00Z",
        "scale": "1h",
        "offset" : "0",
        "decay" : 0.5
    }
}

需要注意的是上述几个衰减函数中都用到了params参数,而该参数官方说明是不支持动态改变数值的,个人觉得不是很好用,后期应该还会优化

  • Function Score 转 Script Score

script_score:function score中的script_score 函数部分不需要进行修改,可以直接拷贝到script score里运行。

weight:

"script" : {
    "source" : "params.weight * _score",
    "params": {
        "weight": 2
    }
}

random_score:

"script" : {
    "source" : "randomNotReproducible()"
}

field_value_factor:


"script" : {
    "source" : "Math.log10((doc['field'].size() == 0 ? 1 : doc['field'].value()) * params.factor)",
    params" : {
        "factor" : 5
    }
}

其中 Math.log10((doc['field'].size() == 0 是为了排除因field missing引起的异常,field_value_factor 里modifier(权重调控函数)可以通过下面函数实现:

名称 实现
none -
log Math.log10(doc['f'].value)
log1p Math.log10(doc['f'].value + 1)
log2p Math.log10(doc['f'].value + 2)
ln Math.log(doc['f'].value)
ln1p Math.log(doc['f'].value + 1)
ln2p Math.log(doc['f'].value + 2)
square Math.pow(doc['f'].value, 2)
sqrt Math.sqrt(doc['f'].value)
reciprocal 1.0 / doc['f'].value

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,539评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,594评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,871评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,963评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,984评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,763评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,468评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,850评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,002评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,144评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,823评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,483评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,026评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,150评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,415评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,092评论 2 355