当前位置:   article > 正文

ElasticSearch教程入门到精通——第一部分(基于ELK技术栈elasticsearch 8.x新特性)

ElasticSearch教程入门到精通——第一部分(基于ELK技术栈elasticsearch 8.x新特性)

ElasticSearch教程入门到精通——第一部分(基于ELK技术栈elasticsearch 8.x新特性)

在这里插入图片描述

在这里插入图片描述

1. ElasticSearch安装(略)

在这里插入图片描述

在这里插入图片描述

2. ElasticSearch基础功能

2.1 索引操作

2.1.1 创建索引

ES软件的索引可以类比为MySQL中表的概念,创建一个索引,类似于创建一个表。查询完成后,Kibana右侧会返回响应结果及请求状态

PUT test_index
  • 1

在这里插入图片描述

重复创建索引——报错!

在这里插入图片描述

在这里插入图片描述

2.1.2 Head 索引

head test_index
  • 1

在这里插入图片描述

head test_index1
  • 1

在这里插入图片描述

在这里插入图片描述

2.1.3 查询索引

2.1.3.1 查询单独索引
GET test_index
  • 1

在这里插入图片描述

在这里插入图片描述

2.1.3.2 查询全部索引
GET _cat/indices
  • 1

在这里插入图片描述

在这里插入图片描述

2.1.4 增加配置

JSON格式的主题内容

PUT test_index_1
{
	"aliases":{
		"test1":{}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

查询看结果
在这里插入图片描述
这样 别名就设置上了

GET test1
  • 1

试一试~

注意:ES软件不支持修改索引信息,如果想要修改,只能新建

在这里插入图片描述

2.1.5 删除索引

DELETE test_index_1
  • 1

在这里插入图片描述
再删除一次 ~!

在这里插入图片描述
在这里插入图片描述

2.2 文档操作

文档是ES软件搜索数据的最小单位,不依赖预先定义的模式,所以可以将文档类比为表的一行JSON类型的数据。我们知道关系型数据库中,要提前定义字段才能使用,在Elasticsearch中,对于字段是非常灵活的,有时候,我们可以忽略该字段,或者动态的添加一个新的字段。

2.2.1 创建文档

索引已经创建好了,接下来我们来创建文档,并添加数据。这里的文档可以类比为关系型数据库中的表数据,添加的数据格式为JSON格式

PUT test_doc
  • 1

添加索引
在这里插入图片描述

PUT test_doc/_doc
{
	"id":1001,
	"name":"zhangsan",
	"age":30
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述

为什么只让用Post 不让用PUT?

  • 因为PUT创建的时候,创建数据具有唯一性标识
PUT test_doc/_doc/1001
{
	"id":1001,
	"name":"zhangsan",
	"age":30
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述

POST test_doc/_doc
{
	"id":1002,
	"name":"lisi",
	"age":40
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在这里插入图片描述

在这里插入图片描述

2.2.2 查询文档

2.2.2.1 查询个别文档
GET test_doc/_doc/1001
  • 1

在这里插入图片描述

GET test_doc/_doc
  • 1

在这里插入图片描述

在这里插入图片描述

2.2.2.2 查询文档所有数据
GET test_doc/_search
  • 1

在这里插入图片描述

在这里插入图片描述

2.2.3 修改数据

PUT test_doc/_doc/1001
{
	"id":10011,
	"name":"zhangsan1",
	"age":300,
	"tel":123123
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这里插入图片描述

POST 也可以
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2.2.4 删除数据

DELETE test_doc/_doc/1002
  • 1

在这里插入图片描述
再删一次
在这里插入图片描述

在这里插入图片描述

2.3 文档搜索

PUT test_query
  • 1
PUT test_query/_bulk
{"index": {"_index": "test_query","_id": "1001"}}
{"id": "1001","name":"zhang san","age":30}
{"index": {"_index": "test_query","_id": "1002"}}
{"id": "1002","name":"li si","age": 40}
{"index": {"_index": "test_query","_id": "1003"}}
{"id": "1003", "name": "wang wu","age" : 50}
{"index": {"_index": "test_query","_id": "1004"}}
{"id": "1004","name": "zhangsan", "age" : 30}
{"index": {"_index": "test_query","_id": "1005"}}
{"id": "1005","name": "lisi","age":40}
{"index": {"_index": "test_query","_id": "1006"}}
{"id": "1006", "name ": "wangwu","age" : 50}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这里插入图片描述

在这里插入图片描述

2.3.1 Match分词查询

Match 是分词查询,ES会将数据分词保存

GET test_query/_search
{
	"query":{
		"match":{
			"name":"zhangsan"
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述

GET test_query/_search
{
	"query":{
		"match":{
			"name":"zhang"
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述

GET test_query/_search
{
	"query":{
		"match":{
			"name":"zhang li"
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这里插入图片描述

在这里插入图片描述

2.3.2 使用term精确匹配某个字段的关键词

但是我不想分词~

GET test_query/_search
{
	"query":{
		"term":{
			"name":{
				"value":"zhang san"
			}
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述

GET test_query/_search
{
	"query":{
		"term":{
			"name":{
				"value":"zhangsan"
			}
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述

在这里插入图片描述

2.3.3 查询结果中过滤某些不需要的字段

某些情况下,不需要查询结果中返回所有的字段,就可以通过添加"_source"进行限制

GET test_query/_search
{
  "_source": ["name","age"], 
  
  "query": {
    "match": {
      "name": "zhang"
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述

在这里插入图片描述

2.3.4 多条件组合查询

组合查询的关键语法是需要在查询条件中使用bool关键字

在这里插入图片描述

2.3.4.1 查询name中含有zhang或age为40的数据

这个需求类似于mysql 中的or的语法,在es中使用should可以满足类似的需求

GET test_query/_search
{
  "query": {
    "bool": {
      "should": [
        [
          {
            "match":{
              "name":"zhang"
            }
          },
          {
            "match":{
              "age":40
            }
          }
        ]
      ]
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在这里插入图片描述

在这里插入图片描述

2.3.4.2 查询文档中name中必须含有zhang或者age必须大于等于30岁的数据

组合使用should和must

GET test_query/_search
{
  "query": {
    "bool": {
      "must": [
        [
          {
            "match":{
              "name":"zhang"
            }
          }
        ]
      ],
      
      "should": [
        {
          "range": {
            "age": {
              "gte": 30
            }
          }
        }
      ]
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

在这里插入图片描述

在这里插入图片描述

2.3.4.3 查询结果排序

查询name中含有 zhang的文档,并按照age排序

GET test_query/_search
{
  
  "query": {
    "match": {
      "name": "zhang"
    }
  },
  "sort":[
    {
      "age" : {
        "order":"desc"
      }
    }
  ]
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在这里插入图片描述

在这里插入图片描述

2.3.5 分页查询

语法

GET 索引名称/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,        //从第几条开始查询
  "size": 2         //每次查询多少数据
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

看下面的查询结果
在这里插入图片描述

计算公式:

f r o m = ( p a g e n o − 1 ) ∗ s i z e from = (pageno -1)*size from=(pageno1)size

在这里插入图片描述

2.4 聚合搜索

实际业务中,经常会涉及到对查询的结果根据某个或者某些字段进行聚合,类似于mysql中的group by语法;

2.4.1 根据age将查询结果进行分组聚合

注意点:这里 "size"设置为0表示查询结果中不展示其他非聚合结果的信息

GET test_query/_search
{
 
  "aggs": {
    "aggAge": {
      "terms": {
        "field": "age"
      }
    }
  },
 
  "size": 0
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这里插入图片描述

在这里插入图片描述

2.4.2 查询年龄大于等于40岁的,并将结果按照age分组聚合

GET test_query/_search
{
 
 "query": {
   "range": {
     "age": {
       "gte": 40
     }
   }
 }, 
 
  "aggs": {
    "aggAge": {
      "terms": {
        "field": "age"
      }
    }
  },
 
  "size": 0
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

查询结果如下

在这里插入图片描述

2.4.3 根据age分组聚合,再对聚合后的结果按照age求平均值

GET test_query/_search
{
  "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age"
      },
      
      "aggs": {
        "avgAgg": {
          "avg": {
            "field": "age"
          }
        }
      }
      
    }
  },
  "size": 0
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

查询结果如下

在这里插入图片描述

在这里插入图片描述

2.4.4 获取结果集中的前N个数据

GET test_query/_search
{
  "aggs": {
    "top3": {
      "top_hits": {
        "size": 3
      }
    }
  },
  "size": 0
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

查询结果如下

在这里插入图片描述

在这里插入图片描述

2.4.5 获取结果集中按照age字段排序后求取前N个数据

GET test_query/_search
{
  "aggs": {
    "top3": {
      "top_hits": {
        "sort": [
          {
          "age" : {
              "order":"desc"
            }
          }
        ], 
        "size": 3
      }
    }
  },
  "size": 0
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这里插入图片描述

2.5 索引模板

我们之前对索引进行一些配置信息设置,但是都是在单个索引上进行设置。在实际开发中,我们可能需要创建不止一个索引,但是每个索引或多或少都有一些共性。

比如我们在设计关系型数据库时,一般都会为每个表结构设计一些常用的字段,比如:创建时间更新时间备注信息等。elasticsearch 在创建索引的时候,就引入了模板的概念,你可以先设置一些通用的模板,在创建索引的时候,elasticsearch会先根据你创建的模板对索引进行设置。

elasticsearch中提供了很多的默认设置模板,这就是为什么我们在新建文档的时候,可以为你自动设置一些信息, 做一些字段转换等。

在这里插入图片描述

2.5.1 创建/修改 索引

索引可使用预定义的模板进行创建这个模板称作Indextemplates.模板设置包括settingsmappings

PUT _template/mytemplate

{
  "index_patterns": [
    "my*"  // 该模板自动适用于索引名称以 my 开头的索引
  ],
  // 设置模板规则
  "settings": {
    "index": {
      "number_of_shards": "2" // 分片数量
    }
  },
  // 影射规则
  "mappings": {
    "properties": {
      // 字段 now 的类型及格式
      "now": {
        "type": "date",
        "format": "yyyy/MM/dd"
      }
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

在这里插入图片描述

可以多长操作!!

2.5.2 查看模板

GET _template/模板名称
  • 1

在这里插入图片描述

在这里插入图片描述

2.5.3 更新模板

与创建命令相同,只要创建的模板名称已存在,就是更新操作,新规则覆盖旧规则

如果创建的是索引,不是索引模板,当要创建的索引已存在时,操作是不会成功的,会出错,提示索引已存在

在这里插入图片描述

2.5.4 应用模板

只要新创建的 索引 符合 索引模板 的匹配规则,就会自动应用模板

如:新创建 my_index_template 索引,以 my 开头,符合匹配规则

// 应用索引模板;创建以 my 开头的索引
PUT my_index_template
// 查询创建的索引
GET my_index_template
  • 1
  • 2
  • 3
  • 4

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2.5.5 删除模板

DELETE _template/索引模板名称
  • 1

删除后查询;结果为空;查询不存在的索引模板时,结果都为空

在这里插入图片描述

在这里插入图片描述

2.6 中文分词

我们在使用Elasticsearch官方默认的分词插件时会发现,其对中文的分词效果不佳,经常分词后得效果不是我们想要得。

2.6.1 分词操作

GET _analyze
{
  "analyzer": "standard", 
  "text": ["zhang san"]
}
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

在这里插入图片描述

2.6.2 分词操作(不带插件情况下,中文拆分逻辑太适合)

GET _analyze
{
  "analyzer": "chinese", 
  "text": ["我是一个三好学生"]
}
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

在这里插入图片描述

2.6.3 集成了IK插件后提供的分词

一定注意!版本下载的正确性!!!
在这里插入图片描述
在这里插入图片描述
别忘了重新启动!!

在这里插入图片描述

2.6.3.1 ik_smart——最少切分
GET _analyze
{
  "analyzer": "ik_smart", 
  "text": ["我是一个三好学生"]
}
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

2.6.3.2 ik_max_word——最细粒度切分

相较于上者,分得更加精细

GET _analyze
{
  "analyzer": "ik_max_word", 
  "text": ["我是一个三好学生"]
}
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

在这里插入图片描述

2.6.4 自定义分词效果

在这里插入图片描述
在这里插入图片描述
重新启动ES!!!

在这里插入图片描述

2.7 文档评分机制(转载)

PUT test_score

PUT test_score/_doc/1001
{
  "text": "zhang kai shou bi, yin jie tai yang"
}

PUT test_score/_doc/1002
{
  "text": "zhang san"
}

GET test_score/_search?explain=true
{
  "query": {
    "match": {
      "text": "zhang"
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

在这里插入图片描述

Elasticsearch 的得分机制是一个基于词频和逆文档词频的公式,简称为 TF-IDF 公式,所以先来研究下 TF-IDF原理。

在这里插入图片描述

2.7.1 TF-IDF 原理

  • 英文全称:Term Frequency - Inverse Document Frequency
  • 中文名称:词频-逆文档频率

常用于文本挖掘,资讯检索等应用,在NLP以及推荐等领域都是一个常用的指标,用于衡量字词的重要性。

比较直观的解释是,如果一个词本来出现的频率就很高,如the,那么它就几乎无法带给读者一些明确的信息。

一般地,以TF-IDF衡量字词重要性时

  • 某个字词在某个文档中出现的频率越高,那么该字词对该文档就有越大的重要性,它可能会是文章的关键词(词在单个文档中出现的频率,相对于当个文档!!!)
  • 但若字词在词库中出现的频率越高,那么字词的重要性越低,如the。(相对于整个文档集合,也就是词库)

在这里插入图片描述

2.7.1.1 计算公式

TF-IDF即是两者相乘,词频乘以逆文档频率,如下:

TF-IDF = T F ∗ I D F =TF*IDF =TFIDF

下标ij的含义:编号为j的文档中的词语i在该文档中的词频,即所占比例,n为该词语的数量。如下:

换言之,就是词语出现的次数与文档中所有词总数的比值。

T F i j = n i j n ∗ j TF_{ij} = \frac{n_{ij}}{n_{*j}} TFij=njnij

N表示文档总数,Ni表示文档集中包含了词语 i i i 的文档数。

对分子分母加一是为了避免某些词语没有在文档中出现过,导致分母为零的情况。

IDF针对某个词计算了它的逆文档频率,即包含该词语的文档比例的倒数(再取对数),若IDF值越小,分母越大,说明这个词语在文档集中比较常见不具有鲜明的信息代表性,TF-IDF的值就小。

总之TF-IDF的值,通常希望它越大越好,大值代表性强。如下:

I D F i = l o g ( N + 1 N i + 1 ) IDF_i=log (\frac{N+1}{N_i+1}) IDFi=logNi+1N+1

2.7.1.2 示例说明

有两个文档,即doc1doc2,并去它们的并集

doc1 = "The cat sat on my bed"
doc2 = "The dog sat on my knees"
# 构建词库,union是并集操作
wordSet = set(doc1.split()).union(set(doc2.split()))
  • 1
  • 2
  • 3
  • 4

两个文档的并集如下:

{‘The’,‘bed’,‘cat’,‘dog’,‘knees’,‘my’,‘on’,‘sat’}

doc1doc2两个文档对应的词在并集中的统计情况:

序号catsatmyondogbedTheknees
011110110
101111011

在这里插入图片描述

2.7.1.3 计算TF

计算词频 TF,对单个文档统计:

再理解一下,何为TF,表示单个单词占当前文档所有单词集合的比值。即1/6=0.16666666666…

catsatmyondogbedTheknees
11110110
0.166666…0.166666…0.166666…0.166666…00.166666…0.166666…0

在这里插入图片描述

2.7.1.4 计算IDF

逆文档频率IDF,全局只有一份逆文档频率,对所有文档统计

N表示文档总数,Ni`表示文档集中包含了词语i的文档数。

此时N=2,共有两个文档。Ni表示含有单词的文档个数。

catsatmyondogbedTheknees
0.17609125…0.00.00.0…0.17609125…0.17609125…0.00.17609125…

在这里插入图片描述

2.7.1.5 TF-IDF计算

最终计算:TF-IDF = TF * IDF

序号catsatmyondogbedTheknees
00.0293490000.029349000
10000.0293490000.029349

在这里插入图片描述

2.7.2 Elasticsearch打分机制

上面介绍了TF-IDF的原理,而ES的得分机制就是基于词频和逆文档词频的公式,即TF-IDF公式。
s c o r e ( q , d ) = c o o r d ( q , d ) ⋅ q u e r y N o r m ( q ) ⋅ ∑ t i n q ( t f ( t i n d ) ⋅ i d f ( t ) 2 ⋅ t . g e t B o o s t ( ) ⋅ n o r m ( t , d ) ) score(q,d) = coord(q,d)\cdot queryNorm(q)\cdot \sum_{t in q}(tf(t in d)\cdot idf(t){^2}\cdot t.getBoost()\cdot norm(t,d)) score(q,d)=coord(q,d)queryNorm(q)tinq(tf(tind)idf(t)2t.getBoost()norm(t,d))

公式中将查询作为输入,使用不同的手段来确定每一篇文档的得分,将每一个因素最后通过公式综合起来,返回该文档的最终得分。这个综合考量的过程,在ES中这种相关性称为得分。

考虑到查询内容和文档的关系比较复杂,所以公式中需要输入的参数和条件非常得多,但是其中比较重要的其实是TF-IDF算法 ,再次解释一下。

  • TF (词频)

Term Frequency : 搜索文本中的各个词条在查询文本中出现了多少次,次数越多,就越相关,得分会比较高

  • IDF(逆文档频率)

Inverse Document Frequency : 搜索文本中的各个词条在整个索引的所有文档中出现了多少次,出现的次数越多,说明越不重要,也就越不相关,得分就比较低。

在这里插入图片描述

2.7.2.1 示例说明

在查询语句的最后加上explain=true ,会把得分过程打印。

注:当前ElasticSearchscorpios索引里,只有一个文档。

PUT itwluo

PUT itwluo/_doc/1001
{
  "text": "java"
}

GET itwluo/_search
{
  "query": {
    "match": {
      "text": "java"
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

result


{
  "took": 992,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "itwluo",
        "_id": "1001",
        "_score": 0.2876821,
        "_source": {
          "text": "java"
        }
      }
    ]
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

详细结果


{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.2876821,
    "hits": [
      {
        "_shard": "[itwluo][0]",
        "_node": "EX7ZCQpSRLu-OWEZjQazog",
        "_index": "itwluo",
        "_id": "1001",
        "_score": 0.2876821,
        "_source": {
          "text": "java"
        },
        "_explanation": {
          "value": 0.2876821,
          "description": "weight(text:java in 0) [PerFieldSimilarity], result of:",
          "details": [
            {
              "value": 0.2876821,
              "description": "score(freq=1.0), computed as boost * idf * tf from:",
              "details": [
                {
                  "value": 2.2,
                  "description": "boost",
                  "details": []
                },
                {
                  "value": 0.2876821,
                  "description": "idf, computed as log(1 + (N - n + 0.5) / (n + 0.5)) from:",
                  "details": [
                    {
                      "value": 1,
                      "description": "n, number of documents containing term",
                      "details": []
                    },
                    {
                      "value": 1,
                      "description": "N, total number of documents with field",
                      "details": []
                    }
                  ]
                },
                {
                  "value": 0.45454544,
                  "description": "tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:",
                  "details": [
                    {
                      "value": 1,
                      "description": "freq, occurrences of term within document",
                      "details": []
                    },
                    {
                      "value": 1.2,
                      "description": "k1, term saturation parameter",
                      "details": []
                    },
                    {
                      "value": 0.75,
                      "description": "b, length normalization parameter",
                      "details": []
                    },
                    {
                      "value": 1,
                      "description": "dl, length of field",
                      "details": []
                    },
                    {
                      "value": 1,
                      "description": "avgdl, average length of field",
                      "details": []
                    }
                  ]
                }
              ]
            }
          ]
        }
      }
    ]
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

新增数据后,观察分值变化

PUT itwluo/_doc/1002
{
  "text": "java bigdata"
}

#查询文档数据
GET itwluo/_search?explain=true
{
  "query": {
    "match": {
      "text": "java"
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

详细结果

{
  "took": 609,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 0.21110919,
    "hits": [
      {
        "_shard": "[itwluo][0]",
        "_node": "EX7ZCQpSRLu-OWEZjQazog",
        "_index": "itwluo",
        "_id": "1001",
        "_score": 0.21110919,
        "_source": {
          "text": "java"
        },
        "_explanation": {
          "value": 0.21110919,
          "description": "weight(text:java in 0) [PerFieldSimilarity], result of:",
          "details": [
            {
              "value": 0.21110919,
              "description": "score(freq=1.0), computed as boost * idf * tf from:",
              "details": [
                {
                  "value": 2.2,
                  "description": "boost",
                  "details": []
                },
                {
                  "value": 0.18232156,
                  "description": "idf, computed as log(1 + (N - n + 0.5) / (n + 0.5)) from:",
                  "details": [
                    {
                      "value": 2,
                      "description": "n, number of documents containing term",
                      "details": []
                    },
                    {
                      "value": 2,
                      "description": "N, total number of documents with field",
                      "details": []
                    }
                  ]
                },
                {
                  "value": 0.5263158,
                  "description": "tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:",
                  "details": [
                    {
                      "value": 1,
                      "description": "freq, occurrences of term within document",
                      "details": []
                    },
                    {
                      "value": 1.2,
                      "description": "k1, term saturation parameter",
                      "details": []
                    },
                    {
                      "value": 0.75,
                      "description": "b, length normalization parameter",
                      "details": []
                    },
                    {
                      "value": 1,
                      "description": "dl, length of field",
                      "details": []
                    },
                    {
                      "value": 1.5,
                      "description": "avgdl, average length of field",
                      "details": []
                    }
                  ]
                }
              ]
            }
          ]
        }
      },
      {
        "_shard": "[itwluo][0]",
        "_node": "EX7ZCQpSRLu-OWEZjQazog",
        "_index": "itwluo",
        "_id": "1002",
        "_score": 0.160443,
        "_source": {
          "text": "java bigdata"
        },
        "_explanation": {
          "value": 0.160443,
          "description": "weight(text:java in 0) [PerFieldSimilarity], result of:",
          "details": [
            {
              "value": 0.160443,
              "description": "score(freq=1.0), computed as boost * idf * tf from:",
              "details": [
                {
                  "value": 2.2,
                  "description": "boost",
                  "details": []
                },
                {
                  "value": 0.18232156,
                  "description": "idf, computed as log(1 + (N - n + 0.5) / (n + 0.5)) from:",
                  "details": [
                    {
                      "value": 2,
                      "description": "n, number of documents containing term",
                      "details": []
                    },
                    {
                      "value": 2,
                      "description": "N, total number of documents with field",
                      "details": []
                    }
                  ]
                },
                {
                  "value": 0.40000004,
                  "description": "tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:",
                  "details": [
                    {
                      "value": 1,
                      "description": "freq, occurrences of term within document",
                      "details": []
                    },
                    {
                      "value": 1.2,
                      "description": "k1, term saturation parameter",
                      "details": []
                    },
                    {
                      "value": 0.75,
                      "description": "b, length normalization parameter",
                      "details": []
                    },
                    {
                      "value": 2,
                      "description": "dl, length of field",
                      "details": []
                    },
                    {
                      "value": 1.5,
                      "description": "avgdl, average length of field",
                      "details": []
                    }
                  ]
                }
              ]
            }
          ]
        }
      }
    ]
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167

在这里插入图片描述

2.7.2.2 计算 TF 值

T F = f r e q / ( f r e q + k 1 ∗ ( 1 − b + b ∗ d l / a v g d l ) ) TF = freq/(freq + k1 * (1-b+b*dl/avgdl)) TF=freq/(freq+k1(1b+bdl/avgdl))

参数含义取值
freq文档中出现词条的次数1.0
k1术语饱和参数1.2(默认值)
b长度规格参数(单词长度对于整个文档的影响程度)0.75(默认值)
dl当前文中分解的字段长度1.0
avgdl查询文档中分解字段数量/查询文档数量1.0
TF(词频)1.0/(1+1.2 * (1-0.75+0.75 * 1.0/1.0))0.454545

在这里插入图片描述

2.7.2.3 计算 IDF 值

I D F = l n ( 1 + ( N − n + 0.5 ) / ( n + 0.5 ) ) IDF = ln(1+(N−n+0.5)/(n+0.5)) IDF=ln(1+(Nn+0.5)/(n+0.5))

参数含义取值
N包含查询字段的文档总数(不一定包含查询词条)1
n包含查询词条的文档数1
IDF(逆文档频率)log(1+(1-1+0.5)/(1+0.5))0.2875821

注:这里的 ln是底数为e 的对数

在这里插入图片描述

2.7.2.4 计算文档得分

s c o r e = t f b o o s t ∗ i d f ∗ t f score = tf boost∗idf∗tf score=tfboostidftf

参数含义取值
boost词条权重2.2(基础值)*查询权重(1)
idf逆文档频率0.2876821
tf词频0.454545
score(得分)2.20.28768210.4545450.2876821

在这里插入图片描述

2.7.2.5 增加新的文档测试得分
  • 增加一个毫无关系的文档
# 增加文档
PUT /scorpios/_doc/2
{
 "text" : "spark"
}
# 得分:0.6931741
GET /scorpios/_search
{
     "query": {
        "match": {
            "text": "hello"
        }
     } 
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

因为新文档无词条相关信息,所以匹配的文档数据得分就应该较高

  • 增加一个一模一样的文档
# 增加文档
PUT /scorpios/_doc/2
{
 "text" : "hello"
}

# 得分:0.18232156
GET /scorpios/_search
{
 	"query": {
 		"match": {
 			"text": "hello"
 		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

因为新文档含词条相关信息,且多个文件含有词条,所以显得不是很重要,得分会变低

  • 增加一个含有词条,但是内容较多的文档
# 增加文档
PUT /scorpios/_doc/2 
{
	"text" : "hello elasticsearch" 
}
# 得分:0.14874382
GET /scorpios/_search
{
     "query": {
         "match": {
         	"text": "hello"
         }
     }
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

因为新文档含词条相关信息,但只是其中一部分,所以查询文档的分数会变得更低一些。

在这里插入图片描述

2.7.3 案列

2.7.3.1 需求

查询文档标题中含有Hadoop,Elasticsearch,Spark的内容,优先选择Spark的内容

2.7.3.2 准备数据
# 创建索引
PUT /test
# 准备数据
PUT /test/_doc/1001
{
	"title" : "Hadoop is a Framework",
	"content" : "Hadoop 是一个大数据基础框架" 
}
PUT /test/_doc/1002
{
	"title" : "Hive is a SQL Tools",
	"content" : "Hive 是一个 SQL 工具" 
}
PUT /test/_doc/1003
{
	"title" : "Spark is a Framework",
	"content" : "Spark 是一个分布式计算引擎" 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
2.7.3.3 查询数据
# 查询文档标题中含有“Hadoop”,“Elasticsearch”,“Spark”的内容
GET /test/_search?explain=true
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": {
              "query": "Hadoop", "boost": 1
            }
          }
        },
        {
          "match": {
            "title": {
              "query": "Hive", "boost": 1
            }
          }
        },
        {
          "match": {
            "title": {
              "query": "Spark", "boost": 1
            }
          }
        }
      ]
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

此时会发现,Spark的结果并不会放置在最前面

此时可以更改 Spark 查询的权重参数 boost,看看查询的结果有什么不同

# 查询文档标题中含有“Hadoop”,“Elasticsearch”,“Spark”的内容
GET /test/_search?explain=true
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": {
              "query": "Hadoop", "boost": 1
            }
          }
        },
        {
          "match": {
            "title": {
              "query": "Hive", "boost": 1
            }
          }
        },
        {
          "match": {
            "title": {
              "query": "Spark", "boost": 2
            }
          }
        }
      ]
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

在这里插入图片描述

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/529118
推荐阅读
相关标签
  

闽ICP备14008679号