elasticsearch常用知识梳理

Elasticsearch

为了避免es升级导致数据(📁data)与日志的丢失(📁log),通常配置(config/elasticsearch.yml)数据与日志的存放位置非es程序存放位置

节点角色

  • master:候选节点(具有投票权)
  • data:数据节点
  • data_content:数据内容节点
  • data_hot:热节点
  • data_warm:索引不再定期更新,但仍可查询
  • data_code:冷节点,只读索引
  • Ingest:预处理节点,作用类似于Logstash中的Filter
  • ml:机器学习节点
  • remote_cluster_client:候选客户端节点
  • transform:转换节点
  • voting_only:仅投票节点(master主节点宕机后投票选举新的master)
  • 协调节点(每个节点默认都是)

分片

- 一个索引包含一个或多个分片,在7.0之前默认五个主分片,每个主分片一个副本;在7.0之后默认一个主分片。副本可以	在索引创建之后修改数量,但是主分片的数量一旦确定不可修改,只能创建索引

- 每个分片都是一个Lucene实例,有完整的创建索引和处理请求的能力

- ES会自动再nodes上做分片均衡

- 一个doc不可能同时存在于多个主分片中,但是当每个主分片的副本数量不为一时,可以同时存在于多个副本中

- 每个主分片和其副本分片不能同时存在于同一个节点上,所以最低的可用配置是两个节点互为主备(当某一节点宕机后,可保证数据的完整性)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-shiG1zSo-1656855298160)(/Users/armin/Desktop/截屏2022-06-23 下午10.01.18.png)]

主分片:存放原始数据,支持数据的读写

副本分片(具有数据的查询能力,副本本非越多越好):主分片的备份,不可进行数据的写入,仅可进行从主分片进行数据的同步;优点:提高数据的安全性、提高服务的可用性、提高并发查询的性能

在一个节点使用一台机器的情况下,每增加一台机器相当于可存放数据的扩容(横向扩容),且增加了副本提高了数据的高可用

集群

一个节点≠一台服务器(一台服务器可启动多个节点,生产环境中建议一台机器一个节点)

集群状态

健康状态

  • Green:所有Primary和Replica均为active,集群健康
  • Yellow:至少一个Replica不可用,但是所有Primary均为active,数据仍然是可以保证完整性的
  • Red:至少有一个Primary为不可用状态,数据不完整,集群不可用

健康检查

  • /_cat/health?v
  • _cluster/health

ES与关系型数据库的结构对比

索引库(indices)---------------------------------Databases 数据库

    类型(type)----------------------------------Table 数据表

        文档(Document)--------------------------Row 行

                字段(Field)---------------------Columns 列 

基于REST风格的API

1)创建索引:PUT /index?pretty			//pretty可有可无2)查询索引:GET _cat/indices?v
(3)删除索引:DELETE /index?pretty
(4)插入数据:
    PUT /index/_doc/id
    {
        Json数据
    }51) 全量替换	PUT
    2) 指定字段更新
        POST /product/_doc/1/_update
        {
          "doc":{
            "name":"iPad mini"	//修改的指定字段
          }
        }
        or
        POST /product/_update/1
        {
          "doc":{
            "name":"iPad mini"
          }
        }6)删除数据 DELETE /index/type/id

Mapping

数据类型

常见类型

1) 数字类型

​ long integer short byte double float half_float scaled_float unsigned_long

2) Keywords

keyword:适用于索引结构化的字段,可以用于过滤、排序、聚合。keyword类型的字段只能通过精确值(exact value)搜索到。Id应该用keyword

​ constant_keyword:始终包含相同值的关键字字段

​ wildcard:可针对类似grep的通配符查询优化日志行和类似的关键字值

​ 关键字字段通常用于排序汇总Term查询,例如term

3) Dates(时间类型):包括datedate_nanos

​ 4) alias:为现有字段定义别名。

​ 5) binary(二进制):binary

​ 6) range(区间类型):integer_range、float_range、long_range、double_range、date_range

​ 7) text:当一个字段是要被全文搜索的,比如Email内容、产品描述,这些字段应该使用text类型。设置text类型以后,字段内容会被分析,在生成倒排索引以前,字符串会被分析器分成一个一个词项。text类型的字段不用于排序,很少用于聚合。(解释一下为啥不会为text创建正排索引[用于聚合]:大量堆空间,尤其是在加载高基数text字段时。字段数据一旦加载到堆中,就在该段的生命周期内保持在那里。同样,加载字段数据是一个昂贵的过程,可能导致用户遇到延迟问题。这就是默认情况下禁用字段数据的原因)

② 对象关系类型:

1) object:用于单个JSON对象

2) nested:用于JSON对象数组

​ 3) flattened:允许将整个JSON对象索引为单个字段。

③ 结构化类型:

1) geo-point:纬度/经度积分

2) geo-shape:用于多边形等复杂形状

3) point:笛卡尔坐标点

2) shape:笛卡尔任意几何图形

​ ④ 特殊类型:

1) IP地址:ip 用于IPv4和IPv6地址

2) completion:提供自动完成建议

​ 3) tocken_count:计算字符串中令牌的数量

​ 4) murmur3:在索引时计算值的哈希并将其存储在索引中

​ 5) annotated-text:索引包含特殊标记的文本(通常用于标识命名实体)

​ 6) percolator:接受来自query-dsl的查询

​ 7) join:为同一索引内的文档定义父/子关系

​ 8) rank features:记录数字功能以提高查询时的点击率。

​ 9) dense vector:记录浮点值的密集向量。

​ 10) sparse vector:记录浮点值的稀疏向量。

​ 11) search-as-you-type:针对查询优化的文本字段,以实现按需输入的完成

​ 12) histogram:histogram 用于百分位数聚合的预聚合数值。

​ 13) constant keyword:keyword当所有文档都具有相同值时的情况的 专业化。

​ ⑤ array(数组):在Elasticsearch中,数组不需要专用的字段数据类型。默认情况下,任何字段都可以包含零个或多个值,但是,数组中的所有值都必须具有 相同的数据类型。

​ ⑥新增:

​ 1) date_nanos:date plus 纳秒

​ 2) features:

两种映射类型

查看映射GET /product/_mapping

{
  "product" : {
    "mappings" : {
      "properties" : {
        "name" : {
          "type" : "text",	//text用于分词模糊查询
          "fields" : {
            "keyword" : {
              "type" : "keyword",	//keyword用于精确查询,name.keyword
              "ignore_above" : 256 //name字段长度,超过256的部分自动丢弃
            }
          }
        }
      }
    }
  }
}

手动映射PUT /product

{
	"mappings": {
    "properties": {
    	"name": {		//name字段
      	"type": "text", //映射类型创建后无法修改,text不可修改为其他任意类型
        "analyzer":"standard"		//指定分词器,stadard为es默认分词器
	   	}
   	}
 	}
}

映射参数(部分

  • index:是否对创建对当前字段创建倒排索引,默认true,如果不创建索引,该字段不会通过索引被搜索到,但是仍然会在source元数据中展示

  • analyzer:指定分析器(character filtertokenizerToken filtersik[中文使用最多]

    • GET _analyze
      {
      	"analyzer": "standard",
      	"text": "xiaomi nfc phone"		//查询text文本使用standard分词器的分词结果
      }
      
  • doc_values:为了提升排序和聚合效率,默认true,如果确定不需要对字段进行排序或聚合,也不需要通过脚本访问字段值,则可以禁用doc值以节省磁盘空间(不支持textannotated_text

  • enable:是否创建倒排索引,可以对字段操作,也可以对索引操作,如果不创建索引,让然可以检索并在_source元数据中展示,谨慎使用,该状态无法修改

    • PUT my_index

    • {
        "mappings": {
        	"enabled": false
        }
      }
      
  • fielddata:查询时内存数据结构,在首次用当前字段聚合、排序或者在脚本中使用时,需要字段为fielddata数据结构,并且创建倒排索引保存到堆中(消耗JVM内存通常禁止使用

  • norms:是否禁用评分,不用做检索或评分应该置为false该字段会造成一定的性能下降,在filter和聚合字段上应该禁用

  • null_value:为null值设置默认值

  • search_analyzer:设置单独的查询时分析器

搜索查询(Query DSL

相关度评分:_score

概念:相关度评分用于对搜索结果排序,评分越高则认为其结果和搜索的预期值相关度越高,即越符合搜索预期值。在7.x之前相关度评分默认使用TF/IDF算法计算而来,7.x之后默认为BM25。在核心知识篇不必关心相关评分的具体原理,只需知晓其概念即可

排序:相关度评分为搜索结果的排序依据,默认情况下评分越高,则结果越靠前

元数据:_source

  1. 禁用_source

    1. 好处:节省存储开销

    2. 坏处:

      • 不支持update、update_by_query和reindex API。
      • 不支持高亮。
      • 不支持reindex、更改mapping分析器和版本升级。
      • 通过查看索引时使用的原始文档来调试查询或聚合的功能。
      • 将来有可能自动修复索引损坏。

      总结:如果只是为了节省磁盘,可以压缩索引比禁用_source更好。

  2. 数据源过滤器

    Including:结果中返回哪些field

    Excluding:结果中不要返回哪些field,不返回的field不代表不能通过该字段进行检索,因为元数据不存在不代表索引不存在

    1. 在mapping中定义过滤:支持通配符,但是这种方式不推荐,因为mapping不可变

      PUT product
      {
        "mappings": {
          "_source": {
            "includes": [
              "name",
              "price"
            ],
            "excludes": [
              "desc",
              "tags"
            ]
          }
        }
      }
      
    2. 常用过滤规则

      "_source": "false", 
      "_source": "obj.*", 
      "_source": [ "obj1.\*", "obj2.\*" ],
      "_source": {
        "includes": [ "obj1.\*", "obj2.\*" ],
        "excludes": [ "*.description" ]
      }
      

Query String

GET /product/_search?q=name:P50			#分词查询name包含P50的数据

GET /product/_search?q=P50 			#分词查询所有字段包含P50的数据,不支持分词的字段P50作为全匹配

全文检索

  • match:查询包含某个term(词)的数据

    GET product/_search
    {
    	"query": {
    		"match": {
    			"name": "xiaomi nfc phone"		//检索product索引中出现过:xiaomi、nfc、phone或组合词汇的所有数据,排序根据_score评分进行排序,匹配度越高评分越高,词频越高评分越高
    		}
    	}
    }
    
  • matc_all:查询所有,类似:GET product/_search

    GET product/_search
    {
    	"query": {
    		"match_all": {}
    	}
    }
    
  • multi_match:多字段查询条件

    GET product/_search
    {
    	"query": {
    		"multi_match": {
    			"query": "phone Inc",						//包含phone或Inc或phone Inc的数据
    			"fields": ["name", "company"]		//name、company字段包含以上数据
    		}
    	}
    }
    
  • match_phrase:短语查询

    GET product/_search
    {
    	"query": {
    		"match_phrase": {
    			"name": "xiaomi phone"		//检索name包含xiaomi phone的数据
    		}
    	}
    }
    

精准匹配

  • term

    GET product/_search
    {
    	"query": {
    		"term": {
    			"name": "xiaomi phone"		//检索name完全相等xiaomi phone的数据(xiaomi phone没有被分词或分词为完整的xiaomi phone则可检索出);name type=text【被分词】无法查询出该数据
    		}
    	}
    }
    
    • termmatch_phrase区别:

      match_phrase 会将检索关键词分词,match_phrase的分词结果必须在被检索字段的分词中都包含,而且顺序必须相同,而且默认必须都是连续的;term搜索不会将搜索词分词

    • termkeyword区别 :

      term是对于搜索词不分词,keyword是字段类型,是对于source data中的字段值不分词

      GET product/_search
      {
      	"query": {
      		"term": {
      			"name.keyword": "xiaomi phone"		//name type如为text类型,其子类型keyword type=keyword,则能将该全匹配的数据搜索出来
      		}
      	}
      }
      
  • terms:检索词项列表中任意项匹配的结果

    GET product/_search
    {
    	"query": {
    		"terms": {
    			"tags": ["lowbee", "gongjiaoka"] 		//检索tags字段包含lowbee或者gongjiaka
    		}
    	}
    }
    
  • range:范围查找

    GET product/_search
    {
    	"query": {
    		"range": {
    			"price": {
    				"gte": 10,
    				"lte": 20					//检索price>=10 && price<=20的数据
    			}
    		}
    	}
    }
    
    GET product/_search
    {
    	"query": {
    		"range": {
    			"date": {
            "time_zone": "+08:00",  //结果date时区加8个小时如:2022-06-26T00:00:00 -> 2022-06-26T08:00:00
    				"gte": "now-1d/d",			//date>=yesterday
    				"lte": "now/d"					//date<=tody
    			}
    		}
    	}
    }
    

过滤器(filter

用于先将结果筛选出来再进行排序等处理

query/filter区别filter是结果导向的而query是过程导向;query倾向于当前文档和查询的语句的相关度filter倾向于当前文档和查询的条件是不是相符;即在查询过程中,query是要对查询的每个结果计算相关性得分的,而filter不会;另外filter有相应的缓存机制,可以提高查询效率

GET /product/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "name": "phone"			//检索评分相同的name包含phone分词的数据
        }
      }
    }
  }
}

组合查询(Bool Query

bool:可以组合多个查询条件,bool查询也是采用more_matches_is_better的机制,因此满足must和should子句的文档将会合并起来计算分值

  • must:必须满足子句(查询)必须出现在匹配的文档中,并将有助于得分。
  • filter:过滤器 不计算相关度分数,cache☆子句(查询)必须出现在匹配的文档中。但是不像 must查询的分数将被忽略。Filter子句在filter上下文中执行,这意味着计分被忽略,并且子句被考虑用于缓存。
  • should:可能满足 or子句(0个或多个条件)应出现在匹配的文档中。
  • must_not:必须不满足 不计算相关度分数 not子句(查询)不得出现在匹配的文档中。子句在过滤器上下文中执行,这意味着计分被忽略,并且子句被视为用于缓存。由于忽略计分,0因此将返回所有文档的分数。
GET population/_search
{
	"query": {
		"bool": {
			"filter": [
				"range": {
					"age": {
						"lte": 17						//首先从人口索引中过滤到非未成年人
					}
				}
			],
			"must": [
				{
					"match": {
						"name": "王五"			//再从过滤后的人口中匹配 name包含王五 的人
					}
				}
			]
		}
	}
}
//该查询优化了查询,假设人口索引共14亿条,先更具年龄过滤(可以提交查询效率)去除成年人,再从未成年中找到王五

minimum_should_match:参数指定should返回的文档必须匹配的子句的数量或百分比。如果bool查询包含至少一个should子句,而没有must或 filter子句,则默认值为1。否则,默认值为0

GET product/_search
{
  "_source": false,
  "query": {
    "bool": {
      "filter": [
        {
          "range": {
            "price": {
              "lte": "10000"
            }
          }
        }
      ],
      "should": [
        {
          "match_phrase": {
            "name": "nfc phone"
          }
        },
        {
          "match": {
            "name": "erji"
          }
        },
        {
          "bool": {
            "must": [
              {
                "range": {
                  "price": {
                    "gte": 900,
                    "lte": 3000
                  }
                }
              }
            ]
          }
        }
      ],
      "minimum_should_match": 2			//filter过滤后should条件中的条件,至少需要满足两个条件
    }
  }
}

聚合查询(Aggregations

持续更新中…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值