原文链接:http://blog.csdn.net/dm_vincent/article/details/42113401
本章翻译自Elasticsearch官方指南的Controlling Relevance一章。
Lucene中的Practical Scoring Function
对于多词条查询(Multiterm Queries),Lucene使用的是布尔模型(Boolean Model),TF/IDF以及向量空间模型(Vector Space Model)来将它们结合在一起,用来收集匹配的文档和对它们进行分值计算。
像下面这样的多词条查询:
GET /my_index/doc/_search
{
"query": {
"match": {
"text": "quick fox"
}
}
}
在内部被重写成下面这样:
GET /my_index/doc/_search
{
"query": {
"bool": {
"should": [
{"term": { "text": "quick" }},
{"term": { "text": "fox" }}
]
}
}
}
bool查询实现了布尔模型,在这个例子中,只有包含了词条quick,词条fox或者两者都包含的文档才会被返回。
一旦一份文档匹配了一个查询,Lucene就会为该查询计算它的分值,然后将每个匹配词条的分值结合起来。用来计算分值的公式叫做Practical Scoring Function。它看起来有点吓人,但是不要退却 - 公式中的绝大多数部分你已经知道了。下面我们会介绍它引入的一些新元素。
1 score(q,d) =
2 queryNorm(q)
3 · coord(q,d)
4 · ∑ (
5 tf(t in d)
6 · idf(t)²
7 · t.getBoost()
8 · norm(t,d)
9 ) (t in q)
每行的意义如下:
- score(q,d)是文档d对于查询q的相关度分值。
- queryNorm(q)是查询归约因子(Query Normalization Factor),是新添加的部分。
- coord(q,d)是Coordination Factor,是新添加的部分。
- 文档d中每个词条t对于查询q的权重之和。
- tf(t in d)是文档d中的词条t的词条频度(Term Frequency)。
- idf(t)是词条t的倒排索引频度(Inverse Document Frequency)
- t.getBoost()是适用于查询的提升(Boost),是新添加的部分。
- norm(t,d)是字段长度归约(Field-length Norm),可能结合了索引期间字段提升(Index-time Field-level Boost),是新添加的部分。
你应该知道score,tf以及idf的意思。queryNorm,coord,t.getBoost以及norm是新添加的。
在本章的稍后我们会讨论查询期间提升(Query-time Boosting),首先对查询归约,Coordination以及索引期间字段级别提升进行解释。
查询归约因子(Query Normalization Factor)
查询归约因子(queryNorm)会试图去对一个查询进行归约,从而让多个查询的结果能够进行比较。
TIP
虽然查询归约的目的是让不同查询的结果能够比较,但是它的效果不怎么好。相关度_score的唯一目的是将当前查询的结果以正确的顺序被排序。你不应该尝试去比较不同查询得到的相关度分值。
该因子会在查询开始阶段就被计算。实际的计算取决于查询本身,但是一个典型的实现如下所示:
queryNorm = 1 / √sumOfSquaredWeights
sumOfSquaredWeights通过对查询中每个词条的IDF进行累加,然后取其平方根得到的。
TIP
相同的查询归约因子会被适用在每份文档上,你也没有办法改变它。总而言之,它是可以被忽略的。
Query Coordination
Coordination因子(coord)被用来奖励那些包含了更多查询词条的文档。文档中出现了越多的查询词条,那么该文档就越可能是该查询的一个高质量匹配。
加入我们查询了quick brown fox,每个词条的权重都是1.5。没有Coordination因子时,分值可能会是文档中每个词条的权重之和。比如:
- 含有fox的文档 -> 分值:1.5
- 含有quick fox的文档 -> 分值:3.0
- 含有quick brown fox的文档 -> 分值:4.5
而Coordination因子会将分值乘以文档中匹配了的词条的数量,然后除以查询中的总词条数。使用了Coordination因子后,分值是这样的:
- 含有fox的文档 -> 分值:1.5 * 1 / 3 = 0.5
- 含有quick fox的文档 -> 分值:3.0 * 2 / 3 = 2.0
- 含有quick brown fox的文档 -> 分值:4.5 * 3 / 3 = 4.5
以上的结果中,含有所有三个词条的文档的分值会比仅含有两个词条的文档高出许多。
需要记住对于quick brown fox的查询会被bool查询重写如下:
GET /_search
{
"query": {
"bool": {
"should": [
{ "term": { "text": "quick" }},
{ "term": { "text": "brown" }},
{ "term": { "text": "fox" }}
]
}
}
}
bool查询会对所有should查询子句默认启用查询Coordination,但是你可以禁用它。为什么你需要禁用它呢?好吧,通常的答案是,并不需要。查询Coordination通常都起了正面作用。当你使用bool查询来将多个像match这样的高级查询(High-level Query)包装在一起时,启用Coordination也是有意义的。匹配的查询子句越多,你的搜索陈请求和返回的文档之间的匹配程度就越高。
但是,在某些高级用例中,禁用Coordination也是有其意义的。比如你正在查询同义词jump,leap和hop。你不需要在意这些同义词出现了多少次,因为它们表达了相同的概念。实际上,只有其中的一个可能会出现。此时,禁用Coordination因子就是一个不错的选择:
GET /_search
{
"query": {
"bool": {
"disable_coord": true,
"should": [
{ "term": { "text": "jump" }},
{ "term": { "text": "hop" }},
{ "term": { "text": "leap" }}
]
}
}
}
当你使用了同义词(参考同义词(Synonyms)),这正是在内部发生的:重写的查询会为同义词禁用Coordination。多数禁用Coordination的用例都会被自动地处理;你根本无需担心它。
索引期间字段级别提升(Index-time Field-level Boosting)
现在来讨论一下字段提升 - 让该字段比其它字段更重要一些 - 通过在查询期间使用查询期间提升(Query-time Boosting)。在索引期间对某个字段进行提升也是可能的。实际上,该提升会适用于字段的每个词条上,而不是在字段本身。
为了在尽可能少占用空间的前提下,将提升值存储到索引中,索引期间字段级别提升会和字段长度归约一起以一个字节被保存在索引中。它是之前公式中norm(t,d)返回的值。
警告
我们强烈建议不要使用字段级别索引期间提升的原因如下:
- 将此提升和字段长度归约存储在一个字节中意味着字段长度归约会损失精度。结果是ES不能区分一个含有三个单词的字段和一个含有五个单词的字段。
- 为了修改索引期间提升,你不得不对所有文档重索引。而查询期间的提升则可以因查询而异。
- 如果一个使用了索引期间提升的字段是多值字段(Multivalue Field),那么提升值会为每一个值进行乘法操作,导致该字段的权重飙升。
查询期间提升(Query-time Boosting)更简单,简洁和灵活。
解释完了查询归约,Coordination以及索引期间提升,现在可以开始讨论对影响相关度计算最有用的工具:查询期间提升。
查询期间提升(Query-time Boosting)
在调整查询子句优先级(Prioritizing Clauses)一节中,我们已经介绍过如何在搜索期间使用boost参数为一个查询子句增加权重。比如:
GET /_search
{
"query": {
"bool": {
"should": [
{
"match": {
"title": {
"query": "quick brown fox",
"boost": 2
}
}
},
{
"match": {
"content": "quick brown fox"
}
}
]
}
}
}
查询期间提升是用来调优相关度的主要工具。任何类型的查询都接受boost参数。将boost设为2并不是简单地将最终的_score加倍;确切的提升值会经过规范化以及一些内部优化得到。但是,它也意味着一个提升值为2的子句比一个提升值为1的子句要重要两倍。
实际上,没有任何公式能够决定对某个特定的查询子句,"正确的"提升值应该是多少。它是通过尝试来得到的。记住boost仅仅是相关度分值中的一个因素;它需要和其它因素竞争。比如在上面的例子中,title字段相对于content字段,大概已经有一个"自然的"提升了,该提升来自字段长度归约(Field-length Norm)(因为标题通常会比相关内容要短一些),因此不要因为你认为某个字段应该被提升而盲目地对它进行提升。适用一个提升值然后检查得到的结果,再进行修正。
提升索引(Boosting an Index)
当在多个索引中搜索时,你可以通过indices_boost参数对整个索引进行提升。在下面的例子中,会给予最近索引中的文档更多的权重:
GET /docs_2014_*/_search
{
"indices_boost": {
"docs_2014_10": 3,
"docs_2014_09": 2
},
"query": {
"match": {
"text": "quick brown fox"
}
}
}
该多索引搜索(Multi-index Search)会查询所有以docs_2014_开头的索引。 索引docs_2014_10中的文档的提升值为3,索引docs_2014_09中的文档的提升值为2,其它索引中的文档的提升值为默认值1。
t.getBoost()
这些提升值在Lucene的Practical Scoring Function中通过t.getBoost()元素表达。提升并不是其在查询DSL出现的地方被适用的。相反,任何的提升值都会被合并然后传递到每个词条上。t.getBoost()方法返回的是适用于词条本身上的提升值,或者是适用于上层查询的提升值。
TIP
实际上,阅读解释API的输出本身比上述的说明更复杂。你在解释中根本看不到boost值或者t.getBoost()。提升被融合到了适用于特定词条上的queryNorm中。尽管我们说过queryNorm对任何词条都是相同的,但是对于提升过的词条而言,queryNorm会更高一些。
相关推荐
总的来说,`elasticsearch-analysis-dynamic-synonym-7.6.2`插件是ES7.6.2版本中实现动态同义词功能的重要工具,它通过高效的数据处理和灵活的API,让同义词管理变得更加便捷,极大地提升了ES在实际业务中的应用效果...
在IT领域,尤其是在搜索引擎优化和大数据分析中,Elasticsearch(ES)是一个广泛使用的开源全文检索引擎。它基于Lucene库,提供了分布式、实时、高可用性以及容错能力的数据存储和搜索解决方案。本篇文章将重点讲解...
《Elasticsearch中文分词器:elasticsearch-analysis-ik-7.10.2》 在信息技术领域,数据处理和搜索效能是至关重要的。Elasticsearch(ES)作为一个开源的全文搜索引擎,因其强大的搜索功能和分布式特性而备受青睐。...
在现代大数据分析和搜索引擎领域,Elasticsearch(ES)因其高效、灵活的全文检索能力而备受青睐。然而,对于中文这样的多字节语言,如何准确地进行分词是关键。这时,我们就需要引入专门的中文分词器。本文将详细...
《Elasticsearch拼音分词器7.4.0在大数据全文检索中的应用》 Elasticsearch(简称ES)是一款强大的开源搜索引擎,广泛应用于大数据领域的全文检索。它以其高可扩展性、实时性能以及丰富的分析能力著称。在中文环境...
"elasticsearch-analysis-dynamic-synonym-7.0.0.zip"是一个专为Elasticsearch设计的同义词插件,它的主要目的是在搜索过程中实现同义词的智能匹配,提高搜索的准确性和用户体验。 这个插件的独特之处在于它支持...
用户在下载并解压此文件后,可以将其安装到Elasticsearch环境中,以增强对中文文档的索引和查询性能。 压缩包中的各个文件如下: 1. httpclient-4.5.2.jar:这是Apache HttpClient库的一个版本,用于实现HTTP协议...
最新版 elasticsearch-analysis-ik-8.7.0.zip最新版 elasticsearch-analysis-ik-8.7.0.zip最新版 elasticsearch-analysis-ik-8.7.0.zip最新版 elasticsearch-analysis-ik-8.7.0.zip
《Elasticsearch分词器:elasticsearch-analysis-ik-7.16.2深度解析》 在信息爆炸的时代,搜索引擎的效能成为了数据检索的关键。Elasticsearch作为一款强大的开源搜索引擎,其灵活性和可扩展性备受青睐。而在中文...
Elasticsearch(ES)是一种流行的开源全文搜索引擎,它基于Lucene构建,提供了分布式、RESTful风格的搜索和分析引擎服务。在中文环境下,为了实现精确的分词和搜索,我们需要安装适合版本的分词插件,如“elastic...
在标题中提到的"elasticsearch-bulk-insert-plugin-8.2.0.0-342.zip"是一个针对Kettle(也称为Pentaho Data Integration)的插件,它允许用户通过Kettle与Elasticsearch进行批量数据插入。Kettle是一款开源的数据...
"elasticsearch-analysis-ik"是ES中最受欢迎的中文分词器之一,专为提升中文文本分析性能而设计。本文将深入探讨"elasticsearch-analysis-ik-7.3.2"这个版本,以及与其相关的技术细节。 首先,"elasticsearch-...
标签 "elasticsearch elasticsearch" 强调了这个资源与Elasticsearch紧密相关,涵盖了Elasticsearch的核心技术和应用。 从压缩包内的文件名称列表来看,我们可以推断出以下几个关键知识点: 1. **mysql-connector-...
**Elasticsearch Head 插件详解** Elasticsearch Head 是一个非常实用的开源工具,用于可视化管理和监控 Elasticsearch 集群。...只需简单的安装步骤,即可在浏览器中享受丰富的功能,提升 Elasticsearch 管理效率。
本文将深入探讨这个分词器的特性和使用方法,并结合相关标签,如“elasticsearch”、“综合资源”、“大数据”、“big data”以及“搜索引擎”,解析其在大数据环境中的重要角色。 一、elasticsearch-analysis-ik ...
Elasticsearch(ES)是一个基于Lucene的分布式、RESTful搜索引擎,广泛应用于大数据分析、日志收集和全文检索等领域。它的核心功能包括索引、搜索、分析和聚合,但默认情况下对中文的支持并不完善,因此需要借助像IK...
在本例中,我们关注的是 Elasticsearch 的特定版本——7.4.2,针对 Linux x86_64 架构的压缩包“elasticsearch-7.4.2-linux-x86_64.tar.gz”。 首先,让我们深入了解 Elasticsearch 的核心概念和功能: 1. 分布式...
在6.8.0版本中,Elasticsearch 提供了强大的索引管理和查询功能,支持多种数据类型,如文本、数值、日期等。此版本对性能进行了优化,增强了稳定性,并修复了一些已知问题。它还支持多租户,允许在一个集群中管理多...
Elasticsearch-Bulk-Insert-Plugin 是一个专为Kettle设计的插件,主要用于高效地将大量数据批量插入到Elasticsearch(ES)集群中。Elasticsearch是一种流行且功能强大的分布式搜索引擎,常用于大数据分析、日志分析...
在 Elasticsearch 中安装 IK 分词器,需要将 elasticsearch-analysis-ik-7.12.1.jar 文件拷贝到 Elasticsearch 的 plugins 目录下,并重启服务。然后,可以通过编辑索引模板或在创建索引时指定分词器来使用 IK 分词...