ES入门概念

54 阅读10分钟

kibana是ES的可视化工具。IK分词qi

基础概念

ES的服务中,可以创建多个索引。

每一个索引默认被分成5片存储。

每一个分片都会存在至少一个备份分片。

备份分片默认不会帮助检索数据,当ES检索压力特别大的时候,备份分片才会帮助检索数据。

备份的分片必须放在不同的服务器中。

一个索引下,可以创建多个类型。

Ps:根据版本不同,类型的创建也不同。

一个类型下,可以有多个文档。这个文档就类似于MySQL表中的多行数据居。

一个文档中,可以包含多个属性。类似于MySOL表中的一行数据存在多个列。

ES的RESTful语法

GET请求:

POST请求:

PUT请求:

DELETE请求:

Field类型

字符串类型:

  • text:一把被用于全文检索。将当前Field进行分词。
  • keyword:当前Field不会被分词。

数值类型:

  • long:
  • integer:
  • short:
  • byte :
  • double :
  • float:
  • half_float:精度比float小一半
  • scaled_float:根据一个long和scaled来表达一个浮点型,long-3455, scaled-100 -> 3.45

时间类型:

  • date类型,针对时间类型指定具体的格式

布尔类型:

  • boolean类型,表达true和false

二进制类型:

  • binary类型暂时支持Base64 encodestring

范围类型:

long_range:赋值时,无需指定具体的内容,只需要存储一个范围即可可,指定gt,lt

文档的操作

文档在ES服务中的唯一标识,_index,_type,_id三个内容为符合,锁定一个文档,

新建文档

自动生成id

POST /book/novel
{
    "name": "盘龙",
    "author": "我吃西红柿",
    "count": 100000,
    "on-sale": "2000-01-01",
    "descr": "嘻嘻嘻嘻呵呵呵呵呵阿哈哈哈哈啊哈哈哈哈抠脚大汉非空和四阶段分段所"
}

手动指定id

POST /book/novel/1
{
    "name": "盘龙",
    "author": "我吃西红柿",
    "count": 100000,
    "on-sale": "2000-01-01",
    "descr": "嘻嘻嘻嘻呵呵呵呵呵阿哈哈哈哈啊哈哈哈哈抠脚大汉非空和四阶段分段所"
}

修改文档

覆盖式修改【不推荐】

# 添加文档,手动指定id
PUT /book/novel/1
{
  "name": "红楼梦",
  "author": "曹雪芹",
  "count": 10000000,
  "on-sale": "1985-01-01",
  "descr": "水电费刻录机圣诞节开发老司机蝶恋蜂狂数据的类方式动静分离肯定是解放路口水电费来看第三方莱克斯顿分离式的非"
}

必须写全,否则没写的值为空

doc修改方式

POST /book/novel/1/_update
{
  "doc": {
    "count": "1234565"
  }
}

删除文档

# 根据id删除文档
DELETE /book/novel/_id

ES各种查询

term&terms查询

term 查询

代表完全匹配,搜索前不对关键字分词,直接去文档分词库匹配内容。

POST /sms_logs_index/sms_logs_type/_search
{
  "from": 0,
  "size": 5,
  "query": {
    "term": {
      "province": {
        "value": "北京"
      }
    }
  }
}

terms查询

terms和term的查询机制是一样,都不会将指定的查询关键字进行分词,直接去分词库中匹配,找到相应文档内容。terms是在针对一个字段包含多个值的时候使用。

term:where province=北京;

terms: where province=北京 or province=? or province=?

POST /sms_logs_index/sms_logs_type/_search
{
  "from": 0,
  "size": 5,
  "query": {
    "terms": {
      "province": [
         "北京","上海"
      ]
    }
  }
}

terms和term的查询机制是一样,都不会将指定的查询关键字进行分词。如果被查询的文档的内容被分词,这样就可能会出现查询不到的情况。

match查询

match 查询属于高层查询,他会根据你查询的字段类型不一样,采用不同的查询方式。

  • 查询的是日期或者是数值的话,他会将你基于的字符串查询内容转换为日期或者数值对待。
  • 如果查询的内容是一个不能被分词的内容 (keyword) ,match 查询不会对你指定的查询关键字进行分词。
  • 如果查询的内容时一个可以被分词的内容 (text) ,match 会将你指定的查询内容根据一定的方式去分词,去分词库中匹配指定的内容。

match 查询,实际底层就是多个 term 查询,将多个 term 查询的结果给你封装到了一起。

match_all查询

查询全部内容,不指定任何查询条件。

# match_all查询
POST /sms-logs-index/sms-logs-type/_search
{
  "query": {
    "match_all": {}
  }
}

match查询

指定一个Field作为筛选的条件

POST /sms-logs-index/sms-logs-type/_search
{
  "query": {
    "match": {
      "smsContent": "收货安装"
    }
  }
}

multi_match查询

match针对一个field做检索,multi_match针对多个field进行检索,多个field对应一个text

# multi_match 查询
POST /sms-logs-index/sms-logs-type/_search
{
  "query": {
    "multi_match": {
      "query": "北京",
      "fields": ["province","smsContent"]
    }
  }
}

其他查询

id查询

# id查询
GET/sms-logs-index/sms-logs-type/1

prefix查询

前缀查询,可以通过一个关键字去指定一个Field的前缀,从而查询到指定的文档。

#prefix 查询
POST /sms-logs-index/sms-logs-type/_search
{
  "query": {
    "prefix": {
      "corpName": {
        "value": "途虎"
      }
    }
  }
}

fuzzy查询

模糊查询,我们输入字符的大概,ES就可以去根据输入的内容大既去匹配一下结果。有错别字也可能ok

wildcard查询

通配查询,和MySQL中的like是一个套路,可以在查询时,在字符串中指定通配符*和占位符?

range查询

范围查询,只针对数值类型,对某一个Field进行大于或者小于的范围指定

# range 查询
POST /sms-logs-index/sms-logs-type/_search
{
  "query": {
    "range": {
      "fee": {
        "gt": 5,
        "lte": 10
        # 可以使用 gt: >, gte: >=, lt: <, 
      }
    }
  }
}

regexp查询

正则查询,通过你编写的正则表达式去匹配内容。

Ps :

prefix,fuzzy, wildcard 和regexp查询效率相对比较低,要求效率比较高时,避免去使用

深分页Scroll

ES对from+size是有限制的,from和size二者之和不能超过1W

原理:

ES查询数据的方式:

  • 第一步现将用户指定的关键进行分词。
  • 第二步将词汇去分词库中进行检索,得到多个文档的id。
  • 第三步去各个分片中去拉取指定的数据。
  • 第四步将数据根据score进行排序。
  • 第五步根据from的值,将查询到的数据舍弃一部分
  • 第六步返回结果。

Scroll在ES查询数据的方式:

  • 第一步现将用户指定的关键进行分词。
  • 第二步将词汇去分词库中进行检索,得到多个文档的id。
  • 第三步将文档的id存放在一个ES的上下文中。
  • 第四步根据你指定的size去ES中检索指定的数据,拿完数据的文档id,会从上下文中移除。
  • 第五步如果需要下一页数据,直接去ES的上下文中,I找后续内容容。

delete-by-query

根据term,match等查询方式去删除大量的文档

Ps :如果你需要删除的内容,是index下的大部分数据,推荐享创建一个全新的index,将保留的文档内容,添加到全新的 索引

复合查询

bool查询

复合过滤器,将你的多个查询条件,以一定的逻辑组合在一起...

  • must:所有的条件,用must组合在一起,表示And的意思
  • must_not:将must_not中的条件,全部都不能匹配,标识Not的的意思
  • should:所有的条件,用should组合在一起,表示0r的意思

boosting查询

boosting 查询是一种用于控制文档相关性得分的复合查询类型 ,主要用于实现对查询结果的 “微调”,通过提升某些匹配条件的文档相关性,同时降低其他匹配条件文档的相关性,从而使查询结果更符合业务需求。

boosting查询可以帮助我们去影响查询后的score。

  • positive:只有匹配上positive的查询的内容,才会被放到返回的结果集中
  • negative:如果匹配上和positive并且也匹配上了negative,就可以降低这样的文档score
  • negative_boost:指定系数,必须小于1.0

关于查询时,分数是如何计算的:

  • 搜索的关键字在文档中出现的频次越高,分数就越高
  • 指定的文档内容越短,分数就越高
  • 我们在搜索时,指定的关键字也会被分词,这个被分词的内容,被分词库匹配的个数越多,分数越高

filter查询

query,根据你的查询条件,去计算文档的匹配度得到一个分数,并且根据分数进行排序,不会做缓存的。

filter,根据你的查询条件去查询文档,不去计算分数,而且filter会对经常被过滤的数据进行缓存。

高亮查询

高亮查询就是你用户输入的关键字,以一定的特殊样式展示给用户,让用户知道为什么这个结果被检索出来。

高亮展示的数据,本身就是文档中的一个 Field,单独将 Field 以 highlight 的形式返回给你。

ES 提供了一个 highlight 属性,和 query 同级别的。

  • fragment_size:指定高亮数据展示多少个字符回来。
  • pre_tags:指定前缀标签,举个栗子 <font color="red">
  • post_tags:指定后缀标签,举个栗子 </font>
{
  "query": {
    "match": {
      "content": "ES 高亮"
    }
  },
  "highlight": {
    "fragment_size": 100,
    "pre_tags": "<mark>",
    "post_tags": "</mark>",
    "fields": {
      "content": {}
    }
  }
}

聚合查询

计数查询

{
    "size": 0, 
    "aggs": {
        "duplicate_logs": {
            "terms": {
                "field": "message.keyword",
                "size": 10
            }
        }
    }
}
  • size: 0:表示不返回搜索命中的文档,只关注聚合结果,这样可以减少不必要的返回数据量。
  • aggs(aggregations 的缩写):用于定义聚合操作。
  • duplicate_logs:是自定义的聚合名称,方便在结果中识别这个聚合操作。
  • terms 聚合:它会对指定字段(这里是 message.keyword,对于文本字段使用 .keyword 后缀表示按精确值聚合 )进行分组,统计每个唯一值出现的次数。
  • size: 10:表示只返回出现次数最多的前 10 个不同的日志消息内容及其对应的出现次数。

范围查询

统计一定范围内出现的文档个数,比如,针对某一个Field的值在0100,100200,200~300之间文档出现的个数分别是多少。

范围统计可以针对普通的数值,针对时间类型,针对jp类型都可以做相应的统计。

range,date_range,ip_range

统计聚合查询

他可以帮你查询指定Field的最大值,最小值,平均值,平方和。