0
点赞
收藏
分享

微信扫一扫

windows nvm 安装过程

文章目录

一、环境准备

1. ES安装

建议直接用docker。

# 安装ElasticSearch
docker pull elasticsearch:7.17.6

# 安装Kibana
docker pull kibana:7.17.6

# 查看已安装镜像
docker images
REPOSITORY              TAG              IMAGE ID       CREATED         SIZE
elasticsearch           7.17.6           5fad10241ffd   2 months ago    606MB
kibana                  7.17.6           4239c3f5bd3d   2 months ago    799MB


# 启动ElasticSearch
docker run  -d -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" --name MyEs7   5fad10241ffd   
# 启动Kibana
docker run -d -p 5601:5601 --name kb7 --link MyEs7:elasticsearch 4239c3f5bd3d



# 查看容器启动状态
docker ps

# 浏览器访问Kibana
http://localhost:5601/

# 如果用Chrome的ElasitcSearch Head 插件,则直接访问访问 ES地址
http://localhost:9200/

docker启动参数说明:

  • -d 后台启动
  • -p 9200:9200 将虚拟机9200端口映射到elasticsearch的9200端口(web通信默认使用9200端口)
  • -p 9300:9300 将虚拟机9300端口映射到elasticsearch的9300端口(分布式情况下,各个节点之间通信默认使用9300端口)
  • –name MyEs7 指定一个名字(MyEs 随意指定)

可用 ElasticSearch Head替代kibana:
不用kibana的话,也可以在chrome浏览器的插件中搜索 ElasticSearch Head安装。

二、基本概念

2.1 节点(Node)

一个 ES 节点就是一个运行的 ES 实例,可以实现数据存储并且搜索的功能。每个节点都有一个唯一的名称作为身份标识,如果没有设置名称,默认使用 UUID 作为名称。最好给每个节点都定义上有意义的名称,在集群中区分出各个节点。节点通过为其配置的ES集群名称确定其所要加入的集群。

一个机器可以有多个实例(这种情况,机器的cpu core怎么分配给每个实例使用可通过参数配置,默认是每个实例线程池共用机器资源),所以并不能说一台机器就是一个 node,大多数情况下每个 node 运行在一个独立的环境或虚拟机上

节点有以下几种类型:

Master-eligible nodes与 Master node

每个节点启动后,默认就是一个Master eligible节点,可以通过设置node.master:false来改变,Master-eligible节点可以参加选主流程,成为Master节点,每个节点都保存了集群的状态,但只有Master节点才能修改集群的状态信息,主节点主要负责集群方面的轻量级的动作,比如:创建或删除索引,跟踪集群中的节点,决定分片分配到哪一个节点,在集群再平衡的过程中,如何在节点间移动数据等。

Data Node

可以保存数据的节点,叫做Data Node。负责保存分片数据。在数据扩展上起到了至关重要的作用,每个节点启动后,默认就是一个Data Node节点,可以通过设置node.data:false来改变。

Ingest Node

可以在文档建立索引之前设置一些ingest pipeline的预处理逻辑,来丰富和转换文档。每个节点默认启动就是Ingest Node,可用通过node.ingest:false来禁用。

Coordinating Node

Coordinating Node负责接收Client的请求,将请求分发到合适的节点,最终把结果汇集到一起,每个节点默认都起到了 Coordinating Node的职责,当然如果把Master、Data、Ingest全部禁用,那这个节点就仅是Coordinating Node节点了。

Machine Learning Node

用于机器学习处理的节点。

2.2 集群(cluster)

ES可以作为一个独立的单个搜索服务器。不过,一般为了处理大型数据集,实现容错和高可用性,ES可以运行在许多互相合作的服务器上。这些服务器的集合称为集群。

2.3 分片(Shard)

ES的“分片(shard)”机制可将一个索引内部的数据分布地存储于多个节点,它通过将一个索引切分为多个底层物理的Lucene索引完成索引数据的分割存储功能,这每一个物理的Lucene索引称为一个分片(shard)。

一个ES的index由多个shard组成,每个shard承载index的一部分数据。

这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。降低单服务器的压力,构成分布式搜索,提高整体检索的效率(分片数的最优值与硬件参数和数据量大小有关)。分片的数量只能在索引创建前指定,并且索引创建后不能更改。

在搜索时,每个分片都需要搜索一次, 然后 ES 会合并来自所有分片的结果。例如,你要搜索 10 个 index,每个 index 有 5 个分片,那么协调这次搜索的节点就需要合并 5×10=50 个分片的结果。这也是一个你需要注意的地方:如果有太多分片的结果需要合并,或者你发起了一个结果巨大的搜索请求,合并任务会需要大量 CPU 和内存资源。这是第二个让 index 少一些的理由。

2.4 副本(Replica)

副本是一个分片的精确复制,每个分片可以有零个或多个副本。副本的作用:
一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。
二是提高es的查询效率,es会自动对搜索请求进行负载均衡。对于查询压力较大的index,可以考虑提高副本数(number_of_replicas),通过多个副本均摊查询压力

  • 一个索引包含一个或多个分片,7.0版本之后默认1个主分片(之前是默认5个),副本可以在索引创建之后修改数量,但主分片数量一旦确定不可修改,只能创建索引
  • 每个分片都是一个Lucene实例,有完整的创建索引和处理请求的能力
  • ES会自动在nodes上做分片均衡【当我们添加了新的副本文件,会将每个节点数据尽量均匀分配,提高每个节点性能】
  • 一个doc不可能同时存在多个主分片中,但每个主分片的副本数量不为一时,可以同时存在多个副本中
  • 每个主分片及其副本分片不能同时存在于同一个节点上,最低的可用配置是两个节点互为主备

2.5 分片和副本数选择

shard数量(number_of_shards)设置过多或过低都会引发一些问题:shard数量过多,则批量写入/查询请求被分割为过多的子写入/查询,导致该index的写入、查询拒绝率上升;对于数据量较大的inex,当其shard数量过小时,无法充分利用节点资源,造成机器资源利用率不高 或 不均衡,影响写入/查询的效率。

对于每个index的shard数量,可以根据数据总量、写入压力、节点数量等综合考量后设定,然后根据数据增长状态定期检测下shard数量是否合理。腾讯云CES技术团队的推荐方案是:

  • 对于数据量较小(100GB以下)的index,往往写入压力查询压力相对较低,一般设置3~5个shard,number_of_replicas设置为1即可(也就是一主一从,共两副本) 。
  • 对于数据量较大(100GB以上)的index: 一般把单个shard的数据量控制在(20GB~50GB) 让index压力分摊至多个节点:可通过index.routing.allocation.total_shards_per_node参数,强制限定一个节点上该index的shard数量,让shard尽量分配到不同节点上 综合考虑整个index的shard数量,如果shard数量(不包括副本)超过50个,就很可能引发拒绝率上升的问题,此时可考虑把该index拆分为多个独立的index,分摊数据量,同时配合routing使用,降低每个查询需要访问的shard数量。

2.6 ES的数据架构

1)索引(index)

ES将数据存储于一个或多个索引中,索引是具有类似特性的文档的集合。类比传统的关系型数据库领域来说,索引相当于SQL中的一个数据库。

一个ES集群中可以按需创建任意数目的索引,但根据不同的硬件配置,索引数有一个建议范围(这个知识点我们以后进行详细讲解)。

2)类型(Type)

类型是索引内部的逻辑分区(category/partition),一般来说,类型就是为那些拥有相同的域的文档做的预定义。类比传统的关系型数据库领域来说,类型相当于“表”。

使用 type 允许我们在一个 index 里存储多种类型的数据,这样就可以减少 index 的数量了。在使用时,向每个文档加入 _type 字段,在指定 type 搜索时就会被用于过滤。使用 type 的一个好处是,搜索一个 index 下的多个 type,和只搜索一个 type 相比没有额外的开销 —— 需要合并结果的分片数量是一样的。

特别注意:
6.x版本:Removal of types,在 6.0 里面,开始不支持一个 index 里面存在多个 type
7.x版本: 正式废除单个索引下多 Type 的支持(只有_doc这一个默认type

3)文档(Document)

文档是Lucene索引和搜索的原子单位,它是包含了一个或多个域的容器,基于JSON格式进行表示。文档由一个或多个域组成,每个域拥有一个名字及一个或多个值,有多个值的域通常称为“多值域”。每个文档可以存储不同的域集,但同一类型下的文档至应该有某种程度上的相似之处。相当于mysql表中的row。

文档的原始信息都存放在_source字段中,获取文档信息:

GET es_test/_doc/1 #获取文档_source和metadata
GET es_test/_source/1 #仅获取_source
GET es_test/_doc/2?_source_include=title,content # 获取metadata和指定_source字段信息,7.x以上用_source_includes,多个s
GET es_test/_source/2?_source_include=title,author # 获取指定_source字段信息,7.x以上用_source_includes,多个s
GET es_test/_doc/1?stored_fields=title,content # 获取stored字段信息
# 获取多个_id文档
GET es_test/_search
{
  "query": {
    "ids": {
      "values": [1,2,3]
      # "_source": false  #可关闭获取_source内容,只返回meta内容
    }
  }
}

4)映射(Mapping)

映射是定义文档及其包含的字段如何存储和索引的过程。

PUT /es_test?pretty
{
  "settings": {
    "index": {
      "number_of_shards": 1,
      "number_of_replicas": 0 
    }
  },
  "mappings": {
    "_doc": { 
      "dynamic": true,
      "properties": {
        "id": {
          "type": "integer"  
        },
        "title": {
          "type": "text"
        },
        "content": {
          "type": "text"
        },
        "tags": {
          "type": "keyword"
        }
      }
    }
  }
}

在这里插入图片描述

三、数据类型

到8.x版本,es支持的数据类型已有29种,可查阅官方文档:数据类型。本章节介绍一下核心数据类型(core-data types)。

核心数据类型:

  • String 类型
    • text
    • token_count
    • keyword
    • constant_keyword
    • wildcard
  • 数值类型
    • 整型
      • float
      • double
      • half_float
      • scaled_float
    • 浮点型
      • byte
      • short
      • integer
      • long
      • unsigned_long
  • 时间类型
    • date
  • 复杂类型
    • (array)
    • object
    • flattend
    • nested
    • join
  • 特定类型
    • GEO地理类
      • geo_point
      • geo_shape
      • point
      • shape
  • 文档排序类
    • dense_vector
    • rank_feature
    • rank_features

3.1 关于settings和mapping

一个索引的schema和特征是通过settings以及mapping设定的,在第二章已经见过。

# 定义es_test的相信息
PUT es_test
{
  "settings": {
    ...
  },
  "mappings": {
    "_doc": {
      "properties": {
        ... #指定字段名和类型
      }
    }
  }
}

3.1.1 动态mapping(Dynamic Mapping)

更详细的可参考:Elasticsearch - mappings之dynamic的三种状态
es自动生成字段和类型的方式,两种情况:

  1. 未定义mapping,就创建索引
  2. 定义了mapping,未包含新字段,增加新字段。

ES自动推断类型的规则:

3.1.2 显示mapping(Explicit Mapping)

ES提供两种用于maping的操作:

  1. PUT index 创建阶段,提供全量字段信息。
  2. PUT index/_mapping ,使用阶段,可add新字段,仅需提供add部分字段信息即可。注意,不可以修改已定义字段类型。

若想修改字段类型,可用re_index,先定义好新索引各字段类型,创建新索引。将旧索引copy过去。

POST _reindex
{
	"source": {"index": "orders"},
	"dest": {"index": "orders_new"}
}

3.1.3 自动类型转换(type coercion)

当定义的类型和输入的类型不一致时,es能自动做类型转换,当转换不了时,数据不能写入。例如:

"age":{"type":"short"}

PUT cars/_doc/1
{
"age":"23" # 字符串"23"自动转换成 23,如果是"age":"st" 则无法转换,该条数据不能插入,并给出错误提示
}

搜索时,同样会发生这种转换。

比较特别的:当boolean类型提供空字符串时,会转换成false"blockbuster":""

3.2 关于分词

Analysis:即文本分析,是把全文本转化为一系列单词(term/token)的过程,也叫分词;在Elasticsearch 中可通过内置分词器实现分词,也可以按需定制分词器。为了和tokenizer分词器区分开来,本文把Analyzer 叫分析器。

分词内容
不分词(Before Tokenization)Covid changed our lives. It changed the way we work.
分词后(After Tokenization)[Covid,changed,our,lives,it,changed,the,way,we,work]

3.2.1 Analyzer 由三部分组成

  • Character Filters:原始文本处理,如去除 html
  • Tokenizer:按照规则切分为单词
  • Token Filters:对切分单词加工、转换大小写、删除 stopwords,增加同义词

官方介绍:
1)字符过滤器 character filter

首先,字符串按顺序通过每个字符过滤器 。他们的任务是在分词前整理字符串。一个字符过滤器可以用来去掉HTML,或者将 & 转化成 and。

2)分词器 tokenizer
其次,字符串被 分词器 分为单个的词条。一个 whitespace的分词器遇到空格和标点的时候,可能会将文本拆分成词条。

3)词条过滤器token filter

最后,词条按顺序通过每个 token 过滤器 。这个过程可能会改变词条,例如,lowercase token filter 小写化(将ES转为es)、stop token filter 删除词条(例如, 像 a, and, the 等无用词),或者synonym token filter 增加词条(例如,像 jump 和 leap 这种同义词)。

默认分析器为标准分析器。由以下三个部分组成:(注意:带有lowercase),所以用term语法去搜标准分析器分词的字段时注意先人工转成小写,用match语法搜则不用担心,因为match会先经过同样的分析器,再搜索。

在这里插入图片描述

扩展:三部分可选参数列表

3.2.2 自定义分析器

#1、定义名为“custom_analyzer”的自定义分析器:大写转为小写
PUT es_test
{
  "settings": {
    "analysis": {
      "analyzer": {
        "custom_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase"
          ]
        }
      }
    }
  },
# 2、该字段my_text使用custom_analyzer分析器
  "mappings": {
    "_doc": {
      "properties": {
        "my_text": {
          "type": "text",
          "analyzer": "custom_analyzer"
        }
      }
    }
  }
}

3.2.4 分析器

分析器使用的三个情形:
1,Index time analysis. 创建或者更新文档时,会对文档进行分词
2,Search time analysis. 查询时,对查询语句分词
3, _analyze接口

ES内置了很多Analyzer, 还有很多第三方的Analyzer插件, 比如一些处理中文的Analyzer(中文分词)。

analyzer、 tokenizer、 filter可以在elasticsearch.yml 配置。
场景分析器:

analyzerlogical namedescription
standard analyzerstandardstandard tokenizer, standard filter, lower case filter, stop filter
simple analyzersimplelower case tokenizer
stop analyzerstoplower case tokenizer, stop filter
keyword analyzerkeyword不分词,内容整体作为一个token(not_analyzed)
pattern analyzerwhitespace正则表达式分词,默认匹配\W+
language analyzerslang各种语言
snowball analyzersnowballstandard tokenizer, standard filter, lower case filter, stop filter, snowball filter
custom analyzercustom一个Tokenizer, 零个或多个Token Filter, 零个或多个Char Filter
  • 查询时通过analyzer指定分析器
POST test_index/_search
{
  "query": {
    "match": {
      "name": {
        "query": "lin",
        "analyzer": "standard"
      }
    }
  }
}
  • 创建index mapping时指定search_analyzer
PUT test_index
{
  "mappings": {
    "doc": {
      "properties": {
        "title":{
          "type": "text",
          "analyzer": "whitespace", # 指定生成倒排索引的分析器
          "search_analyzer": "standard"  # 指定搜索该字段的分析器
        }
      }
    }
  }
}

索引时分词是通过配置 Index mapping中的每个字段的参数analyzer指定的。

ES使用分析器的顺序

ElasticSearch确定生成索引时的 analyzer:
1)读取字段的“analyzer”配置
2)上述步骤没有,再读取index的setting:analysis.analyzer.default
3)都没有,使用默认的 standard 标准分析器

# 1)读取字段的“analyzer”配置
PUT my_index
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "whitespace"
      }
    }
  }
}

# 2)上述步骤没有,再读取index的setting:analysis.analyzer.default
PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "default": {
          "type": "english"
        }
      }
    }
  }
}

ElasticSearch确定搜索时的 search_analyzer:
1)search API 指定 analyzer
2)读取 index 的 mapping 字段配置 search_analyzer
3)读取 index 的 setting 的 analysis.analyzer.default_search
4)field 的 analyzer
5)都没有,使用默认的 standard analyzer

# 1) search API 指定 analyzer
GET my_index/_search
{
  "query": {
    "match": {
      "message": {
        "query": "Quick foxes",
        "analyzer": "stop"
      }
    }
  }
}
# 2) 读取 index 的 mapping 字段配置 search_analyzer
PUT my_index
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "whitespace",
        "search_analyzer": "simple"
      }
    }
  }
}
# 3) 读取 index 的 setting 的 analysis.analyzer.default_search
PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "default": {
          "type": "simple"
        },
        "default_search": {
          "type": "whitespace"
        }
      }
    }
  }
}

3.2.5 粗粒度和细粒度分词

中文分析器有粗粒度和细粒度分析器,以ik分析器为例:

分析器说明语句分词适用场景
ik_max_word细颗粒度分词关注我系统学习ES[关注,我,系统学,系统,学习,es]穷尽所有分词可能,适合 Term 查询
ik_smart粗粒度分词关注我系统学习ES[关注,我,系统,学习,es]适合 Phrase 查询

3.2.6 关于normalizer

需要分词的字符串通常是text类型。而es中还有一种不需要分词的string类型,叫做keyword。keyword类型的整个句子可以类似于text类型分词后的一个词条。
对于keyword的处理,通常是定义normalizer,这是专门为keyword类型存在的。他和text类型的analyzer的区别是,没有tokenizer这一步:

  • Character Filters:原始文本处理,如去除 html
  • Token Filters:对切分单词加工、小写、删除 stopwords,增加同义词
PUT es_test
{
  "settings": {
    "analysis": {
      "normalizer": {
        "my_normalizer": {
          "type": "custom",
          "char_filter": [],
          "filter": ["lowercase", "asciifolding"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "foo": {
        "type": "keyword",
        "normalizer": "my_normalizer"
      }
    }
  }
}

3.3 倒排索引

倒排索引是 Elasticsearch 中非常重要的索引结构,是从文档单词到文档 ID 的映射过程。

假设有两篇文章:
在这里插入图片描述
倒排索引就是建立词和文章id间的关系,通过词能够找到文章。简单例子如下:
在这里插入图片描述

倒排序索引包含两个部分:

  • 单词词典:记录所有文档单词,记录单词到倒排列表的关联关系

  • 倒排列表:记录单词与对应文档结合,由倒排索引项组成

倒排索引项:

  • 文档

  • 词频 TF - 单词在文档中出现的次数,用于相关性评分

  • 位置(Position)- 单词在文档中分词的位置,用于phrase query

  • 偏移(Offset)- 记录单词开始结束的位置,实现高亮显示

以 Token“学习”为例(这才是全部的倒排索引信息):
在这里插入图片描述

3.4 String 类型

1)text——会分词

我们不去特殊定义它的分析器,那么ES就会使用默认的分析器 standard。调用分析器分析的命令:

GET /_analyze
{
  "text": ["my name is A"],
  "analyzer": "standard" #   "analyzer": "keyword"  则返回不分词结果
}

2) token_count——记录分词数

可记录filed分词后长度。

PUT tech_books
{
  "mappings": {
    "properties": {
      "title": { # 父field
        "type": "text",
        "fields": { 
          "word_count": {  # 通常放到下一层,用子field来记录
            "type": "token_count",
            "analyzer": "standard"
          }
        }
      }
    }
  }
}

GET tech_books/_search
{
  "query": {
    "term": {  
     "title.word_count": { # <outer_field>.<inner_field> 的方式获取
        "value": 4
      }
    }
  }
}

3)keyword——不会分词

term查询是查不分词结果

4)constant_keyword

当某个字段需要用一个不变的keyword的时候。

PUT census 
{
  "mappings": {
    "properties": {
      "country":{
        "type": "constant_keyword",
        "value":"United Kingdom" #该索引country字段都为United Kingdom
      }
    }
  }
}

5) wildcard

wildcard也是keyword家族的。在mapping定义时指定为wildcard type则可在搜索时,对该字段进行wildcard搜索。

GET errors/_search
{
  "query": {
    "wildcard": {
      "description": {
        "value": "*obj*" 
      }
    }
  }
}

3.5 数值类型

主要是注意各类型的范围。

3.6 date 时间类型

date类型允许我们规定格式,如果不指定格式,储存的格式,ES是可以自动控制的(但仅限于三种)。
注意:一旦我们自行规定了格式,如果新增数据不符合这个格式,ES将会报错mapper_parsing_exception。
可以使用的格式有:

yyyy-MM-dd HH:mm:ss
yyyy-MM-dd
epoch_millis(时间戳-毫秒)
epoch_second(时间戳-秒)


# 规定格式如下:|| 表示或者
PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "date": {
          "type":   "date",
          "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis|dd-MM-yy||dd/MM/yyyy|||yyyy/MM/dd"  # 支持用yyyy,MM,dd, HH,mm ss自定义
        }
      }
    }
  }
}

3.7 复杂类型

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

# 创建索引
PUT /toherotest
{
  "mappings": {
    "_doc":{
      "properties" : {
                "field1" : { "type" : "text" }
            }
    }
  }
}
# 存入数据
POST /toherotest/_doc/1
{
  "field1":"中国我爱你"  
}


# 新增数据-array
POST /toherotest/_doc/2
{
  "field1":["这是","一个","数组"] #注意,直接用的是field1
}

2)object就是一个json提;需要注意的是,object类型的字段,也可以有多个值,形成Array<object>的数据结构。

重点:Array<object>中的object不允许彼此独立地索引查询。这是什么意思呢?举个简单例子:我们现在有2条数据:数据结构都是一个Array<object>

第一条数据:[ { "name":"tohero1", "age":1 }, { "name":"tohero2", "age":2 } ]

第二条数据:[ { "name":"tohero1", "age":2 }, { "name":"tohero2", "age":1 } ]

如果此时我们的需求是,只要 name = “tohero1”and “age”= 1 的数据,但没法查,两条数据都会查出来。怎么实现?用nessted类型。

3)nested 类型
需要建立对象数组的索引并保持数组中每个对象的独立性,则应使用nested数据类型而不是 object数据类型。在内部,嵌套对象索引阵列作为一个单独的隐藏文档中的每个对象,这意味着每个嵌套的对象可以被独立的查询。

三、GEO 地理位置类型

对于 GEO 地理位置类型,分为 地图:Geo-point 和 形状 :Geo-shape,两种数据类型。
对于web开发,一般常用的是 地图类型 Geo-point。
知道如何定义,如何查询即可

四、查询(queries)

查询方式有两种:

  1. 基于URI请求的查询,如:GET movies/_search?q=title:Godfather可获取索引movies中title匹配Godfather 的文档。
  2. 基于query-DSL的查询:domain-specific language(DSL)在ES中是基于json结构体的,示例如下:
GET movies/_search
{
	"query": {
		"match": {
			"title": "Godfather"
		}
	}
}

实际应用中,DSL是主流。

GET|POST <your_index_name>/_search?q=<name:value> AND|OR <name:value>


GET movies/_search?q=title:Godfather Knight Shawshank # 支持value包含多个值
GET movies/_search?q=title:Knight AND actors:Bale # AND语句使用
GET movies/_search?q=title:Godfather actors:Bale # 默认为OR
GET movies/_search?q=title:Godfather actors:Bale&default_operator=AND #修改默认
GET movies/_search?q=title:Godfather actors:(Brando OR Pacino) rating:(>=9.0 AND <=9.5)&from=0&size=10&explain=true&sort=rating&default_operator=AND # 更多参数

#DSL在curl中的使用
curl -XGET "http://localhost:9200/movies/_search" -H 'Content-Type: application/json' -d'
{
	"query": {
		"multi_match": {
			"query": "Lord",
			"fields": ["synopsis","title"]
			}
	}
}'

查询的两种内部结构(context)
ES将所有查询自动分为两类:

  1. query context:会计算相关分,返回结果会返回这个分数。
  2. filter context:不计算相关分,返回结果中没有相关分,可大幅提高搜索效率。三种情况放在filter context中执行:
    • bool 的filter语句
    • bool 的must_not语句
    • contant_score 的filter语句

常用查询参数
查询蚕食是指和query同级的参数:
size:每页获取的文档数量,默认10000,受_settings中的max_result_window参数控制。
from:起始页数,默认0
highlight:高亮匹配到的字段
explain:见常用接口章节的"_explain"接口
sort:排序依据,不指定的话,按相关性分数"_score"排
_source:是否打印_source字段,见接口章节
fields:"_source"为false时,打印_source中指定字段。
scirpt_fields:自定义的脚本字段
indices_boost:调整夸索引搜索时,不同索引的权重

GET movies*/_search
{
	"query": { ... },
	"size":10,
	"from":3,# 跳过前2页,即跳过了2*10个结果
	"highlight": {
		"fields": {
			"field1": {}, #指定要高亮的字段
			"field2": {}
		},
		"pre_tags": "符号1", #自定义高亮标识符 默认是"<em>"
		"post_tags": "符号2",#自定义高亮标识符  默认是"</em>"
	},
	"sort": [
		{ "field1" :{ "order": "desc" } }, #注意field也可以是metadata中字段,如_score
		{ "field2" :{ "order": "desc" } } # 多个字段是,当filed1一样时,才按field2排序
	],
	"_source": ["title*","synopsis", "rating"], # 注意字段名可通配符匹配
	 "script_fields": {
		"top_rated_movie": {
			"script": {
			"lang": "painless",
			"source": "if (doc['rating'].value > 9.0) 'true'; else 'false'"
			}
		}
	},# 返回结果中会显示"top_rated_movie":“true”
	"indices_boost": [
		{ "movies": 0.1},
		{ "movies_new": 0}, 
		{ "movies_top": 2.0} 
	]
}

索引名和字段名都支持通配符匹配,通配符会匹配到子字段,如title*会匹配到titletitle.original

查询可分为三类:

  • term-level queries
  • full-text queries
  • compound queries

es的数据分为结构化数据(structured data(non-text data))和非结构化数据(unstructured data (fulltext-data))。
Numbers, dates, range, IP等都是结构化数据。
term-level queries专门用于结构化数据查询。
非结构化数据 (fulltext)的查询和索引都可经过analyzer。

4.1 term-level 查询

term-level 查询的查询是不关心query和内容的相关程度的,所以term-level 查询不关注相关性分。注意:term-level 查询也会返回分数,但Y有些分数是没有什么意义的。最好用explain查看一下打分的原因,比如term就会打bm25分,还是又用的,而terms就是给个常量1分。

term-level 查询不进行分词分析。

term-level 查询包括:
non-expensive: term, terms, ids, exists
expensive: wildcard, range, prefix,fuzzy, regex,join queries, others

expensive是指比较费性能,耗时会较长的查询。可通过控制集群参数来关闭enpensive查询权限。

PUT _cluster/settings
{
	"transient": {
		"search.allow_expensive_queries": "false"
	}
}

4.1.1 term


# 缩写版
GET movies/_search
{
  "query": {
    "term": {
      "title": "The Godfather"  # 不适合搜索text类型字段
    }
  }
}
# 展开版
GET movies/_search
{
	"query": {
		"term": {
			"title": {
				"value": "The Godfather",
				"boost": 2 #支持boost参数
			}
		}
	}
}

4.1.2 terms

# Terms query
GET movies/_search
{
  "query": {
    "terms": { 
      "certificate": ["PG-13","R"]
    }
  }
}

terms的数组里最多可写的字段受index.max_terms_count参数控制,默认65,536个。

PUT movies/_settings
{
  "index":{
    "max_terms_count":10
  }
}

terms有一个变种查询,可利用其他文档自身相关信息,作为查询term。

GET movies/_search
{
  "query": {
    "terms": {
      "director": {
        "index":"famouse_person", # 指定索引下
        "country":"en", # 指定所有country字段位en的文档
        "path":"name" # 字段name的值,组成terms在director中查询
      }
    }
  }
}

4.1.3 ids

批量查询_id字段的语句。

GET movies/_search
{
  "query": {
    "ids": {
      "values": [10,4,6,8]
    }
  }
}

4.1.4 exists

返回字段存在的文档。如果想获取不存在的文档,则需要用bool语句的must_not+exists。

GET movies/_search
{
  "query": {
    "exists": {
      "field": "title"
    }
  }
}

4.1.5 range

对于 date和数值类型数据,取范围。支持lt,gt,lte,gte

GET movies/_search
{
  "query": {
    "range": {
      "rating": {
        "gte": 9.0,
        "lte": 9.5
      }
    }
  }
}

对于date类型字段,ES还支持一定的数学计算:
now 表示当前时间
y for years
M for moths
w for weeks
d for days
h for hours
m for minutes
s for seconds

# Range query with date math
GET movies/_search
{
  "query": {
    "range": {
      "release_date": {
        "lte": "15-02-1995||+2d" # +表示未来,-表示过去
      }
    }
  }
}
# Range query with date match using now 
GET movies/_search
{
  "query": {
    "range": {
      "release_date": {
        "lte": "now+1y"  
      }
    }
  }
}

4.1.6 wildcard

可理解成term的通配符模式。
*:匹配0或多个任意字符
?:匹配1个任意字符

GET movies/_search
{
  "query": {
    "wildcard": { 
      "title": {
        "value": "god*"
      }
    }
  }
}

4.1.7 prefix

前缀匹配查询

GET movies/_search
{
  "query": {
    "prefix": {
      "genre.original": {
        "value": "Ad"
      }
    }
  }
}

ES会根据前缀去派生查询,所以这个速度是比较慢的。可以再创建索引时,指定index_prefixes参数来预先生成前缀,加速匹配。

PUT boxoffice_hit_movies_custom_prefix_sizes
{
  "mappings": {
    "properties": {
      "title":{
        "type": "text",
        "index_prefixes":{
          "min_chars":4, #默认2
          "max_chars":10  #默认5
        }
      }
    }
  }
}

4.1.8 fuzzy

用于拼写错误的查询。fuzziness参数表示编辑距离。增、删、改都算1个编辑距离。fuzziness设置的话默认是AUTO:

查询字段长度fuzziness (编辑距离)说明
0-20若长度小于等于2,则编辑距离为0,fuzzy相当于不启用
3-51
>52
GET movies/_search
{
  "query": {
    "fuzzy": {
      "genre": {
        "value": "drma",
        "fuzziness": 1
      }
    }
  }
}

4.2 full-text 查询

match_all,match,match_phrase

4.2.1 match_all

相关分1.0。返回索引所有文档

GET books/_search
{
  "query": {
    "match_all": {}
  }
}

4.2.2 match

语法:

# 简化版
GET books/_search
{
	"query": {
		"match": { #A
			"FIELD": "SEARCH TEXT" #B
		}
	}
}
# 展开版
GET books/_search
{
	"query": {
		"match": {
			"FIELD": { #A
				"query":"<SEARCH TEXT>", #B
				"<parameter>":"<MY_PARAM>", #C
			}
		}
	}
}

SEARCH TEXT会先经过分词。分词后的term,和FIELD匹配默认是 “OR”关系,匹配得越多,相关分数越高。
parameter支持:官方文档看全部参数
operator:AND 或 OR,分词后的term匹配需满足的关系。AND表示必须都匹配。
minimum_should_match:至少匹配几个term,operator为OR时才有效。支持带符号数值(如3,-2)和带符号百分比(20%,-20%),以及它们的组合(2<80%,2<-20%)。百分比时需匹配的term个数为总数*百分比向下取整。2<80%含义为当term总数<=2个时,需全部匹配;当>2个时,需至少匹配总数*百分比向下取整个。
fuzziness:和fuzzy中的参数使用方式一样。
analyzer:指定搜索时的分析器。
lenient:忽略数据类型转换异常
auto_generate_synonyms_phrase_query:是否开启同义词增强功能,默认为true。

GET books/_search
{
  "query": {
    "match": {
      "title": {
        "query": "Java Complete Guide",
        "operator": "AND" # 默认是OR
        "analyzer": "whitespace"
      }
    }
  }
}

4.2.3 match_phrase

按分词匹配的时候,要保持和query中一样的顺序,且各term间的间距不能超过参数slop(默认为0),即查出来的内容中的term默认必须都是连续的。

GET books/_search
{
  "query": {
    "match_phrase": {
      "synopsis": "book for every Java programmer"
    }
  }
}

GET books/_search
{
  "query": {
    "match_phrase": {
      "synopsis": {
       "query": "for every Java programmer book",
       "slop": 1 #可间隔1个词
      }
    }
  }
}

4.2.4 match_phrase_prefix

和match_phrase类似,只不过把最后一个词当做前缀匹配。最后一个term的模糊匹配数控制:max_expansions 默认值为50(可自己设定)。注意:"max_expansions"的值最小为1,哪怕设置为0,依然会 + 1个通配符匹配;所以,尽量不要用该语句,因为,最后一个term始终要去扫描大量的索引,性能可能会很差。

GET books/_search
{
  "query": {
    "match_phrase_prefix": {
      "tags": {
        "query": "concepts found",
        "slop":1
        "max_expansions": 2 
      }
    }
  }
}

4.2.5 match_bool_prefix

类似match_phrase_prefix,差别是分词后的term在匹配时可以不按顺序。官方。

4.2.6 multi_match

多个Fields之间的查询关系是 or。

字段^数字:表示增强该字段评分倍数(权重影响相关性评分)。

参数type指定了multi_match相关性分_score的取值方法,支持:

  • best_fields(默认): 从匹配的任意 field 查找文档, 但是用 field相关分最高的一个作为 _score,支持tie_breaker参数,等价写法为dis_max。operator:AND影响的是每个term在field中的表现,filed之间的关系还是or。
  • most_fields:从匹配的任意 field 查找文档, 相加所有field的相关分作为_score,等价写法为should。
  • cross_fields: cross_fields 使用词中心式(term-centric)的查询方式,这与 best_fields 和 most_fields 使用字段中心式(field-centric)的查询方式非常不同,它将所有字段当成一个大字段,并在 大字段 中查找 每个词,这样相关性分上会和most_fields 有差异 。operator控制的是field之间的关系。不同field会根据使用的分析器,分成不同的组,operator控制的就是组之间的关系。
  • phrase:每个field跑一个match_phrase查询, 用 field相关分最高的一个作为 _score。
  • phrase_prefix:每个field跑一个match_phrase_prefix查询, 用 field相关分最高的一个作为 _score。
  • bool_prefix:每个field跑一个match_bool_prefix查询, 相加所有field的相关分作为_score。
GET books/_search
{
  "_source": false, 
  "query": {
    "multi_match": {
      "query": "Java",
      "fields": [
        "title^2",
        "synopsis",
        "tags"
      ]
    }
  }
}

4.2.7 dis_max

实际属于复合查询。best_fields的type下,ES实际上是吧multi_match语句在后台会改写成dis_max语句来运行。dis_max的_score为:
_ s c o r e = max ⁡ ( S q ) + t i e _ b r e a k e r ⋅ ( sum ( S q ) − max ⁡ ( S q ) ) \_score=\max{(S_q)}+tie\_breaker\cdot(\text{sum}( S_q)-\max{(S_q)}) _score=max(Sq)+tie_breaker(sum(Sq)max(Sq))
S q S_q Sq为所有子query的得分集合,tie_breaker默认值为0。

# Best fields - with a tie breaker
GET books/_search
{
  "_source": false, 
  "query": {
    "multi_match": {
      "query": "Design Patterns",
      "type": "best_fields", 
      "fields": ["title","synopsis"],
      "tie_breaker": 0.5
    }
  }
}
# 6.9938974 + 0.5 *(2.9220228 2.7801032 2.6008778)

#等价的 dis_max query
GET books/_search
{
  "_source": false, 
  "query": {
    "dis_max": {
      "queries": [
        {"match": {"title": "Design Patterns"}},
        {"match": {"synopsis": "Design Patterns"}}],
      "tie_breaker": 0.5
    }
  }
}

4.2.8 query_string

query_string是吧URI的编写方式放到DSL中的一种方法,同时也支持原生DSL相关的写法,主要是支持逻辑操作的查询比较方便。
原生DSL写法时,query中的字符串会先分词,再搜索。
default_operator:分词后term间的关系由default_operator控制,默认为OR。
default_field:只搜索一个field的时候指定。
fields:搜索多个field的时候指定,field之间的关系是OR。

GET books/_search
{
  "query": {
    "query_string": { 
      "query": "author:Bert AND edition:2 and release_date>=2000-01-01" # 模拟URI的能力
    }
  }
}


GET books/_search
{
  "query": {
    "query_string": {
      "query": "Patterns" #不限定field的时候,以term方式在所有field中搜索
    }
  }
}

GET books/_search
{
  "query": {
    "query_string": {
      "query": "Patterns",
      "fields": ["title","synopsis","tags"] #限定搜索field
    }
  }
}

GET books/_search
{
  "query": {
    "query_string": {
      "query": "Design Patterns",
      "default_field": "title",
      "default_operator": "AND"
    }
  }
}

GET books/_search
{
  "query": {
    "query_string": {
      "query": "\"making code better\"", #类似match_phrase的功能
      "default_field": "synopsis",
      "phrase_slop": 1
    }
  }
}

GET books/_search
{
  "query": {
    "query_string": {
      "query": "Pattenrs~", # ~打开fuzzy功能,"Pattenrs~10"表示编辑距离为10
      "default_field": "title"
    }
  }
}

query_string中的fuzzy编辑距离默认为2,且采用的是 Damerau-Levenshtein 距离(可以移位)。如果要修改默认距离,则用~10修改为10。

simple_query_string

simple_query_string支持操作符。

OperatorDescription
|OR
+AND
-NOT
~Fuzzy query
*Prefix query
Phrase query
GET books/_search
{
  "query": {
    "simple_query_string": {
      "query": "Java + Cay",# 在title中搜Java且Cay
      "default_field": "title" 
    }
  }
}

4.3 compound 查询

compound 查询有以下几种:
• Boolean query: bool
• Constant score query: constant_score
• Function score: function_score
• Boosting query: boosting
• Disjunction max query: dis_max

4.3.1 bool

bool查询支持四种语句(clauses): must, must_not, should,和 filter。四种语句的子query中支持自定义查询名称:
_name:给query命名,便于问题定位和减少重复query。

GET books/_search
{
	"query": {
		"bool": { #A A bool query is a combination of conditional boolean clauses
			"must": [{ ...,"_name":"must条件1"},{ ...,"_name":"must条件2"}],#B The criteria must match with the documents
			"must_not": [{ }],#C The criteria must-not match (no score contribution)
			"should": [{ }],#D The query should match
			"filter": [{ }]#E The query must match (no score contribution)
		}
	}
}
短语说明
must子句(查询)必须出现在匹配的文档中,并将有助于相关性得分。
must_not子句(查询)不得出现在匹配的文档中。子句在过滤器上下文中执行,这意味着计分被忽略,并且子句被视为用于缓存。
should子句(查询)应出现在匹配的文档中(可以不出现),并将有助于相关性得分。【注意should的最小匹配数】
filter必须匹配,类似must语句,子句在过滤器上下文中执行,这意味着计分被忽略,并且子句被视为用于缓存。

注意:

  • 4种语句的子句,支持 Full text queries 和 Term-level queries , bool ,constant_score ;
  • 只有must 和 should 子句会计算相关性评分;filter 和 must_not 子句都是在过滤器context中执行,计分被忽略,并且子句被考虑用于缓存。

示例:

GET books/_search
{
  "query": {
    "bool": {
      "must": [{"match": {"author": "Joshua"}}],
      "must_not":[{"range":{"amazon_rating":{"lt":4.7}}}],
      "should": [{"match": {"tags": "Software"}}],
      "filter":[
        {"range":{"release_date":{"gte": "2015-01-01"}}},
        {"term": {"edition": 3}}
      ]}
   }
}

should子句中的参数minimum_should_match和前面match语句中的使用方法一样,在bool中,默认值为两种情况:

  1. must存在时,默认为1
  2. must不存在时,默认为0

4.3.2 constant_score

一共两个参数filter,boost。官方。
说明仅支持filter子句。
正常情况filter的score为0,boost可指定filter的返回分。

GET /_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": { "user.id": "kimchy" }
      },
      "boost": 1.2
    }
  }
}

4.3.3 boosting

支持三个必选参数:
positive:接子query,子query可以使 term-level,full-text level和bool等
negative:接子query,子query可以使 term-level,full-text level和bool等
negative_boost:0-1的一个值

1)根据 positive 下的查询语句检索,得到结果集;
2)在上述的结果集中,对于那些同时还匹配 negative 查询的文档,将通过文档的原始 _score 与 negative_boost 相乘的方式重新计算相关性得分:
_ s c o r e = negative_boost ∗ positive评分 \_score=\text{negative\_boost}*\text{positive评分} _score=negative_boostpositive评分

GET /_search
{
  "query": {
    "boosting": {
      "positive": {
        "term": {
          "text": "apple"
        }
      },
      "negative": {
        "term": {
          "text": "pie tart fruit crumble tree"
        }
      },
      "negative_boost": 0.5
    }
  }
}

4.3.4 rescore

rescore 和 上面的 boosting 是比较相似的,都是在 query 结果集的基础上重新修改相关性得分。但是修改的算法是不一样的,根据场景需求,选择即可。

同时 rescore 可以利用 window_size 参数控制重新计算得分的文档数量,在数据量较大的情况,适当控制 window_size 参数,性能上会比 Boosting Query好

4.3.5 dis_max

见4.2.7章节,或官方文档。queris中的子查询必须满足至少一个。

GET /_search
{
  "query": {
    "dis_max": {
      "queries": [
        { "term": { "title": "Quick pets" } },
        { "term": { "body": "Quick pets" } }
      ],
      "tie_breaker": 0.7
    }
  }
}

4.3.6 function_score

提供了用户自定义的对相关分进行修正的能力。官方文档。

# 展开版
GET books/_search
{
	"query": {
		"function_score": {
			"query": { #A
				#类似原最外层的query
			},
			"<parameter>":"<MY_PARAM>", #C
		}
	}
}

parameter中重要参数:

  • functions:用于加权的function数组,只有一个function时,可以不用functions,直接写相关函数替代即可。functions里的重要参数:
    • filter:过滤器得到的所有文档的_score都是1,如果不用filter,那么默认使用的是match_all查询。通常和weight一起使用。

    • weight:设置一个简单而不被规范化的权重提升值(boost会被规范化),即news_score=weight*old_score,weight的默认值是1.0,当设置了weight,这个weight就会和评分函数的值相乘,在通过score_mode和其他funcitions分数合并。还有一个注意的点,当score_mode 为avg的时候,两个functions的func_score分别为 1 和 2 且他们的weight为3和4,那么他们的最终分为 (1*3+2*4)/(3+4) 而不是 (1*3+2*4)/2

    • random_score:返回均匀分布的[0,1)的值。支持两个参数seedfield。score=random(seed, field的最小值(如果是个多值field), 盐值(由索引名称和shard Id决定))。如果seed、field、盐值这三个值不变,那对于同一个文档,每次得到的score都相同。

      • seed:可以不填,默认值是一个带符号的随机值(每次请求都会变化,即效果等价于填入request_id)
      • field:可以不填(seed不填,只天field也无效),默认会加载fileddata里的_id,会消耗内存,耗费性能。最好指定一个对于文档来说是全局唯一的值。推荐_sed_no,该值每个文档唯一,但如果文档有更新,该值会改变。
    • field_value_factor:根据某个filed的值返回。注意:field_value_score 不能返回负数值,否则会报错,建议用filter做过滤。

      • field:指定用于加权的字段(func_score=doc['field_name'].value)
      • factor:field_value的调权值,默认为1。func_score=factor*doc['field_name'].value
      • modifier:func_score的调权函数:new_score=modifier(func_score)=modifier(factor*doc['field_name'].value)。支持none, log(会产生负值,建议用log1p), log1p, log2p, ln(会产生负值,建议用ln1p), ln1p, ln2p, square, sqrt(field为负值会报错), or reciprocal(field为负值和0会报错). 默认为none。
      • missing:filed不存在时的缺省值ben。
    • script_score:写脚本,脚本中可引用各种ES衰减函数和各种选择的编程语言支持的函数。

      • script:脚本详情
        • source 或 id:source为脚本源码,id为一个保存的脚本名(通过 stored script APIs创建和管理保存脚本)。
        • params:script中用到的参数
        • lang:脚本编程语言,默认painless
    • 衰减函数:

      • DECAY_FUNCTION:可选衰减函数gauss, linear, exp
        • multi_value_mode:如果field是一个多值字段,则最终用于参与衰减计算的distance 有多种选择:min(默认,将选择最接近原点的值来确定distance)、max、avg、sum。
        • FIELD_NAME:当作衰减函数的自变量,只能是numeric, date, 或 geopoint 类型
          • origin : 中心点,用于计算distance 。distance参与后续的计算。支持数值、时间 以及 “经纬度地理座标点”(最常用) 的字段。
          • offset : 默认值0,从 origin 为中心,为他设置一个偏移量offset覆盖一个范围,在此范围内所有的评分_score也都是和origin一样满分1.0。
          • scale : 衰减率,即是一个文档从origin下落时,_score改变的速度。
          • decay : 在 scale 处所得的评分_score,默认为0.5 (一般不需要改变,这个参数使用默认的就好了)
# field_value_factor
{
    "query": {
        "function_score": {
            "query": {... },
            "field_value_factor": {
                "field": "field_name" #如: "field": "rating_score"
                 "factor": 1.2,
        		 "modifier": "sqrt",
       			 "missing": 1
            }
        }
    }
}

# script_score
{
    "query": {
        "function_score": {
            "query": {... },
            "script_score": {
                "script": {
          			"source": "Math.log(a + doc['my-int'].value)", #甚至可以定义多值,并经过很复杂的逻辑计算,最终return value。
      		  		"params": {"a": 2}
      		  }
            }
        }
    }
}
# 衰减函数
{
    "query": {
        "function_score": {
            "query": {... },
			"DECAY_FUNCTION": { 
			    "FIELD_NAME": { 
			          "origin": "11, 12",# "2013-09-17"
			          "scale": "2km", # "10d"
			          "offset": "0km", # "5d"
			          "decay": 0.33
			    }
			}
}
  • score_mode: functions中各函数得分的加权方式
选项说明
multiplyscores are multiplied (default)
sumscores are summed
avgscores are averaged
firstthe first function that has a matching filter is applied
maxmaximum score is used
minminimum score is used
  • boost_mode: functions最后得分和query相关分的加权方式:
选项说明说明
multiplyquery score and function score is multiplied (default)new_score = query_score * func_score
replaceonly function score is used, the query score is ignorednew_score = func_score,直接替换query_score
sumquery score and function score are addednew_score = query_score + func_score
avgaveragenew_score = avg(query_score ,func_score)
maxmax of query score and function scorenew_score= max(query_score, func_score)
minmin of query score and function scorenew_score= min(query_score, func_score)
  • max_boost:限制functions函数的最大效果,就是限制func_score最大能多少,但是不会限制query_score。如果func_score超过了max_boost的限制值,会把func_score的值设置成max_boost。默认值为FLT_MAX。
  • min_score:过滤functions加权后 _score(即new_score)小于min_score的文档。注意:运行机制是先完成打分,再过滤。

4.4 特殊查询

官方提供了多种特殊查询方式:如
distance_feature query
more_like_this query
percolate query
rank_feature query
script query(线性扫描,很慢)
script_score query
wrapper query
pinned query

有时间可把官方DSL一栏的都梳理一遍。

调整相关度

参考教程

boost

注意:1)boost 可用于任何查询语句;2)这种提升或降低并不一定是线性的,新的评分 _score 会在应用权重提升之后被归一化 ,每种类型的查询都有自己的归一算法

高亮

highlight和query同一层级。

GET books/_search
{
  "query": {
    "match_phrase": {
      "title": "must-have book for every Java programmer"
    }
  },
  "highlight": {#A The highlight object at the same level as query object 
    "fields": {# B mention which fields we wish to have highlights 
      "title": {}
    }
  }
}

同义词处理

https://www.elastic.co/guide/en/elasticsearch/reference/8.5/analysis-synonym-graph-tokenfilter.html

常用接口

_analyze接口

分析器接口。也可以在路径中添加索引名称以使用对应索引的分析器。

# 优先使用POST, GET在Kibana上也可以但在es head会报错
POST /es_test/_analyze
{
"text":["apple egg book"]
# "analyzer": "standard"
}

# 拆得更细用
GET _analyze
{
  "tokenizer" : "standard",
  "filter" : ["lowercase"],
  "text" : "THE Quick FoX JUMPs"
}

_count 接口

Elasticsearch提供了查看文档总数的_count接口,可通过GET或POST方法请求该接口。在请求该接口的路径上,可以添加索引、映射类型,以限定统计文档数量的范围。所以在示例中对_count接口的请求都是正确的:

GET _count
GET index/_count

POST kibana_sample_data_logs/_count
{
  "query": {
    "match": {
      "message": "chrome"
    }
  }
}


_bulk 接口

bulk对JSON串的有着严格的要求。每个JSON串不能换行,只能放在同一行
,同时,相邻的JSON串之间必须要有换行(Linux下是\n;Window下是\r\n)。bulk的每个操作必须要一对JSON串(delete语法除外)。

{ action: { metadata }}
{ request body        }
{ action: { metadata }}
{ request body        }

bulk的操作类型:

  • create 如果文档不存在就创建,但如果文档存在就返回错误
  • index 如果文档不存在就创建,如果文档存在就更新
  • update 更新一个文档,如果文档不存在就返回错误
  • delete 删除一个文档,如果要删除的文档id不存在,就返回错误
    其实可以看得出来index是比较常用的。还有bulk的操作,某一个操作失败,是不会影响其他文档的操作的,它会在返回结果中告诉你失败的详细的原因。

POST _bulk
{ "index" : {"_index": "students","_id":"10"}}
{ "name" : "smith" }
{ "delete" : {"_index": "test","_id":"5"}}
{ "create": {"_index": "test","_id":"11"}}
{ "age" : 30,"name":"Candy" }
{ "update" : {"_id" :"1","_index" : "students"} }
{ "doc": {"age" : "20"}} 

# 或者把index写到请求中
POST /es_test/_doc/_bulk
{"create":{"_id": "1"}}
{"id": "1","title":"my love fruit","content":"t1 t2 t3","tags":["t1","t2","t3"]}
{"create":{"_id": "2"}}
{"id": "2","title":"my early love fruit","content":"t3 t2 t4","tags":["t3","t2","t4"]}
{"create":{"_id": "3"}}
{"id": "3","title":"my future love fruit","content":"t2 t5 t6 t3","tags":["t2","t5","t6","t3"]}

POST /es_test/_doc/_bulk
{"delete":{"_id": "1"}}
{"delete":{"_id": "2"}}
{"delete":{"_id": "3"}}

_mapping 接口

GET获取索引的mapping信息,或者PUT 创建或修改mapping信息。

# 获取
GET index/_mapping

PUT index/_mapping 
{..}

_explain 接口

获取评分或者错误的详细解释。

GET /_search?explain
{
 "query" : { "match" : { "tweet" : "honeymoon" }}
}
# 等价 explain 为true
GET /_search
{
 "query" : { "match" : { "tweet" : "honeymoon" }},
 "explain":true
}

# 格式: /index/type/id/_explain ,可用于解释,为什么一个id没有被match。7.x以下
GET/POST /es_test/_doc/2/_explain
{
	 "query": {
  		  "term": {"content": "t0" }
  }
}
# 可看到filter过滤原因:"description": "content:t0 doesn't match id 1"
GET /es_test/_doc/2/_explain
{
	 "query": {
     "bool" : {
   		 	 "filter" : { "term" : { "content" : "t0" }},
     		 "should" : [{ "match" : { "title" :"my" }}]
		 }
  }
}

# 7.x及以上,格式: /index/_explain/id,因为只有_dco类型,所以不需要指定类型了。
GET /es_test/_explain/2/
{...}

# 如果碰到禁用以上_explain方式的系统,一般可以通过转换成bool查询实现,但这种只能查看能匹配的文章。

{	 "query": {
     "bool" : {
    		 "filter" : { "term" : { "_id" : "xxx" }},
   			 "must" : [{原query}]
 		}
  },
  "explain":"true"
}

_search接口

查询接口,很常用,若不配合query,则返回index下所有文档的meta+_source信息,等价于match_all

GET books/_search

# 等价
GET books/_search
{
"query": {
"match_all": { }
}
}

这里讲讲如何获取想要的字段信息。包括_source字段和sotored字段。

# 获_source取字段信息,7.0以上用_source_includes,多个s
GET /es_test/_doc/2?_source_include=title,content


# 也可以用:
POST es_test/_search
{
  "query": {
    "term": {
      "_id": "2"
    }
  },
  "fields": ["title", "content"],
  "_source": false #若不用fields可直接开成true
}
# 或

POST es_test/_search
{
  "query": {
    "term": {
      "_id": "2"
    }
  },
  "_source": {
		"includes": ["title", "content"]
	}# 或者简写成 "_source": ["title", "content"]
}


# 获取stored字段信息
GET twitter/_doc/1?stored_fields=title,content
# 或
POST es_test/_search
{
  "query": {
    "term": {
      "_id": "2"
    }
  },
  "stored_fields": ["title", "content"]
}


_refresh 接口

_refresh接口用于主动刷新一个或多个索引,将已经添加的文档编入索引以使它们在检索时可见。在调用该接口时,可以直接调用或与一个或多个索引起使用, 还可以使用_all刷新所有索引。

GET 索引1/_refresh

POST _refresh

GET _all/_refresh

POST 索引1,索引2/_refresh

_stats 接口

_stats接口用于查看索引上不同操作的统计数据,可以直接请求也可以与索引名称一起使用。_stats接口返回的统计数据非常多,如果只对其中某一组统计数据感兴趣,可以在_stats接口后附加统计名称。 例如以下对_stats接口的调用都是正确的:

GET _stats

GET _stats/store

GET kibana_sample_data_flights/_stats

GET kibana_sample_data_flights/_stats/fielddata

_validate接口

_validate接口用于在不执行查询的情况下,评估一个查询是否合法可执行,这通常用于验证执行开销比较高的查询。_validate接口可通过GET或POST方法请求,请求路径中必须要包含_validate/query,也可以在路径中添加索引名称以限定查询执行的范围。类似_search接口。示例:

POST _validate/query
{
  "query": {
	...
  }
}

# 解释具体错误
GET /es_test/_validate/query?explain
{
	 "query": {
		...
	 }
}

_mget 接口

一条一条的查询,比如说要查询100条数据,那么就要发送100次网络请求,这个开销还是很大的,如果批量查询的话,查询100条数据,就只要发送1次网络请求,网络请求的性能开销缩减100倍。

GET /_mget
{
  "docs": [
    {
      "_index": "es_test",
      "_id": "1"
    },
    {
      "_index": "es_test",
      "_id": "2"
    }
  ]
}

_field_caps接口

_field_caps接口用于查看某一字段支持的功能,主要包括字段是否可检索以及是否可聚集等。需要查看的字段可以通过 URI参数fields设置,可以使用GET或POST方法请求。在请求地址中,还可以添加索引名称以限定查询范围。

GET _field_caps?fields=title

POST es_test/_field_caps?fields=title,content

容量控制接口

_split接口:对新索引做分片上的操作
_shrink接口:对新索引做分片上的操作
_reindex接口:将文档复制到新索引

性能调优

分片、线程池

参考:

《Madhusudhan Konda - Elasticsearch in Action Second Edition Version 11 (2022, Manning Publications)》
GIt: https://github.com/madhusudhankonda/elasticsearch-in-action/wiki
GIT2:https://github.com/madhusudhankonda/elasticsearch-in-action/tree/main/kibana_scripts

http://mp.weixin.qq.com/mp/homepage?__biz=MzIxMjE3NjYwOQ==&hid=5&sn=b9c85139ca524fc7823379f4a2da99ba&scene=18#wechat_redirect

https://opster.com/elasticsearch-guides/

举报

相关推荐

0 条评论