ES 排序相关性

  • Post author:
  • Post category:其他


默认情况下,返回的结果是按照 相关性 进行排序的——最相关的文档排在最前。

1.按照字段的值排序

在这个案例中,通过时间来对 tweets 进行排序是有意义的,最新的 tweets 排在最前。 我们可以使用 sort 参数进行实现:

GET /_search

{


“query” : {


“bool” : {


“filter” : { “term” : { “user_id” : 1 }}

}

},

“sort”: { “date”: { “order”: “desc” }}

}

2.多级排序

假定我们想要结合使用 date 和 _score 进行查询,并且匹配的结果首先按照日期排序,然后按照相关性排序:

GET /_search

{


“query” : {


“bool” : {


“must”:   { “match”: { “tweet”: “manage text search” }},

“filter” : { “term” : { “user_id” : 2 }}

}

},

“sort”: [

{ “date”:   { “order”: “desc” }},

{ “_score”: { “order”: “desc” }}

]

}

3.多值字段的排序

一种情形是字段有多个值的排序, 需要记住这些值并没有固有的顺序;一个多值的字段仅仅是多个值的包装,这时应该选择哪个进行排序呢?

对于数字或日期,你可以将多值字段减为单值,这可以通过使用 min 、 max 、 avg 或是 sum 排序模式 。 例如你可以按照每个 date 字段中的最早日期进行排序,通过以下方法:

“sort”: {


“dates”: {


“order”: “asc”,

“mode”:  “min”

}

}

4.字符串排序与多字段

被解析的字符串字段也是多值字段, 但是很少会按照你想要的方式进行排序。如果你想分析一个字符串,如 fine old art , 这包含 3 项。我们很可能想要按第一项的字母排序,然后按第二项的字母排序,诸如此类,但是 Elasticsearch 在排序过程中没有这样的信息。

你可以使用 min 和 max 排序模式(默认是 min ),但是这会导致排序以 art 或是 old ,任何一个都不是所希望的。

我们真正想要做的是传递一个 单字段 但是却用两种方式索引它。所有的 _core_field 类型 (strings, numbers, Booleans, dates) 接收一个 fields 参数

该参数允许你转化一个简单的映射如:

“tweet”: {


“type”:     “string”,

“analyzer”: “english”

}

为一个多字段映射如:

“tweet”: {

“type”:     “string”,

“analyzer”: “english”,

“fields”: {


“raw”: {

“type”:  “string”,

“index”: “not_analyzed”

}

}

}

tweet 主字段与之前的一样: 是一个 analyzed 全文字段。

新的 tweet.raw 子字段是 not_analyzed.

现在,至少只要我们重新索引了我们的数据,使用 tweet 字段用于搜索,tweet.raw 字段用于排序:

GET /_search

{


“query”: {


“match”: {


“tweet”: “elasticsearch”

}

},

“sort”: “tweet.raw”

}

以全文 analyzed 字段排序会消耗大量的内存。

5.什么是相关性?

我们曾经讲过,默认情况下,返回结果是按相关性倒序排列的。 但是什么是相关性? 相关性如何计算?

每个文档都有相关性评分,用一个正浮点数字段 _score 来表示 。 _score 的评分越高,相关性越高。

Elasticsearch 的相似度算法被定义为检索词频率/反向文档频率, TF/IDF ,包括以下内容:

检索词频率

检索词在该字段出现的频率?出现频率越高,相关性也越高。 字段中出现过 5 次要比只出现过 1 次的相关性高。

反向文档频率

每个检索词在索引中出现的频率?频率越高,相关性越低。检索词出现在多数文档中会比出现在少数文档中的权重更低。

字段长度准则

字段的长度是多少?长度越长,相关性越低。 检索词出现在一个短的 title 要比同样的词出现在一个长的 content 字段权重更大。

单个查询可以联合使用 TF/IDF 和其他方式,比如短语查询中检索词的距离或模糊查询里的检索词相似度。

5.1理解评分标准

当调试一条复杂的查询语句时,想要理解 _score 究竟是如何计算是比较困难的。Elasticsearch 在 每个查询语句中都有一个 explain 参数,将 explain 设为 true 就可以得到更详细的信息。

GET /_search?explain

{


“query”   : { “match” : { “tweet” : “honeymoon” }}

}

“_explanation”: { //honeymoon 相关性评分计算的总结

“description”: “weight(tweet:honeymoon in 0)

[PerFieldSimilarity], result of:”,

“value”:       0.076713204,

“details”: [

{ //honeymoon 相关性评分计算的总结

“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,

}

]

}

]

}

输出 explain 结果代价是十分昂贵的,它只能用作调试工具 。千万不要用于生产环境。

第一部分是关于计算的总结。告诉了我们 honeymoon 在 tweet 字段中的检索词频率/反向文档频率或TF/IDF, (这里的文档 0 是一个内部的 ID,跟我们没有关系,可以忽略。)

然后它提供了权重是如何计算的细节:

检索词频率:

检索词 `honeymoon` 在这个文档的 `tweet` 字段中的出现次数。

反向文档频率:

检索词 `honeymoon` 在索引上所有文档的 `tweet` 字段中出现的次数。

字段长度准则:

在这个文档中, `tweet` 字段内容的长度 — 内容越长,值越小。

复杂的查询语句解释也非常复杂,但是包含的内容与上面例子大致相同。 通过这段信息我们可以了解搜索结果是如何产生的。

6.Doc Values 介绍

本章的最后一个话题是关于 Elasticsearch 内部的一些运行情况。在这里我们先不介绍新的知识点,所以我们应该意识到,Doc Values 是我们需要反复提到的一个重要话题。

当你对一个字段进行排序时,Elasticsearch 需要访问每个匹配到的文档得到相关的值。倒排索引的检索性能是非常快的,但是在字段值排序时却不是理想的结构。

在搜索的时候,我们能通过搜索关键词快速得到结果集。

当排序的时候,我们需要倒排索引里面某个字段值的集合。换句话说,我们需要 转置 倒排索引。

转置 结构在其他系统中经常被称作 列存储 。实质上,它将所有单字段的值存储在单数据列中,这使得对其进行操作是十分高效的,例如排序。

在 Elasticsearch 中,Doc Values 就是一种列式存储结构,默认情况下每个字段的 Doc Values 都是激活的,Doc Values 是在索引时创建的,当字段索引时,Elasticsearch 为了能够快速检索,会把字段的值加入倒排索引中,同时它也会存储该字段的 Doc Values。

Elasticsearch 中的 Doc Values 常被应用到以下场景:

对一个字段进行排序

对一个字段进行聚合

某些过滤,比如地理位置过滤

某些与字段相关的脚本计算

因为文档值被序列化到磁盘,我们可以依靠操作系统的帮助来快速访问。当 working set 远小于节点的可用内存,系统会自动将所有的文档值保存在内存中,使得其读写十分高速; 当其远大于可用内存,操作系统会自动把 Doc Values 加载到系统的页缓存中,从而避免了 jvm 堆内存溢出异常。

我们稍后会深入讨论 Doc Values。现在所有你需要知道的是排序发生在索引时建立的平行数据结构中。



版权声明:本文为mezheng原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。