全部产品
开放搜索

相关性实战

更新时间:2017-06-07 13:26:11   分享:   

分词、匹配、相关性、排序表达式

针对目前若干用户遇到的搜索结果与预期不符合的问题进行统一详细说明,并以此为话题展开说明下opensearch在搜索效果方面的功能和后续一些工作方向。

首先,对于搜索来讲,最常见的有两种做法:

  1. 数据库的like查询,可以理解为简单的包含关系;
  2. 百度、google等搜索引擎,涉及到分词,将查询词根据语义切分成若干词组term(这个是搜索引擎重难点之一),通过term组合匹配给相应文档进行打分,根据分值排序,并最终返回给用户。

opensearch采用的方式与上述搜索引擎做法基本一致。那这里就有三部分内容会影响搜索效果:1,分词方式;2,匹配方式;3,相关性算分。

我们来分别说下这三部分在opensearch上的行为和表现。

接下来,我们详细说明下各个字段的展现效果及适用场景,供大家参考。

分词方式

熟悉各类分词是本篇操作的前提,请务必先查阅 字段类型及分词描述 文档,这里不在复述。

匹配方式

原理

分完词后得到若干term,如何召回文档,就涉及到匹配方式。目前opensearch内部默认支持的是AND,即一篇文档中包含全部的term才能被搜索出来。当然这是对同一关键词而言的,除此之外系统还支持多种匹配方式,如AND、OR、RANK、NOTAND以及(),优先级从高到低为(),ANDNOT,AND,OR,RANK。

举例

关系 用法 含义
query=title:”苹果 手机” 查询title中包含苹果和手机的文档
AND query=title:’苹果’ AND cate:’手机’ 交集。查询title中包含苹果,且cate包含手机的文档
OR query=title:’苹果’ OR cate:’手机’ 并集。查询title中包含苹果,或cate包含手机的文档
RANK query=title:’苹果’ RANK cate:’手机’ 查询title中包含苹果的文档,如果cate包含手机则可以加分
ANDNOT query=title:’苹果’ ANDNOT cate:’手机’ 查询title中包含苹果,但cate不包含手机的文档

案例

  1. 问:我文档中包含“吃饭了”,我搜索“吃饭”、“吃饭了”都能召回,搜索“吃饭了吗”没结果?

    答:因为目前opensearch是要求全部的分词结果都匹配才能召回文档,上面的“吗”在文档中没有出现,所以无法召回。

  2. 问:我只想查找某些词排在最前面的文档,比如以“肯德基”开头的文档;答:目前不支持位置相关召回。

后续工作

  1. 支持用户词典,比如纠错、同义词等,可以根据自己的实际场景挖掘出属于自己的专属词典。
  2. O2O实体词识别,如query=title:’杭州市文一西路’改写为query=title:’杭州市文一西路’ OR (city:’310010’AND district:’0012’ AND title:’文一西路’)。

  3. 相关搜索功能。

  4. 热词统计、点击反馈等。

使用技巧

  1. 可以通过AND,OR等实现强大的搜索功能。
  2. 对于一些filter中的过滤字段,如= 、!=的需求,可以尽量使用索引字段来做,可以提高查询性能。点击获取更多优化小技巧

相关性算分

上面提到的都是跟召回相关的技术,召回文档之后,究竟文档如何排序就涉及到相关性。目前opensearch有sort子句来支持用户自定义排序。如果不设置sort,则默认为sort=-RANK;sort本身支持多维排序,以及升降序的支持。比如sort=-RANK;+bonus,意思为第一位按照相关性降序排序,相关性分值一样的文档再按照bonus升序排列。这里我们重点描述下RANK的用法,RANK即为opensearch中的相关性设置,主要分为两部分:粗排和精排,分别有对应的控制台中的粗精排表达式配置

原理

Opensearch相关性算分策略为,取召回的rank_size(目前是100万)个文档按照粗排表达式的定义进行算分;取粗排分最高的N个结果(百级别)按照精排表达式进行算分,并排序;然后根据start与hit的设置取相应结果返回给用户。如果用户获取的结果超过了精排结果数N,则后续按照粗排分数排序结果继续展现。

  1. 粗排表达式:从上面原理介绍中可以看出粗排对性能(latency)的影响非常大,但同时粗排又非常的重要,否则会出现好的文档无法进入精排而导致文档不能被最终展现。所以粗排要尽量的简单有效,目前opensearch的粗排只支持几个简单的正排字段、静态bm25、时效分等因素。

  2. 精排表达式:通过粗排表达式筛选出较优质的N个文档进行详细排序,精排表达式中支持复杂的数学计算、逻辑等,并且opensearch提供了丰富的典型场景(如O2O类)的function和feature来满足日常的相关性需求。

同时,系统以内置了多个场景的应用结构和排序表达式,可以供大家参考和使用。

举例

场景 表达式 含义
论坛-粗排 static_bm25() 简略文本分
论坛-精排 text_relevance(title)*3+text_relevance(body)
+if(text_relevance(title)>0.07,timeliness(create_timestamp),timeliness(create_timestamp)*0.5)
+(topped+special+atan(hits)*0.5+atan(replies))*0.1
文本分
时效分
其他属性分
O2O-粗排 sold_score+general_score*2 销量、门店综合分值(离线算好)
O2O-精排 2*sold_score+0.5*reward
- 10*distance(lon,lat,u_posx,u_posy)
+ if ((flags&2) \=\=2, 2, 0)+if(is_open\=\=5,10,0)
+ special_score
销量、配送速度及准点率
距离
是否繁忙、是否在营业时间
人工干预
小说-粗排 static_bm25()*0.7+hh_hot*0.00003 文本分、热度
小说-精排 pow(min(0.5,max(text_relevance(category),max(text_relevance(title), text_relevance(author)))),2)
+ general_score*2
+ 1.5*(1/(1+pow(2.718281,-((log10(hh_hot)-2)*2-5)))))
分类相关性、标题相关性、作者相关性
小说质量
小说热度
电商-粗排 static_bm25()+general_score*2+timeliness(end_time) 文本分、宝贝综合分值、过期时间
电商-精排 text_relevance(title)*3+text_relevance(category)
+ general_score*2+boughtScore*2
+ tag_match(ctr_query_value,doc_value,mul,sum,false,true)+..
文本相关性、类目相关性
宝贝人气、卖家分
ctr预估、特征规则分等

案例

  1. 问:精排表达式text_relevance(seller_id)报找不到字段答:text_relevance()只支持TEXT及SWS_TEXT类型,其他不可以。

  2. 问:查询报2112错误,是什么问题?答:查询语句(query子句)必须与formula相配合,比如query=default:’keyword’,default中包含title和body字段,而formula指定text_relevance(title)+text_relevance(author)则会报错,因为author在default中不存在。

后续工作

  1. 优化错误码,目前很多查询错误都会报1000错误,不利于用户定位问题,且容易造成系统有问题的误导,后续会统一进行梳理。
  2. 后续会对电商类场景提供更多样的feature来支持,如有类似的需要请联系我们。
  3. 发布截断功能,允许用户指定重要字段,构建索引时考虑该字段的值,降低参与粗排文档数、提高参与精排文档数,即降低查询开销又提高搜索质量,让更多好的文档能够排上来。
  4. 相关性ABTest调试界面,会在搜索测试页面增加多个排序表达式的对比界面,将每项表达式的值列出来,方便用户进行排序表达式的调整。

使用技巧

  1. 排序表达式的算分是在查询结算对每个文档进行计算的,所以如果跟查询无关的部分的计算可以预先离线计算好,新增一个general_score字段来存放,排序的时候只要使用general_score字段即可,避免大量计算过程,提高查询性能。
  2. tag_match的feature允许用户将query中的特征与doc中特征做多维运算,在电商场景下有着非常广泛的用途,有类似的需求的用户可以研究下。
  3. opensearch提供了丰富的function和feature,使用得当可以获得非常强大的功能。
  4. 相关性有很多部分共同组成,各项之间的权重需要根据搜索排序效果不断进行调整以达到一个用户满意的搜索效果。
本文导读目录
本文导读目录
以上内容是否对您有帮助?