搜索业务中的经验总结

一些业内概念

  • ctr和cqr
    • ctr在大部分场景是点击率的意思。在搜索中也有“query和片段(doc field)的交集占片段的比例”的意思。
    • cqr是query与片段的交集占query的比例。
  • tightness的两种概念
    • query命中doc的所有term,计算前后两个term在doc中的距离,距离远,tightness越低。
    • 两个紧密度概念,一个是单个term的,一个是term之间的tightscore。如query 是下载深海大作战,经分词工具被切分成“下载 深海 大 作战”,但其实“大”和“作战”的紧密度很高,从文本相关性角度来看,召回“喵星大作战”app要一定程度比“大人物作战”会更相关。单个term的紧密度代表了这个term被认为需要跟它的前后词紧密相连。
  • omit: 省略惩罚score,如果query中的term在doc没有出现,进行算分惩罚。
  • 召回策略的思路、手段
    • ES:传统的term检索,侧重于ctr、cqr、紧密度等基础相关性,侧重于表面匹配
    • bert向量召回:语义召回,更好的对query中用户意图的理解(同义词,一词多义问题)
    • session向量召回:用户行为 or query行为召回,搜了又看 or 看了又看

一些遇到的问题

两次相同查询排序不同

  • 现象:这会导致两种badcase,1是用户搜完看到的结果顺序不同,2是用户在翻页/loadmore后看到有重复数据
  • 原因:ES多分片的查询模式导致。
  • 解决方案:考虑dfs_query_then_fetch,这个配置能让一次search请求路由到其他分片,同时获得全局的tf-idf,来避免仅在本地数据计算分数时的局限性。另外,也要考虑给ES查询时带上with-preference,但这不是一个完整的解决方案,因为会导致热点问题(可以通过preference=uid来解决)

query=文章title时 排序不佳

  • 现象:用户搜索的query与文章title完全相等,但对应的文章却没有排到第一位。
  • 原因:搜索中要对query进行切词,去除低权重分词,并检索每个分词的相关性,所以检索结果的top结果并不一定对原title全匹配。
  • 解决方案:后置强插。对每个搜索结果的title和query进行匹配,全命中时强插到第一位。

在线和离线分词是否该统一

  • 做统一有什么好处? 两侧分词统一,系统收敛,所有遇到的case都能归结为分词库的问题。
  • 不做统一有什么好处? 很多场景里,写入的时候尽可能多的分词,方便匹配,搜索的时候尽可能少的分词,减少过度匹配,这种方式最佳实践。
  • 不做统一有什么坏处? 一种是分词粒度带来的紧密度问题,分的细了导致多了很多细分词:“人民 利 利益”,导致间隔大,紧密度匹配分低。 另一种是切词不一致导致term方式匹配不到

单维度排序怎么做

经典场景是query相关性搜索后按时间最新排序。 如果按单页20个召回后排序,用户会发现第二页和第一页的排序不是时间严格的。 如果按全量500个召回后排序,用户会发现排在前面的doc相关性很差。 目前做法是增加相关性截断,比如分数必须大于0.3,然后大约有50个,再按时间严格排序,用户体验较好。唯一的缺点是同query下“默认排序”和“时间排序”的结果个数不同。

results matching ""

    No results matching ""