DisMax 查询解析器
DisMax 查询解析器被设计来处理简单短语和多个不同权重的字段。
通常,DisMax 查询解析器更像 google 而不是标准查询解析器。
DisMax 支持 Lucene 查询解析器语法的精简子集
好奇 DisMax 这个名字的来源?DisMax 代表 Maximum Disjunction。不论是否能记住这个名字的含义,只要记住 DisMax 是易于使用,能接受任何输入且不会出错的。
参数
参数 | 说明 |
---|---|
q | 查询的原始输入 |
q.alt | 如果 q 参数未使用,这个参数用来呼叫标准查询解析器解析输入 |
qf | query fields,指定执行查询时所需要的索引字段,如果未指定则为 df 定义的字段 |
mm | 最小匹配数,指定查询最少要匹配几个条件,如果没有指定该参数,则依赖于 q.op 参数(不论该参数是在查询条件里指定,还是在 solrconfig.xml 里指定的默认值,或 schema.xml 里通过 defaultOperator 选项指定):q.op = AND 则 mm = 100%;q.op = OR 则 mm=1。用户也可以在 solrconfig.xml 里指定 mm 的默认值。该参数还允许在表达式里混入空格,例如 " 3 < -25% 10 < -3\n", " \n-25%\n", " \n3\n " |
pf | phrase fields:增加文档的分数以防 q 参数的所有词条出现在附近 (神马意思?) |
ps | phrase slop:指定 2 个词条分开的位置数,以匹配一个特定的短语 |
qs | query phrase slop:含义同 ps,一般和 qf 参数一起使用 |
tie | Tie Breaker:一个远小于 1 的浮点值,在 DisMax 查询里作为决定性因素 (这 tmd 又是神马意思?) |
bq | boost query:指定一个因子,对于匹配时需要加强重要性的那些词条或短语 |
bf | Boost Functions:指定一个函数来加权 |
qf
字段列表,每个字段都有一个权重因子来增强或减弱该字段在查询中的重要性,示例
qf="fieldOne^2.3 fieldTwo fieldThree^0.4"
上面例子表示 fieldOne 的权重因子为2.3,fieldTwo 为默认的权重因子,fieldThree 的权重因子为0.4mm
mm
Lucene/Solr 在处理查询时,有 3 类子句:强制的,禁止的,可选的。默认情况下,q 参数里的所有词条或短语都被作为可选的,除非前面有 + 或者 -。在处理可选的子句时,mm 参数表示最少有多少可选的子句要被匹配,DisMax 查询解析器对于如何指定 mm 提供了极大的灵活性
语法 | 示例 | 说明 |
---|---|---|
正整数 | 3 | 最少有几个子句需要匹配,不论总共有多少子句 |
负整数 | -2 | 从全部子句里减去多少个子句 |
百分比 | 75% | 全部子句总数的百分比,向下取整 |
负百分比 | -25% | 全部子句里可以不用匹配的子句所占的百分比,向下取整 |
表达式:正整数后跟>或<和另一个值 | 3<90% | 如果全部子句数量等于或小于该正整数,那么就都是强制的;但是如果是大于这个正整数,那么就只需要满足百分比 |
多项表达式,包含>或< | 2<-25% 9<-3 |
多个表达式,任一个要生效,必须是其数字比前一个的数字更大。左边的例子里,如果有 1~2 个子句,则都是强制的;如果有 3~9 个子句,则 -25% 是强制的;如果超过 9 个子句,则 -3 是必须的 |
默认的 mm=100%
pf
格式如同 qf,如果该字段匹配短语而非几个词条,那么会导致加权因子生效。
例如,查询 q=hello world,那么 "hello world" 显然比 "hello this is a world" 更匹配,因为其不仅匹配了 hello 和 world,还同时将输入作为单个短语进行了匹配
ps
貌似是对 pf 里的短语指定一个“间距”,如果在这个间距内也算是短语
tie
如果一个查询在多个字段都匹配,tie 可以用来决定最终的得分,最终得分的计算公式为
分数最大值 + tie * (其他分数)
示例如下
两个 field: A 和 B,query 分别在 A 和 B 中都能命中,其得分如下:
文档 | 字段A得分 | 字段B得分 | 最大得分 |
---|---|---|---|
doc1 | 0.5 | 0.8 | 0.8 |
doc2 | 0.8 | 0.1 | 0.8 |
这时候两个 doc 在不同 field 上的 max 得分相同,但是我们其实更希望 doc1 得分更高,那么 tie 就可以派上用场了
假设 tie = 0.1,则各自的最终分为
doc1 = 0.8 + 0.5 * 0.1 = 0.85
doc2 = 0.8 + 0.1 * 0.1 = 0.81
doc1 胜出
可见,若 tie = 0,则就是分数最大的字段的得分作为最终得分,若 tie = 1,则就是将所有字段得分简单相加作为最终得分;一般设定 tie = 0.1
bq
bq 参数指定了一个附加的、可选的查询子句,会附加到用户的主查询中以影响结果的分数;可以使用多个 bq 参数
bf
同 bq,不过 bf 是指定一个函数查询,且可以附带一个可选的权重因子,可以使用任何 solr 支持的函数查询,示例
recip(rord(myfield),1,2,3)^1.5
bf 的函数本质上是 bq 参数组合了 {!func} 的一个简写,例如,如果想要最近的文档排在前面,如下的查询是一样一样滴
bf=recip(rord(creationDate),1,1000,1000)
bq={!func}recip(rord(creationDate),1,1000,1000)