elasticsearch 搜索(三):权重、随机评分、衰减函数、

一 过滤集提升权重
找一个在巴塞罗那的度假屋,希望根据每个度假屋的特性数量来评分,当时我们希望能用缓存的过滤器来影响评分,现在 function_score 查询正好可以完成这件事情
demo code:
GET /_search
{
"query": {
"function_score": {
"filter": {
"term": { "city": "Barcelona" }
},
"functions": [
{
"filter": { "term": { "features": "wifi" }},
"weight": 1
},
{
"filter": { "term": { "features": "garden" }},
"weight": 1
},
{
"filter": { "term": { "features": "pool" }},
"weight": 2
}
],
"score_mode": "sum"//评分模式 有multiply,sum、avg、max、min、first
}
}

function_score 查询有个 filter 过滤器而不是 query 查询。
functions 关键字存储着一个将被应用的函数列表。
函数会被应用于和 filter 过滤器(可选的)匹配的文档。
pool 比其他特性更重要,所以它有更高 weight 。
score_mode 指定各个函数的值进行组合运算的方式。

二 随机评分

一致随机(consistently random): 有相同评分的_score 文档 会每次都以相同的次序出现,当你希望你网站的广告有更高的展现率,引入一些随机性能保证有相同评分的文档都能有均等相似的展现机率。我们想让每个用户看到不同的随机次序,但也同时希望如果是同一用户翻页浏览时,结果的相对次序能始终保持一致,这种行为被称为 一致随机(consistently random)
引入一个新参数
random_score 函数会输出一个 0 到 1 之间的数,当种子 seed 值相同时,生成的随机结果是一致的,例如,将用户的会话 ID 作为 seed
{
"random_score": {
"seed": "the users session id" //会话ID
}
} #位置在上述的functions里面

random_score 语句没有任何过滤器 filter ,所以会被应用到所有文档
将用户的会话 ID 作为种子 seed ,让该用户的随机始终保持一致,相同的种子 seed 会产生相同的随机结果

三 越细越好
有些人在寻找度假屋的时候,也许用户希望离市中心近点,也有因为经济因素要选一个更远的住处,也有富二代,愿意为最好的位置付更多的钱。如何满足多元化的需求?
这里需要一组 衰减函数(decay functions),让我们有能力在两个滑动标准,如地点和价格,之间权衡。
有三种衰减函数—— linear 、 exp 和 gauss (线性、指数和高斯函数),它们可以操作数值、时间以及经纬度地理坐标点这样的字段

origin
中心点 或字段可能的最佳值,落在原点 origin 上的文档评分 _score 为满分 1.0 。
scale
衰减率,即一个文档从原点 origin 下落时,评分 _score 改变的速度。(例如,每 £10 欧元或每 100 米)。
decay
从原点 origin 衰减到 scale 所得的评分 _score ,默认值为 0.5 。
offset
以原点 origin 为中心点,为其设置一个非零的偏移量 offset 覆盖一个范围,而不只是单个原点。在范围 -offset <= origin <= +offset 内的所有评分 _score 都是 1.0 。
这三个函数的唯一区别就是它们衰减曲线的形状
linear 线性函数是条直线,一旦直线与横轴 0 相交,所有其他值的评分都是 0.0 。
exp 指数函数是先剧烈衰减然后变缓。
gauss 高斯函数是钟形的——它的衰减速率是先缓慢,然后变快,最后又放缓。

GET /_search
{
"query": {
"function_score": {
"functions": [
{
"gauss": {
"location": {
"origin": { "lat": 51.5, "lon": 0.12 },
"offset": "2km",
"scale": "3km"
}
}
},
{
"gauss": {
"price": {
"origin": "50",
"offset": "50",
"scale": "20"
}
},
"weight": 2
}
]
}
}
}

location 字段以地理坐标点 geo_point 映射。
price 字段是数值。
参见 理解价格语句 ,理解 origin 为什么是 50 而不是 100 。
price 语句是 location 语句权重的两倍

location 语句可以简单理解为:
以伦敦市中作为原点 origin 。
所有距原点 origin 2km 范围内的位置的评分是 1.0 。
距中心 5km ( offset + scale )的位置的评分是 0.5 。

price 语句使用了一个小技巧:用户希望选择 £100 英镑以下的度假屋,但是例子中的原点被设置成 £50 英镑,价格不能为负,但肯定是越低越好,所以 £0 到 £100 英镑内的所有价格都认为是比较好的。
如果我们将原点 origin 被设置成 £100 英镑,那么低于 £100 英镑的度假屋的评分会变低,与其这样不如将原点 origin 和偏移量 offset 同时设置成 £50 英镑,这样就能使只有在价格高于 £100 英镑( origin + offset )时评分才会变低

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注