es 3期 第14节-全文文本分词查询
#### 1.Elasticsearch是数据库,不是普通的Java应用程序,传统数据库需要的硬件资源同样需要,提升性能最有效的就是升级硬件。
#### 2.Elasticsearch是文档型数据库,不是关系型数据库,不具备严格的ACID事务特性,任何企图直接替代严格事务性场景的应用项目都会失败!!!
##### 索引字段与属性都属于静态设置,若后期变更历史数据需要重建索引才可生效
##### 对历史数据无效!!!!
##### 一定要重建索引!!!
#### 全文文本概念
### 概念介绍
## 1.文章语句分词
## 2.分词之后,支持基于分词检索
## 3.分词算法很多,分词领域很深入
## 4.基于倒排索引算法-Inverted-Index
## 5.分词检索的打分算法TF/IDF=>BM25
## 6.字段类型仅限于text类型
## 全文搜索内容较深,初步学习使用即可
# es测试分词器默认api语法,默认分词算法 standard 按照空格、逗号这种方式分
# 初步理解分词,数据在入库前已经做好了分词并建立了索引
POST _analyze
{
"text": [
"hello every body, 我是DavidSoCool, 我正在学习es"
],
"analyzer":"standard"
}
### 全文文本检索
# Match-all:全查询
# Match:标准分词
# 准备数据
DELETE kibana_sample_data_flights_fulltext
POST _reindex
{
"source": {
"index": "kibana_sample_data_flights"
},
"dest": {
"index": "kibana_sample_data_flights_fulltext"
}
}
## match-all 全匹配
# 1.Match all没有限制条件,直接等同于search查询
# 2.boost:可以调整加权数值
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match_all": {
"boost": 10
}
}
}
## match_none,反向全匹配,可用于测试索引健康,不同与查询数据消耗性能
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match_none": {}
}
}
## match,文本匹配,最常用的
# 排序默认根据_score分值,匹配的次越多,分值就越高,可以用于做简单的推荐系统
GET kibana_sample_data_flights_fulltext/_mapping
# 先测试下分词结果,分成了4个词
POST _analyze
{
"text": [
"Cape Town International Airport"
],
"analyzer":"standard"
}
# 任意匹配一个词就能查询出来
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match": {
"Origin":"Cape Town International Airport"
}
}
}
# 看5000条以后_score分值和Origin字段匹配的数量
GET kibana_sample_data_flights_fulltext/_search
{
"from":1000,
"track_total_hits": true,
"query":{
"match": {
"Origin":"Cape Town International Airport"
}
}
}
# 看9000条以后_score分值和Origin字段匹配的数量
GET kibana_sample_data_flights_fulltext/_search
{
"from":9000,
"track_total_hits": true,
"query":{
"match": {
"Origin":"Cape Town International Airport"
}
}
}
## Request 请求参数
# query:查询表达式
# analyzer:指定分词器,对于查询输入的文本进行分词
# operator:分词之间关联关系,默认是or
# minimum_should_match:分词最小匹配数量
# 这条语句等价于下面那条
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match": {
"Origin":{
"query": "Cape Town International Airport",
"analyzer": "standard",
"operator": "or"
}
}
}
}
# 这条语句等价于上面那条
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match": {
"Origin":"Cape Town International Airport"
}
}
}
# 使用operator=and,表示所有词都匹配上,注意看total
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match": {
"Origin":{
"query": "Cape Town International Airport",
"analyzer": "standard",
"operator": "and"
}
}
}
}
# 去掉前两个词后,跳过100条看看
GET kibana_sample_data_flights_fulltext/_search
{
"from": 100,
"track_total_hits": true,
"query":{
"match": {
"Origin":{
"query": "International Airport",
"analyzer": "standard",
"operator": "and"
}
}
}
}
# minimum_should_match,控制匹配词的精确度,可以使用数字和百分比
# 只能用or,and会查不出数据
GET kibana_sample_data_flights_fulltext/_search
{
"from": 100,
"track_total_hits": true,
"query":{
"match": {
"Origin":{
"query": "Cape Town International Airport",
"analyzer": "standard",
"operator": "or",
"minimum_should_match": 2
}
}
}
}
# 跳过数据看看,total总数111条,跳过110条
# 第111条还是全匹配数据,112开始就只有2个词匹配的数据了
GET kibana_sample_data_flights_fulltext/_search
{
"from": 110,
"track_total_hits": true,
"query":{
"match": {
"Origin":{
"query": "Cape Town International Airport",
"analyzer": "standard",
"operator": "or",
"minimum_should_match": 2
}
}
}
}
# 如何minimum_should_match=4就相当于使用and的了
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match": {
"Origin":{
"query": "Cape Town International Airport",
"analyzer": "standard",
"operator": "or",
"minimum_should_match": 4
}
}
}
}
# minimum_should_match 使用百分比,这里不是简单看分词的比例,需要看文档理解
# 建议还是使用数字,如果词很多可以使用百分比
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match": {
"Origin":{
"query": "Cape Town International Airport",
"analyzer": "standard",
"operator": "or",
"minimum_should_match": "50%"
}
}
}
}
# minimum_should_match 也可以使用负数,相当于是负相关,不建议使用
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match": {
"Origin":{
"query": "Cape Town International Airport",
"analyzer": "standard",
"operator": "or",
"minimum_should_match": -1
}
}
}
}
# fuzziness 纠错搜索,可以帮助我们纠正输入错误的词,具体看文档
# 将Cape输入成错误的Capa
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match": {
"Origin":{
"query": "Capa",
"analyzer": "standard",
"operator": "or",
"fuzziness": 1
}
}
}
}
## Match boolPrefix前缀匹配
# 集成了match和bool
# 去掉最后的Airport,并且把International最后的l去掉,相当于前面2个单词全匹配,最后一个Internationa使用的前缀匹配
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match_bool_prefix": {
"Origin":"Cape Town Internationa"
}
}
}
# 原语句
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match": {
"Origin":"Cape Town International Airport"
}
}
}
## match_phrase 短语搜索,按照我们输入的词顺序匹配,之前的是每个词各自匹配
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match_phrase": {
"Origin":"Cape Town International Airport"
}
}
}
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match_phrase": {
"Origin":"Cape Town"
}
}
}
# 中间跳过一个词Town就查不出来,因为没有这个短语
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match_phrase": {
"Origin":"Cape International Airport"
}
}
}
# slop参数,匹配允许短语间隔误差词数量,中间跳过一个词Town也可以查出来
# slop会耗费计算资源
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match_phrase": {
"Origin":{
"query": "Cape International Airport",
"slop": 1
}
}
}
}
# slop参数,中间跳过两个词
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match_phrase": {
"Origin":{
"query": "Cape Airport",
"slop": 2
}
}
}
}
## Match phase prefix
# 短语前缀查询,集成了短语匹配+前缀
# 前面分词走短语查询
# 最后的分词走前缀查询
# 把Airport的末尾t去掉,效率比slop高效些
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query":{
"match_phrase_prefix": {
"Origin":"Cape Town International Airpor"
}
}
}
## Multi match 多字段
# 很多应用场景需要同时查询多个字段,查询内容一样如电商领域,商品标题与商品描述
# Multimatch专门解决此场景需求,单个字段查询时等同与match匹配
## type 匹配类型
# best_fields,多字段中选择分值最高的字段,默认匹配类型
# most_fields,多字段分值累计和
# cross_fields,多字段查询时,部分分词在第一个字段里,其它的分词在另外的字段里phrase,短语匹配,等同match_phase
# phrase_prefix,短语前缀匹配,等同match_phase_prefix
# bool_prefix,全文匹配逻辑前缀,等同match_bool_prefix.
# tie_breaker,选择多字段分值计算方式,0-选择其中较大的,1-选择合并
# 切换不同的类型(best_fields/most_fields),测试对比前后的分值与结果数量
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query": {
"multi_match": {
"query": "Cape Town International Airport",
"type": "best_fields",
"fields": [
"Origin",
"Dest"
]
}
}
}
# 还可以使用模糊匹配字段
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query": {
"multi_match": {
"query": "Cape Town International Airport",
"fields": "*rigin"
}
}
}
# 多个字段匹配,使用^符号和后面增加权重值数字,增加某个字段的权重,类同于单独写boost
GET kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query": {
"multi_match": {
"query": "Cape Town International Airport",
"type": "best_fields",
"fields": [
"Origin",
"Dest^2"
]
}
}
}
## Intervals文本顺序间隔,这个比较复杂一般用不上,需要深入研究
# 间隔查询是全文分词非常⾼级的查询能⼒,容许控制输入分词查询与内容之间的间隔。⽀持了多种间隔类型机制。
# 多个查询检索条件有先后,先基于第⼀个条件查询,之后在结果集上执⾏后⾯的查询条件,类似于 if,then 逻辑
## intervals match 间隔匹配查询
# match,关键字,间隔查询的全文分词⽅式,等同前⾯的match查询
# query,关键字,查询输入的内容
# max_gaps,关键字,容许中间间隔最⼤的词数量,默认-1,不限制
# ordered,关键字,查询的内容是否必须符合顺序,取值true/false,默认false
# analyzer,关键字,分词器
# filter,关键字,⼆级查询过滤器,⽀持多种过滤类型
# use_field,⾃定义字段类型,
## filter 参数说明,⼆级查询过滤器,⽀持多种过滤类型
# 类型 说明
# after query查询在此之后执⾏
# before query查询在此之前执⾏
# contained_by 包含此执⾏条件之内的结果
# containing 包含此执⾏条件
# not_contained_by 不在此执⾏结果之内
# not_containing 不包含此条件
# not_overlapping 不重叠条件
# overlapping 重叠条件
# script 基于painless脚本限制
POST kibana_sample_data_flights_fulltext/_search
{
"track_total_hits": true,
"query": {
"intervals": {
"Dest": {
"match": {
"ordered": true,
"query": "Sydney Smith Airport",
"analyzer": "standard",
"max_gaps": 2,
"filter": {
"containing": {
"match": {
"query": "International"
}
}
}
}
}
}
}
}
## Query String查询字符
# DSL查询比较复杂,ES也提供了类似SOL表达式的查询方式,但功能性上并未超越DSL,仅仅是方便
# 优缺点优点:简单直接
# 缺点:语法阅读困难,表达能力有限,建议尽量不使用
# 查询Dest,用or的方式
POST kibana_sample_data_flights_fulltext/_search
{
"query":{
"query_string": {
"query": "Dest:(Phoenix or Ministro)"
}
}
}
# 查询数字范围
POST kibana_sample_data_flights_fulltext/_search
{
"query":{
"query_string": {
"query": "FlightDelayMin:[10 TO 100]"
}
}
}
## Url查询字符
# 查询表达式基于URL的形式
## 优缺点
# 优点:简洁直接
# 缺点:表达能力局限,极少情况下应用,建议使用DSL
POST kibana_sample_data_flights_fulltext/_search?q=(Dest:Phoenix) AND (Origin:Chubu)
### 查询性能分析
## Profile性能分析
# 1.基于查询树,生成性能分析报告
# 2.与传统关系型数据库执行计划一样等价
# 3.Kibana具备可视化功能,看懂需要一定功力
POST kibana_sample_data_flights_fulltext/_search
{
"profile":true,
"query":{
"query_string": {
"query": "Dest:(Phoenix or Ministro)"
}
}
}
profile查询解结果如下
还可使用search profiler如下
## Explain分值计算评估,有兴趣可以深入
# 1.解释分值计算逻辑与规则
# 2.帮助理解全文查询分值计算信息
POST kibana_sample_data_flights_fulltext/_explain/74TR0Y8BbWz2Sn6EhZCn
{
"query":{
"match": {
"Dest": "Ministro Pistarini International Airport"
}
}
}
_explain结果如下,这是Dest字段ministro的分值计算
## 全文查询建议
# 全文文本查询是非精确查询(可以通过一些参数控制位精确查询)
# 查询关联度与分词算法(需要去了解,查询结果不是想要的并非是es错误)
# 查询精确度问题(近似值)
elasticsearch text 文本字段类型官⽅参考 https://www.elastic.co/guide/en/elasticsearch/reference/8.6/text.html
elasticsearch analysis-analyzers 内置分词器官⽅参考 https://www.elastic.co/guide/en/elasticsearch/reference/8.6/analysis-analyzers.html
elasticsearch full-text-queries 全文查询官⽅参考 https://www.elastic.co/guide/en/elasticsearch/reference/8.6/full-text-queries.html
elasticsearch query-dsl-intervals-query 间隔查询官⽅参考 https://www.elastic.co/guide/en/elasticsearch/reference/8.6/query-dsl-intervals-query.html
elasticsearch index-modules-similarity
elasticsearch similarity 相似度算法官⽅参考 https://www.elastic.co/guide/en/elasticsearch/reference/8.6/index-modules-similarity.html https://www.elastic.co/guide/en/elasticsearch/reference/8.6/similarity.html
原文地址:https://blog.csdn.net/DavidSoCool/article/details/144333197
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!