Solr排序陷阱

简介: 假期梳理了之前在新浪博客的文档,将一些有用的内容搬到这里。本文是关于Solr排序陷阱。

背景

晚上,有同事咨询solr排序框架的事情。谈到混合排序的实现。依然不放过我昨天的建议:solr1.*4.*在排序框架上已经非常非常具有适应性、定制性、稳定性、先进性。没有必要整一个新的名词或者名称出来。不过,可以扩展solr的排序易用性和优化排序性能。


陷阱

讨论的对象: 因子A*文本得分 因子B*函数得分=文档得分。

目标:通过函数得分和文本得分的比例来调和最终命中的结果。solr直接提供的_val_ 是得分相加,并且没有显示“因子”的概念。


其实这里有陷阱。首先solr文本得分的归一化,和函数得分的归一化不一样,并且文本是语言方面的关联信息,而函数通常是业务方面的关联信息。实际测试发现,函数得分往往屏蔽了文本得分的影响。导致结果呈现另外一个极端,业务效果明显,而文本效果很糟糕。其实一个语言的就够复杂了,又融和一个业务的,并且要他们组合起来,把两种不同业务的东西通过单纯的数字组合起来。这不是拍脑袋的事情了。

其次,函数得分计算过程,往往与命中的文档的域值相关,这就涉及IO了。从而增加了排序阶段的IOCPU开销,当然cache能缓解部分压力,但是,依然存在cache击穿的风险。也就意味着,很容易在命中大的结果集时候,注定要发生超时。超时的排序,等于失败的排序,这样的排序没法上线。

第三,得分计算算法复杂度是线性的,但是,实际中,时间开销与命中文档规模、函数涉及的域多少是紧密相关的。假如命中10w,那么就多出了10w的函数得分计算开销。这就极大的影响了查询性能。并且,可能拖垮整个系统,导致整体响应时间变慢。进一步深入细说下,lucene索引结构和文本得分。

lucene搜索里面,文档得分是一档一分,也就是 document just。而不是全局得分corpus just。也就是说知道了doc 就知道了得分,而无需在命中结果集之后,再根据结果集的信息来计算得分。这样就可以做到得分计算,基于当前文档的“自封闭性”。而lucene索引结构,针对文本得分做了优化处理,tf itf 值在获取doc id的时候就已经知晓,无需额外的IO。这就是为何doc freq 联合编码的原因所在,获取了docid 同时获取了freq。而docfreq 通过term直接获取了的。


解法

那么这个文本与函数的融合,该如何处理?

回到问题的上一层,文本和函数的融合是出于什么,或者说需求是什么。

实践业务沟通中,原来需求是这样的:在文本搜索的时候,发现类似的文本太多了,我希望业务价值好的文档在文本得分接近的时候,尽可能的靠前点。这样既保持了文本的良好视觉、语义效果,又把业务期望凸显的文档展现了。两种方法可以解决:

方法1offline计算好得分,这样online开销降低,排序的时候sortby(score,desc,func desc);

方法2:两阶段排序 在文本相关性收集结果后,对topN执行函数排序。这样,可以实现文本相关度的筛选后,比较好的文档进一步参入函数排序。确保了结果近似最优,同时降低了函数排序部分IO开销,使得需求和实现的性能得到平衡。

目录
相关文章
|
5月前
|
算法 索引
一篇文章讲明白Lucene学习总结之九:Lucene的查询对象(2)
一篇文章讲明白Lucene学习总结之九:Lucene的查询对象(2)
21 0
|
6月前
|
存储 算法 关系型数据库
MySQL怎样处理排序⭐️如何优化需要排序的查询?
MySQL怎样处理排序⭐️如何优化需要排序的查询?
|
存储 数据采集 自然语言处理
lucene 索引流程详细分析|学习笔记
快速学习 lucene 索引流程详细分析
153 0
lucene 索引流程详细分析|学习笔记
|
存储 搜索推荐 Java
搜索引擎solr中string类型字段排序混乱问题
elasticsearch与solr作为目前市面上主流的搜索引擎可以满足绝大多数搜索场景,伴随着搜索而来的就是排序。下面记录一次solr中string类型字段排序混乱问题。
526 0
搜索引擎solr中string类型字段排序混乱问题
|
关系型数据库 MySQL Java
【BUG日记】【MySQL】多个排序字段,是有优先级的,先来先优先。
【BUG日记】【MySQL】多个排序字段,是有优先级的,先来先优先。
242 0
【BUG日记】【MySQL】多个排序字段,是有优先级的,先来先优先。
ORDER BY排序太简单?那是因为你还没用过这四大排序函数!
我们在写SQL代码时,只要有排序,首先想到的肯定是ORDER BY,以至于好多小伙伴觉得排序多简单啊。 今天就给大家介绍四个你不怎么常用排序函数,他们就是SQL Server排序中经常用到的ROW_NUMBER(),RANK(),DENSE_RANK(),NTILE()这四个好兄弟。
ORDER BY排序太简单?那是因为你还没用过这四大排序函数!
|
存储 自然语言处理 关系型数据库
Lucene的查询过程
Lucene的查询过程
193 0
|
存储 自然语言处理 分布式计算
看Lucene源码必须知道的基本规则和算法
 下面介绍一些Lucene使用基本规则和算法。这些规则和算法的选择,都和Lucene和支持TB级的倒排索引有关。
|
存储 自然语言处理 数据库
Lucene 查询原理
# 前言 Lucene 是一个基于 Java 的全文信息检索工具包,目前主流的搜索系统Elasticsearch和solr都是基于lucene的索引和搜索能力进行。想要理解搜索系统的实现原理,就需要深入lucene这一层,看看lucene是如何存储需要检索的数据,以及如何完成高效的数据检索。
8641 1