Elasticsearch7教程
Elasticsearch快速入门,掌握这些刚刚好!
前序
Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。
正排索引和倒排索引
导读
索引(index)作为一种具备各种优势的数据结构,被大量应用在数据检索领域。其中倒排索引数据结构在搜索引擎框架中扮演着非常重要的角色。
假设我们有网页1和网页2:
- 网页1:厦门SEO顾问潇湘驭文为您提供厦门SEO培训服务。
- 网页2:SEO是一门艺术。
正排索引
经过搜索引擎初步分词之后,网页1和2的正向索引如下图所示:
假设使用正向索引,那么当你搜索SEO的时候,搜索引擎必须检索网页中的每一个关键词,假设一个网页中包含成千上百个关键词,可想而知,会造成大量的资源浪费。于是倒排索引应运而生。
倒排索引
倒排索引是相对正向索引而言的,你也可以将其理解为逆向索引。它是一种关键词与网页一一对应的数据结构。如下图所示:
从上图可以一目了然,倒排索引可以直接参与排名。
比如你搜索“SEO”,搜索引擎可以快速检索出包含“SEO”搜索词的网页1和网页2,为后续的相关度和权重计算奠定基础,从而大大加快了返回搜索结果的速度。
下载及配置
下载
软件名 | 下载地址 |
---|---|
Elasticsearch | https://www.elastic.co/cn/start |
Kibana | https://www.elastic.co/cn/start |
Logstash | https://www.elastic.co/cn/downloads/logstash |
解决跨域
当使用 elasticsearch-head
会存在跨域问题。
修改 *Elasticsearch *配置文件 ..elasticsearch-7.10.1configelasticsearch.yml
# 解决端口 9100 访问 9200 跨域问题
http.cors.enabled: true
http.cors.allow-origin: "*"
中文显示
当使用 Kibana
可以设置成中文
修改 Kibana 配置文件 ..kibana-7.10.1-windows-x86_64configkibana.yml
# 改成中文
i18n.locale: "zh-CN"
Elasticsearch的基本概念
shard(分片)
单台机器(节点)无法存储大量的索引数据, ES可以把一个完整的索引分成多个分片, 分布到不同的节点上, 从而构成分布式索引.
每个分片都是一个Lucene实例, 也就是说每个分片底层都有一个单独的Lucene提供独立的索引和检索服务, 它们可以托管在集群的任一节点上.
单个Lucene中存储的索引文档最大值为 lucene-5843
, 极限是2147483519(=integer.max_value - 128)
个文档. 可使用_cat/shards
API 监控分片的大小.
分片好处
允许水平切分/扩展集群容量; 可在多个分片上进行分布式的、并行的操作, 提高系统的性能和吞吐量.
注意事项
分片的数量只能在创建索引前指定, 创建索引后不能修改. 5.x 版本默认不能通过配置文件elasticsearch.yml定义分片个数.
replica(副本)
ES支持为每个Shard创建多个副本, 相当于索引数据的冗余备份. 分片有Primary Shard(主分片)、Replica Shard(副本分片), 建立索引时, 系统会先将索引存储在主分片中, 然后再将主分片中的索引复制到不同的副本中.
副本的重要性
- 解决单点问题, 提高可用性和容错性: 某个节点失败时服务不受影响, 可以从副本中恢复;
- 提高查询效率和查询时的吞吐量: 搜索可以在所有的副本上并行执行, 提高了服务的并发量.
注意事项
主分片在建立索引时设置, 后期不能修改; 主分片和副本分片不能存储在同一个节点中 —— 无法保证高可用. 5.x版本中, 默认主分片为5个, 默认副本分片数为1个, 即每个主分片各有1个副本分片(共5个副本分片); 可随时修改副本分片的数量. 默认情况下, 每个索引共有 5 primary shard 5 * 1 replica shard = 10 shard. 集群中至少要有2个节点, 这是最少的高可用配置.
index(索引)
索引是具有相似结构的文档的集合, 等同于Solr中的集合, 比如可以有一个商品分类索引, 订单索引. 每个索引都要有唯一的名称, 名称要小写, 通过索引名称来执行索引、搜索、更新和删除等操作. 一个集群中可以有任意多个索引, 只要保证名称不同即可.
document(文档)
文档是存储在ES中的一个个JSON格式的字符串, 是ES索引中的最小数据单元, 由field(字段)构成.
type(类型)
type是index的逻辑分类, 在ES 6.x版本之前, 每个索引中可以定义一个或多个type, 而在6.X版本之后, 一个index中只能定义一个type.
一种type一般被定义为具有一组公共field的document, 比如对博客系统中的数据建立索引, 可以定义用户数据type,
博客数据type, 评论数据type, 也就是每个document都必须属于某一个具体的type, 也就是说每个document都有_type
属性.
mapping(映射)
类似于关系数据库中的Table结构, 每个index都有一个映射: 定义索引中每个字段的类型.
所有文档在写进索引之前都会先进行分析, 如何对文本进行分词、哪些词条又会被过滤, 这类行为叫做映射(mapping).
映射可以提前定义, 也可以在第一次存储文档时自动识别. 一般由用户自己定义规则.
类似于Solr中schema.xml
约束文件的作用.
field(字段)
字段可以是一个简单的值(如字符串、数字、日期), 也可以是一个数组, 还可以嵌套一个对象或多个对象. 字段类似于关系数据库中表数据的列, 每个字段都对应一个类型. 可以指定如何分析某一字段的值, 即对field指定分词器.
概念关系图
ES的索引中, 各概念的关系为: Field –> Document –> Type –> Index, 索引结构图如下:
注意:在7.0之前,一个Index可以创建多个类型,从7.0开始,一个索引只能创建一个类型,也就是 _doc
与关系型数据库的对比:
Elasticsearch | RDBMS |
---|---|
Index(索引) | DataBase(数据库) |
Type(类型) | Table(表) |
Document(文档) | Row(行) |
Field(字段) | Column(列) |
Mapping(映射) | Schema(约束) |
Everything is indexed(存储的都是索引) | Index(索引) |
Query DSL(ES独特的查询语言) | SQL(结构化查询语言) |
RestAPI
CRUD 操作
代码语言:javascript复制# 查询 movies 的数据
GET movies/_search
# 查询 movies 的数量
GET movies/_count
# 查看所有的索引
GET _cat/indices
# 查询id为24的数据
GET movies/_doc/24
代码语言:javascript复制# 添加新的文档,如果没有指定id,ES会自动生成id
POST users/_doc
{
"firstname": "will",
"lastname": "smith"
}
# 添加id为2的文档,ES不会自动生成id
POST users/_doc/2
{
"firstname": "will2",
"lastname": "smith2"
}
# 查询 users 的数据
GET users/_search
# 创建id为2的文档,如果索引中已经存在相同的id,会报错,创建失败;如果不存在相同的id,则创建成功
POST users/_create/2
{
"firstname": "will2",
"lastname": "smith2"
}
# 更新id为2的文档,更新指定field
POST users/_update/2
{
"doc": {
"firstname": "jack",
"lastname": "well"
}
}
# 更新id为2的文档,添加一个field
POST users/_update/2
{
"doc": {
"age": 30
}
}
# 删除id为2的文档
DELETE users/_doc/2
# 删除 users 索引
DELETE users
代码语言:javascript复制# 创建或修改id为1的文档
PUT users/_doc/1
{
"firstname": "jack",
"lastname": "ma"
}
# 创建id为2的文档,如果索引中已经存在相同的id,会报错,创建失败;如果不存在相同的id,则创建成功
PUT users/_create/2
{
"firstname": "will",
"lastname": "smith"
}
# 批量查询多个指定index的指定field的值
GET _mget
{
"docs" : [
{"_index": "users", "_id": 1},
{"_index": "users", "_id": 2}
]
}
# 批量插入数据,如果id不存在,则创建;如果id存在,则更新
POST users/_bulk
{"index" : {"_id" : 3}}
{"firstname": "A", "lastname": "a"}
{"index" : {"_id" : 4}}
{"firstname": "B", "lastname": "b"}
{"index" : {"_id" : 5}}
{"firstname": "C", "lastname": "c"}
URI 查询
代码语言:javascript复制# 查询title中包含2012的所有电影
GET movies/_search?q=2012
# 查询title中包含2012的所有电影,df(default field)
GET movies/_search?q=2012&df=title
# 查询title中包含2012的所有电影
GET movies/_search?q=title:2012
分页搜索,from
表示偏移量,从0开始,size
表示每页显示的数量
# 查询title中包含2012的所有电影,从第10条开始算起(不包含第10条),查询8条数据
GET movies/_search?q=title:2012&from=10&size=8
代码语言:javascript复制# 查询title中包含Beautiful或Mind的所有数据
GET movies/_search?q=title:Beautiful Mind
GET movies/_search?q=title:(Beautiful Mind)
GET movies/_search?q=title:( Beautiful Mind)
# 查询title中包含"Beautiful Mind"这个短语的所有数据
GET movies/_search?q=title:"Beautiful Mind"
# 查询title中既包含Mind,又包含Beautiful的所有数据
GET movies/_search?q=title:(Mind AND Beautiful)
# 查询title中包含Mind,或包含Beautiful的所有数据
GET movies/_search?q=title:(Mind OR Beautiful)
# 查询title中包含Beautiful但不包含Mind的所有数据
GET movies/_search?q=title:(Beautiful NOT Mind)
GET movies/_search?q=title:(Beautiful -Mind)
# 查询title中包含Beautiful且电影上映时间在2012年之后的所有数据
GET movies/_search?q=title:Beautiful AND year:>=2012
# 查询电影上映时间在2018年之后的所有数据
GET movies/_search?q=year:>=2018
# 注意[空格]格式问题
# 查询在2012到2017年的所有数据
GET movies/_search?q=year:(>=2012 AND <2018)
# 查询2016年到2017年上映的电影,开头可以是 { [,但必须以 ] 结尾
GET movies/_search?q=year:{2015 TO 2017]
# ? 代表一个字母
GET movies/_search?q=title:Min?
# 查询title中包含以Min开头的字母的电影
GET movies/_search?q=title:Min*
Analysis
Analysis(只是一个概念),本文分析是将全文本转换为一系列单词的过程,也叫分词。analysis是通过analyzer(分词器)来实现的,可以使用Elasticsearch内置的分词器,也可以自己去定制一些分词器。
除了在数据写入的时候进行分词处理,在查询的时候也可以使用分析器对查询语句进行分词。
analyzer
analyzer是由三部分组成:
- Character Filter:将文本中html标签剔除
- Tokenizer:按照规则进行分词,在英文中按照空格分词
- Token Filter:去掉 stop、world(停顿词,a、an、the、is、are等),然后转换小写
内置分词器
分词器名称 | 处理过程 |
---|---|
Standard Analyzer | 默认的分词器,按词切分,小写处理 |
Simple Analyzer | 按照非字母切分(符号、数字被过滤),小写处理 |
Stop Analyzer | 小写处理,停用词过滤(the, a, this) |
Whitespace Analyzer | 按照空格切分,不转小写 |
Keyword Analyzer | 不分词,直接将输入当做输出 |
Pattern Analyzer | 正则表达式,默认是W (非字符串分隔) |
Standard Analyzer
默认的分词器,按词切分,小写处理
代码语言:javascript复制GET _analyze
{
"analyzer": "standard",
"text": ["2 Running quick brown-foxes leap over lazy dog in the summer evening"]
}
Simple Analyzer
按照非字母切分(符号、数字被过滤),小写处理
代码语言:javascript复制GET _analyze
{
"analyzer": "simple",
"text": ["2 Running quick brown-foxes leap over lazy dog in the summer evening"]
}
Stop Analyzer
小写处理,停用词过滤(the, a, this)
代码语言:javascript复制GET _analyze
{
"analyzer": "stop",
"text": ["2 Running quick brown-foxes leap over lazy dog in the summer evening"]
}
Whitespace Analyzer
按照空格切分,不转小写
代码语言:javascript复制GET _analyze
{
"analyzer": "whitespace",
"text": ["2 Running quick brown-foxes leap over lazy dog in the summer evening"]
}
Keyword Analyzer
不分词,直接将输入当做输出
代码语言:javascript复制GET _analyze
{
"analyzer": "keyword",
"text": ["2 Running quick brown-foxes leap over lazy dog in the summer evening"]
}
Pattern Analyzer
正则表达式,默认是W (非字符串分隔)
代码语言:javascript复制GET _analyze
{
"analyzer": "pattern",
"text": ["2 Running quick brown-foxes leap over lazy dog in the summer evening"]
}
Request Body 深入搜索
term 查询
term是表达语义的最小单位,在搜索的时候基本都要使用到term。
term查询的种类:Term Query、Range Query等等。
在ES中,term查询不会对输入的内容进行分词处理,而是作为一个整体,在倒排索引中查找准确的词项,并算分。我们也可以使用 Constant Score 将查询转换为一个 filter,避免算分,利用缓存,提高查询的效率
term 与 terms
term 用于查询单个值,terms用于查询多个值
代码语言:javascript复制# 查询电影名字中包含有 beautiful 这个单词的所有电影,对于输入的单词不会进行分词的处理。
GET movies/_search
{
"query": {
"term": {
"title": {
"value": "beautiful"
}
}
}
}
代码语言:javascript复制# 查询电影名字中包含有 beautiful 或者 mind 的所有电影,对于输入的单词不会进行分词的处理。
GET movies/_search
{
"query": {
"terms": {
"title": [
"beautiful",
"mind"
]
}
}
}
range
搜索排序,使用sort
表示,例如按year
字段降序排列;
# 查询上映时间在2016到2018年的所有电影,根据上映时间进行倒序排序
GET movies/_search
{
"query": {
"range": {
"year": {
"gte": 2016,
"lte": 2018
}
}
},
"sort": [
{
"year": {
"order": "desc"
}
}
]
}
Constant Score
代码语言:javascript复制# 查询 title 中包含 beautiful 的所有电影,不进行相关算分,查询数据进行缓存,提高效率
GET movies/_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"title": "beautiful"
}
}
}
}
}
全文查询
全文查询的种类:Match Query、Match Phrase Query、Query String 、Query 等
索引和搜索的时候都会进行分词,在查询的时候,会对输入进行分词,然后每个词项会逐个到底层进行查询,将最终的结果进行合并
match
条件搜索,使用match
表示匹配条件,例如搜索出title
为beautiful
的文档
# 查询电影名字中包含有 beautiful 的所有数据,每页10条,取第二页数据
GET movies/_search
{
"query": {
"match": {
"title": "beautiful"
}
},
"from": 1,
"size": 10
}
文本类型字段的条件搜索,例如搜索title
字段中包含20
的文档,对比上一条搜索可以发现,对于数值类型match
操作使用的是精确匹配,对于文本类型使用的是模糊匹配
搜索并返回指定字段内容,使用_source
表示,例如只返回title
和id
两个字段内容
# 查询电影名字中包含有 beautiful 或者 mind 的所有数据,但只显示 title 和 id 这两个属性
GET movies/_search
{
"_source": ["title", "id"],
"query": {
"match": {
"title": "beautiful mind"
}
}
}
match_phrase
短语匹配搜索,使用match_phrase
表示,例如搜索title
字段中同时包含beautiful
和mind
的文档
# 查询电影名字中包含 beautiful mind 这个短语的所有数据
GET movies/_search
{
"query": {
"match_phrase": {
"title": "beautiful mind"
}
}
}
multi_match
代码语言:javascript复制# 查询 title 或 genre 中包含有 beautiful 或 Adventure 的所有数据
GET movies/_search
{
"query": {
"multi_match": {
"query": "beautiful Adventure",
"fields": ["title", "genre"]
}
}
}
match_all
代码语言:javascript复制# 查询所有数据
GET movies/_search
{
"query": {
"match_all": {}
}
}
query_string
代码语言:javascript复制# 查询 title 中包含 beautiful 和 mind 的所有电影
GET movies/_search
{
"query": {
"query_string": {
"default_field": "title",
"query": "mind AND beautiful"
}
}
}
GET movies/_search
{
"query": {
"query_string": {
"default_field": "title",
"query": "mind beautiful",
"default_operator": "AND"
}
}
}
simple_query_string
simple_query_string
覆盖了很多其他查询的用法。
# 查询 title 中包含 beautiful 和 mind 的所有电影
GET movies/_search
{
"query": {
"simple_query_string": {
"query": "beautiful mind",
"fields": ["title"]
}
}
}
GET movies/_search
{
"query": {
"simple_query_string": {
"query": "beautiful mind",
"fields": ["title"],
"default_operator": "AND"
}
}
}
# 查询 title 中包含 beautiful mind 这个短语的所有电影(用法类似 match_phrase)
GET movies/_search
{
"query": {
"simple_query_string": {
"query": ""beautiful mind"",
"fields": ["title"]
}
}
}
# 查询 title 或 genre 中包含 beautiful 或 mind 的所有电影(用法类似 multi_match)
GET movies/_search
{
"query": {
"simple_query_string": {
"query": "beautiful mind",
"fields": ["title", "genre"]
}
}
}
# 查询 title 中包含 beautiful mind 或者 Modern Romance 这两个短语的所有电影
GET movies/_search
{
"query": {
"simple_query_string": {
"query": ""beautiful mind" | "Modern Romance"",
"fields": ["title"]
}
}
}
# 查询 title 或者 genre 中包含 beautiful 和 mind 这两个词,或者 Comedy 和 Romance 和 Musical 和 Drama 和 Children 这五个词的所有数据
GET movies/_search
{
"query": {
"simple_query_string": {
"query": "(beautiful mind) | (Comedy Romance Musical Drama Children)",
"fields": ["title", "genre"]
}
}
}
# 查询 title 中包含 beautiful 和 people,但不包含 Animals 的所有数据
GET movies/_search
{
"query": {
"simple_query_string": {
"query": "beautiful people -Animals",
"fields": ["title"]
}
}
}
模糊搜索
代码语言:javascript复制# 查询 title中从第六个字母开始只要最多纠正一次,就与 neverendign 匹配的所有数据
GET movies/_search
{
"query": {
"fuzzy": {
"title": {
"value": "neverendign",
"fuzziness": 1,
"prefix_length": 5
}
}
}
}
组合查询
组合搜索,使用bool
来进行组合,must
表示同时满足
条件 | 说明 |
---|---|
must | 同时满足 |
should | 满足其中任意一个 |
must_not | 同时不满足 |
filter | 过滤搜索 |
# 查询 title 中包含 beautiful 或 mind 单词,并且上映时间在 2016到2018 年的所有数据
GET movies/_search
{
"query": {
"bool": {
"must": [
{
"simple_query_string": {
"query": "beautiful mind",
"fields": ["title"]
}
},
{
"range": {
"year": {
"gte": 2016,
"lte": 2018
}
}
}
]
}
}
}
搜索过滤,使用filter
来表示,例如过滤出year
字段在2016-2018
的文档
# 查询 title 中包含 beautiful 单词,并且上映年份在 2016到2018 年的所有数据,但不会进行相关行算分
GET movies/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"title": "beautiful"
}
},
{
"range": {
"year": {
"gte": 2016,
"lte": 2018
}
}
}
]
}
}
}
Mapping
mapping 类似于数据库中的schema,作用如下:
- 定义索引中的字段类型;
- 定义字段的数据类型,例如:布尔、字符串、数字、日期
- 字段倒排索引的设置
数据类型
类型 | 描述 |
---|---|
Text、Keyword | 字符串。Keyword的意思是字符串的内容不会被分词处理。Text类型ES会自动的添加一个Keyword类型的子字段。 |
Date | 日期类型 |
Integer、Float、Long | 数字类型 |
Boolean | 布尔类型 |
Geo_point、Geo_shape | 特殊类型 |
Mapping的定义
语法
代码语言:javascript复制PUT users
{
"mappings": {
// mapping信息
}
}
定义mapping的建议方式: 写入一个样本文档到临时索引中,ES会自动生成mapping信息,通过访问 mapping信息的api查询mapping的定义,修改自动生成的mapping成为我们需要方式,创建索引,删 除临时索引,简而言之就是 “卸磨杀驴” 。
创建Mapping
代码语言:javascript复制PUT users
{
"mappings": {
"properties": {
"id": {
"type": "integer"
},
"name": {
"type": "keyword"
},
"job": {
"type": "keyword"
},
"age": {
"type": "integer"
},
"gender": {
"type": "keyword"
}
}
}
}
填充测试数据
代码语言:javascript复制PUT users/_bulk
{"index": {"_id": 1}}
{"id": 1, "name": "Bob", "job": "java", "age": 21, "sal": 8000, "gender": "female"}
{"index": {"_id": 2}}
{"id": 2, "name": "Rod", "job": "html", "age": 31, "sal": 18000, "gender": "female"}
{"index": {"_id": 3}}
{"id": 3, "name": "Gaving", "job": "java", "age": 24, "sal": 12000, "gender": "male"}
{"index": {"_id": 4}}
{"id": 4, "name": "King", "job": "dba", "age": 26, "sal": 15000, "gender": "female"}
{"index": {"_id": 5}}
{"id": 5, "name": "Jonhson", "job": "dba", "age": 29, "sal": 16000, "gender": "male"}
{"index": {"_id": 6}}
{"id": 6, "name": "Douge", "job": "java", "age": 41, "sal": 20000, "gender": "female"}
{"index": {"_id": 7}}
{"id": 7, "name": "cutting", "job": "dba", "age": 27, "sal": 7000, "gender": "male"}
{"index": {"_id": 8}}
{"id": 8, "name": "Bona", "job": "html", "age": 22, "sal": 14000, "gender": "female"}
{"index": {"_id": 9}}
{"id": 9, "name": "Shyon", "job": "dba", "age": 20, "sal": 19000, "gender": "female"}
{"index": {"_id": 10}}
{"id": 10, "name": "James", "job": "html", "age": 18, "sal": 22000, "gender": "male"}
{"index": {"_id": 11}}
{"id": 11, "name": "Golsling", "job": "java", "age": 32, "sal": 23000, "gender": "female"}
{"index": {"_id": 12}}
{"id": 12, "name": "Lily", "job": "java", "age": 24, "sal": 2000, "gender": "male"}
{"index": {"_id": 13}}
{"id": 13, "name": "Jack", "job": "html", "age": 23, "sal": 3000, "gender": "female"}
{"index": {"_id": 14}}
{"id": 14, "name": "Rose", "job": "java", "age": 36, "sal": 6000, "gender": "female"}
{"index": {"_id": 15}}
{"id": 15, "name": "Will", "job": "dba", "age": 38, "sal": 4500, "gender": "male"}
{"index": {"_id": 16}}
{"id": 16, "name": "smith", "job": "java", "age": 32, "sal": 23000, "gender": "male"}
再谈搜索
聚合查询
对搜索结果进行聚合,使用aggs
来表示,类似于MySql中的group by
语法
代码语言:javascript复制GET indexName/_search
{
"aggs": {
"aggs_name": { // 名字自定义
"AGG_TYPE": {
// aggregation body
}
}
}
}
单值输出
代码语言:javascript复制ES中大多数的数学计算只输出一个值,如:min、max、sum、avg、cardinality
# 查询总和工资
GET users/_search
{
"size": 0,
"aggs": {
"sal_sum": {
"sum": {
"field": "sal"
}
}
}
}
# 查询平均工资
GET users/_search
{
"size": 0,
"aggs": {
"avg_sal": {
"avg": {
"field": "sal"
}
}
}
}
# 查询总共有多少个岗位,cardinality的值类似于sql中的count distinct,即去重统计总数
GET users/_search
{
"size": 0,
"aggs": {
"count_job": {
"cardinality": {
"field": "job"
}
}
}
}
多值输出
代码语言:javascript复制ES还有些函数,可以一次性输出很多个统计的数据:terms、stats
# 查询工资的信息(数量、最大、最小、平均、总数)
GET users/_search
{
"size": 0,
"aggs": {
"stats_sal": {
"stats": {
"field": "sal"
}
}
}
}
# 查询到达不同城市的航班数量
GET kibana_sample_data_flights/_search
{
"size": 0,
"aggs": {
"terms_flight_dest": {
"terms": {
"field": "DestCountry"
}
}
}
}
# 查询每个岗位有多少人数
GET users/_search
{
"size": 0,
"aggs": {
"terms_job": {
"terms": {
"field": "job"
}
}
}
}
# 查询目的地的航班次数以及天气信息
GET kibana_sample_data_flights/_search
{
"size": 0,
"aggs": {
"terms_dest_city": {
"terms": {
"field": "DestCityName"
},
"aggs": {
"terms_whether_info": {
"terms": {
"field": "DestWeather"
}
}
}
}
}
}
# 查询每个岗位下工资的信息(平均、最高、最低)
GET users/_search
{
"size": 0,
"aggs": {
"terms_job_info": {
"terms": {
"field": "job"
},
"aggs": {
"stats_sal_info": {
"stats": {
"field": "sal"
}
}
}
}
}
}
# 查询不同工种的男女数量,然后统计不同工种下男女员工的工资信息
GET users/_search
{
"size": 0,
"aggs": {
"terms_job_info": {
"terms": {
"field": "job"
},
"aggs": {
"terms_gender_info": {
"terms": {
"field": "gender"
},
"aggs": {
"stats_sal_info": {
"stats": {
"field": "sal"
}
}
}
}
}
}
}
}
# 查询年龄最大的两位员工的信息
GET users/_search
{
"size": 0,
"aggs": {
"top_age_2": {
"top_hits": {
"size": 2,
"sort": [
{
"age": {
"order": "desc"
}
}
]
}
}
}
}
# 查询不同区间人员的工资统计信息
GET users/_search
{
"size": 0,
"aggs": {
"range_sal_info": {
"range": {
"field": "sal",
"ranges": [
{
"key": "0 <= sal <= 5000",
"from": 0,
"to": 5000
},
{
"key": "5001 <= sal <= 10000",
"from": 5001,
"to": 10000
}
]
}
}
}
}
# 以直方图的方式以每5000元为一个区间查看工资信息
## interval:指定的值为一个区间
## extended_bounds:指定区间的范围
GET users/_search
{
"size": 0,
"aggs": {
"histogram_sal_info": {
"histogram": {
"field": "sal",
"interval": 5000,
"extended_bounds": {
"min": 0,
"max": 30000
}
}
}
}
}
# 查询平均工资中最低工资的工种
GET users/_search
{
"size": 0,
"aggs": {
"job_info": {
"terms": {
"field": "job"
},
"aggs": {
"job_avg_sal": {
"avg": {
"field": "sal"
}
}
}
},
"min_sal_job": {
"min_bucket": {
"buckets_path": "job_info>job_avg_sal"
}
}
}
}
# 求工资和工种的信息
GET users/_search
{
"size": 0,
"aggs": {
"job_info": {
"terms": {
"field": "job"
}
},
"sal_info": {
"stats": {
"field": "sal"
}
}
}
}
# 查询年龄大于30的员工的平均工资
GET users/_search
{
"size": 0,
"query": {
"range": {
"age": {
"gte": 30
}
}
},
"aggs": {
"avg_sal": {
"avg": {
"field": "sal"
}
}
}
}
# 查询Java员工的平均工资
GET users/_search
{
"size": 0,
"query": {
"constant_score": {
"filter": {
"term": {
"job": "java"
}
},
"boost": 1.2
}
},
"aggs": {
"avg_sal": {
"avg": {
"field": "sal"
}
}
}
}
# 查询30岁以上的员工的平均工资和所有的工种信息
GET users/_search
{
"size": 0,
"aggs": {
"older_emp": {
"filter": {
"range": {
"age": {
"gte": 30
}
}
},
"aggs": {
"avg_sal": {
"avg": {
"field": "sal"
}
}
}
},
"job_info": {
"terms": {
"field": "job"
}
}
}
}
推荐搜索
在搜索过程中,因为单词的拼写错误,没有得到任何的结果,希望ES能够给我们一个推荐搜索。
代码语言:javascript复制GET movies/_search
{
"suggest": {
# 自定义的名称
"title_suggestion": {
"text": "drema",
"term": {
"field": "title",
"suggest_mode": "popular"
}
}
}
}
suggest_mode
值 | 说明 |
---|---|
popular | 推荐词频更高的一些搜索 |
missing | 当没有要搜索的结果的时候才推荐 |
always | 无论什么情况下都进行推荐 |
自动补全
自动补全应该是我们在日常的开发过程中最常见的搜索方式了。
自动补全的功能对性能的要求极高,用户每发送输入一个字符就要发送一个请求去查找匹配项。ES采取了不同的数据结构来实现,并不是通过倒排索引来实现的;需要将对于的数据类型设置为
completion
;所以在将数据索引进ES之前需要先定义mapping信息。
需要重新导入数据,先跳过
高亮显示
高亮显示在实际的应用中也会碰到很多。
代码语言:javascript复制GET movies/_search
{
"query": {
"match": {
"title": "beautiful"
}
},
"highlight": {
"pre_tags": "<span color='red'>", # 需要高亮文本的前置 html 内容
"post_tags": "</span>", # 需要高亮文本的后置 html 内容
"fields": { # 需要高亮的属性
"title": {}
}
}
}