1 ApachLucene评分
文档匹配计算文档评分
计算文档评分属性,关注因素
文档加权:对文档建立索引时对文档的加权值
字段加权:查询和索引时对字段的加权值
协调因子:基于文档词条数的协调因子(文档词条数)
逆文档率:逆文档频率越高,词条月罕见
长度规范:更短的文档更受分数青睐
词频,文档中此词条出现的次数,越高,文档得分越高
查询规范;每个查询词条比重的平方之和计算而成,不易比较
相关性的意义
在大多数情况下,我们希望得到最匹配的文档,但最相关的不一定是最匹配的。
文档除了被TF/IDF相似度模型完美匹配外,有客户付钱让他们的文档
出现在结果中更靠前的位置。基于客户计划,我们想给这样的文档更大的重要性,
把付费最高的用户的文档放到搜索结果的最顶部。当然,这就不属于TF/IDF相关性了。
在大多数情况下,优化查询相关性是持续性的工作,要根据业务规则、需求以及用户行为方式等调整。
有一点非常重要:记住这不是设置之后就可以抛诸脑后的一次性过程。
2 Elasticsearch 的脚本功能(暂不care)
更新文件、过滤和搜索,在执行脚本请求的过程中熟悉几个属性;
script:此属性包含实际的脚本代码。
lang:这个属性定义了提供脚本语言信息的字段。如果省略, Elasticsearch假定为mvel。
params:此对象包含参数及其值。每个定义的参数可以通过指定参数名称在脚本中使用。
通过使用参数,我们可以编写更干净的代码。由于可以缓存,使用参数的脚本比嵌入常
数的代码执行得更快。
3 搜索不同语言的内容(暂不care)
4 使用查询加权影响得分
随着应用程序的增长,提高搜索质量的需求也进一步增大。
我们把它叫做搜索体验。我们需要知道什么对用户更重要,关注用户如
何使用搜索功能。这导致不同的结论,例如,有些文档比其他的更重要,或特定查询需强调一个
字段而弱化其他字段。这就是可以用到加权的地方。
加权是一个评分过程中额外使用的值。我们已经知道它适用于下列地方。
query:这可以通知搜索引擎,给定查询是复杂查询的一部分,而且比其他部分更重要。
field:有几个文档字段对用户非常重要。例如,以Bill搜索电子邮件,应该首先列出
那些发送自Bill的邮件,紧随其后列出主题中含有Bill的邮件,然后是内容中提到Bill
的邮件。
查询增加加权
{
"query" : {
"query_string" : {
"fields" : ["from^5", "to^10", "subject"],
"query" : "john",
"use_dis_max" : false
}
}
}
看看高亮显示的部分(^5和^10)。通过这种方式,可以告诉Elasticsearch给定字段的重要程
度。我们看最重要的字段是to,其次是from。 subject字段的boost为默认值,即1.0
修改得分
1. constant_score查询
2. 加权查询
它允许我们定义一个查询的额外部分,用于降低匹配
文档的得分。下面的例子列出所有图书,但E.M.Remarque写的书得分将低10倍
{
"query" : {
"boosting" : {
"positive" : {
"term" : {
"available" : true
}
},
"negative" : {
"match" : {
"author" : "remarque"
}
},
"negative_boost" : 0.1
}
}
}
3. function_score查询
这个查询在得分计算成本高昂时非常有用,因为它将计算
过滤后文档的得分;function_score查询背后的逻辑很简单。
首先,函数匹配文档并基于score_mode参数计算得分。
boost_mode: boost_mode参数允许定义如何将函数查询所计算分数与查询分数结合起
来。可以将它设置成下列值。
multiply:这是默认行为,查询得分将与函数计算所得分相乘。
replace:导致查询得分全部被忽略,文档得分等于函数计算所得分。
sum:文档得分等于查询得分和函数得分的总和。
avg:文档得分等于查询得分和函数得分的平均值。
max:文档得分等于查询得分和函数得分的最大值。
min:文档得分等于查询得分和函数得分的最小值。
score_mode:该参数定义了函数计算所得分是如何结合在一起的。以下是该参数可以设
置的值。
multiply:这是默认行为,结果是查询得分乘以函数的得分。
sum:把所定义的函数的得分相加。
avg:函数得分等于所有匹配函数得分的平均值。
first:把第一个拥有匹配文档过滤器的函数的得分返回。
max:返回所有函数得分的最大值。
min:返回所有函数得分的最小值。
然后,文档的查询得分由函数计算所得分数结合而成,结合时基于boost_mode参数。
boost参数允许我们为文档设置一个查询范围的加权值。我们还没谈到
可以包含到查询的functions节点中的函数,下面是目前可用的函数。
boost_factor参数的值不会被范式化,而是原原本本的值。
script_score函数这个函数允许我们使用一个脚本来计算得分,用于函数返回的得分
random_score函数:使用这个函数,可以通过指定seed值来生成一个伪随机分数
5 索引时加权何时有意义
我们获得独立于查询的一个加权,成本是重建索引(在加权值变化时,我们需要重建索引)。
此外,由于加权过程中已经在索引时计算,性能会稍好一些。 Elasticsearch把加权的信息存储为
规范化信息的一部分
在输入数据中定义字段加权
{
"title": "The Complete Sherlock Holmes",
"author": {
"_value": "Arthur Conan Doyle",
"_boost": 10,
},
"year": 1936
}
就是这些。在上述文档被编制到索引后,我们会让Elasticsearch知道author字段的重要性大
于其他字段
在映射中定义加权
{
"mappings": {
"book": {
"properties": {
"title": {
"type": "string"
},
"author": {
"type": "string",
"boost": 10.0
}
}
}
}
}
6 同义词
你应该听说过同义词:有相同或相近意思的词语
同义词过滤器
为了使用同义词过滤器,我们需要定义自己的分析器,称为synonym,使用空格分词器和一
个叫synonym的过滤器。该过滤器的类型属性必须设置为synonym,它告诉Elasticsearch,该过
滤器是一个同义词过滤器。此外,我们希望忽略大小写,对大写和小写的同义词一视同仁(设置
ignore_case属性为true)。自定义一个使用同义词过滤器的分析器,需要以下映射
{
"index": {
"analysis": {
"analyzer": {
"synonym": {
"tokenizer": "whitespace",
"filter": [
"synonym"
]
}
},
"filter": {
"synonym": {
"type": "synonym",
"ignore_case": true,
"synonyms": [
"crime => criminality"
]
}
}
}
}
}
定义同义词规则
使用Apache Solr同义词
显式同义词
criminality => crime
abuse => punishment
当然,一个单词可以映射到多个单词,多个单词也能被映射到单个单词,如下所示:
star wars, wars => starwars
等效同义词
除了显式映射以外, Elasticsearch允许我们使用等效同义词。例如,下面的定义会使所有单
词可交换,你可以使用其中一个单词,来匹配包含其中一个单词的文档
star, wars, star wars, starwars
扩展同义词
使用Apache Solr格式的时候,同义词过滤器允许我们使用一个额外的expand属性。当
expand属性设置为true(默认为false)
"filter" : {
"synonym" : {
"type" : "synonym",
"expand": false,
"synonyms" : [
"one, two, three"
]
}
}
Elasticsearch将把前面的同义词定义映射如下:
one, two, thee => one
这意味着, one、 two、 three将被更改为one。如果expand属性设置为true,相同的同义
词定义将以下列方式解释:
one, two, three => one, two, three
这基本上意味着左侧的每个单词将扩展为右侧的所有单词
使用WordNet同义词
我们需要为同义词过滤器提供额外的format属性,应将其值设置为wordnet,以便
Elasticsearch理解。
7 理解解释信息
理解字段分析
Elasticsearch提供一个专门的REST API端点, _analyze
值得注意的是,有另一种分析API的可用形式:我们能够提供分词器和过滤器。要在创建目
标映射之前实验一下配置时;
解释查询
Elasticsearch让我们可以解释特定的查询和文档是如何计算得分的_explain
curl -XGET 'localhost:9200/library/book/1/_explain?pretty&q=quiet'