elasticsearch权威指南 学习25

这一篇有很多翻译的问题。先放在这,以后重构。

elasticsearch权威指南-- getting start 第八章 Sorting and Relevance(3)

https://www.elastic.co/guide/en/elasticsearch/guide/current/relevance-intro.html

What Is Relevance?

正如我们前文所提到的,默认情况下结果会根据相关性进行降序排序。但是到底什么是相关性?它是怎么计算的呢?

所有document的相关性都由一个浮点型的字段:_score来表示,_score越高,document的相关性越大。

一个query查询都会为document生成一个_score字段,这个_score字段的计算取决于query的内容。不同query语句用于不同的场景:一个fuzzy查询可能决定通过计算最原始的term的拼写的相似度得出的_score。

我们通常说的相关性实际上就是我们用作查询的query string和document中的全文字段的相关性。

在Elasticsearch中标准的相似度算法是:term frequency/inverse document frequency(term 频频/倒排document的频频) 。或者叫做TF/IDF。它主要关注以下几个点:

Term frequency

在字段中一个term在field出现的频率,出现的越多,相关性越高,一个term在field中出现5次,那么它的相关性就会比出现1次的高。

Inverse document frequency

每一个term在index中出现的次数,次数越多,相关性越低,Terms在很多的document中都出现过,那么它的权重就会比出现一个特殊的字段要低。

Field-length norm

field的长度,field越长,那么一个单词在其中相关性就会越低,一个在简短的title中的term要比一个在长的title中term要有更多的权重。

单独的查询可能将TF/IDF的分数与其他的内容结合,比如这个term的与查询语句的接近程度,或者模糊匹配到一个term,这样也会影响_score大小。

同样的相关性不仅仅与全文(full-text)检索有关,同样的应用于yes/no的语句,当更多的语句匹配时,那么_score越高。

当使用符合条件查询的时候,比如bool查询,那么它会把每一个子查询的分数总计到一起,得出一个document的_score。

Understanding the Score

当我们debugging一个复杂的查询的时候,我们往往很难确切的知道一个document的_score是如何计算出来的。Elasticsearch为我们提供了explain参数来具体的展现分数计算的细节:

GET /_search?explain
{
     “query” : { “match” : { “tweet” : “honeymoon” }}
}
我们会在响应中的explanation看到_score是如何计算出来的。
当添加了explain之后会产生一堆输出,这些输出很让人崩溃,但是它却很值得我们搞清楚它的含义。
首先我们会看到一些元数据的输出:
{
     “_index” : “us”,
     “_type” : “tweet”,
     “_id” : “12”,
     “_score” : 0.076713204,
     “_source” : { … trimmed … },

接着我们会看到一些关于分片和node的信息,这些信息是比较有用的,因为term和document的频率是按每个分片来计算的,而不是每个index。

“_shard” : 1,
“_node” : “mzIVYCsqSWCG_M_ZffSs9Q”,

之后是_explanation,每个里面都含有一个description,这是告诉我们应用哪一种计算方式,以及计算出来的结果,而detail中是计算的细节:

“_explanation”: {
     “description”: “weight(tweet:honeymoon in 0)
     [PerFieldSimilarity], result of:”,
     “value”: 0.076713204,
     “details”: [
     {
          “description”: “fieldWeight in 0, product of:”,
          “value”: 0.076713204,
          “details”: [
          {
               “description”: “tf(freq=1.0), with freq of:”,
               “value”: 1,
               “details”: [
               {
                    "description": "termFreq=1.0",
                    "value": 1
               }
          ]
     },
               {
                    “description”: “idf(docFreq=1, maxDocs=1)”,
                    “value”: 0.30685282
               },
               {
                    “description”: “fieldNorm(doc=0)”,
                    “value”: 0.25,
               }
          ]
     }
]
}
第一部分是计算的总结,它告诉我们honeymoon这个term的TF/IDF的权重,而document 0只是一个文档ID,我们可以忽略它。

接着是权重计算的细节:

term frequency

honeymoon在tweet这个字段中出现的次数。

Inverse document frequency

在这个index的所有document中,honeymoon出现在tweet里的次数。

Field-length norm

在document中tweet这个字段的长度。

如果感觉JSON格式的响应不易观察,可以添加format=yaml参数,使数据变成YAML格式。

Understanding Why a Document Matched

我们可以通过explain选项来为每一个结果添加explanation信息。我们可以用这种方式理解什么样的document可以匹配,什么样的不能匹配。

我们来看下面这个请求:

GET /us/tweet/12/_explain
{
     “query” : {
          “filtered” : {
               “filter” : { “term” : { “user_id” : 2 }},
               “query” : { “match” : { “tweet” : “honeymoon” }}
               }
     }
}
我们看到整个explanation只有一个description元素。如下:
“failure to match filter: cache(user_id:[2 TO 2])”
它告诉我们user_id 这个filter阻止了我们去匹配document。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>