Elasticsearch入门简单版

文章目录

Elasticsearch 入门与深入

2004年 Shay Banon 基于Lucene开发了 Compass

2010年 Shay Banon 重写了 Compass,取名 Elasticsearch

  • 查询性能好(Near Real Time)

  • 支持分布式,可水平扩展

  • 支持多语言的集成:降低全文检索的学习曲线,可以被任何编程语言调用

一、Elasticsearch介绍

1、主要功能

  • 海量数据的用户式存储以及集群管理

    • 服务与数据的高可用,水平扩展
  • 近实时搜索,性能卓越

    • 结构化 / 全文 / 地理位置 / 自动完成
  • 海量数据的近实时分析

    • 聚合功能

2、版本与升级

0.4:2010年2月第一次发布

1.0:2014年1月

2.0:2015年10月

5.0:2016年10月

6.0:2017年10月

7.0:2019年10月

新特性 5.x
  • Lucene 6.x,性能提升,默认打分机制从TF-IDF 改为 BM 25
  • 支持Ingest 节点 / Painless Scripting / Completion suggested 支持 / 原生的 Java REST 客户端
  • Type 标记成 deprecated,支持了 Keyword 的类型
  • 性能优化
    • 内部引擎移除了避免同一文档并发更新的竞争锁,带来 15% — 20% 的性能提升
    • Instant aggregation ,支持分片上聚合的缓存
    • 新增了 Profile API
新特性 6.x
  • Lucene 7.x
  • 新功能
    • 跨集群复制(CCR)
    • 索引生命周期管理
    • SQL 的支持
  • 更友好的升级及数据迁移
    • 在主要版本之间的迁移更为简化,体验升级
    • 全新的基于操作的数据复制框架,可加快恢复数据
  • 性能优化
    • 有效存储稀疏字段的新方法,将该地了存储成本(浓稠索引就是1对1,稀疏索引就是一对区间头)
    • 在索引时进行排序,可加快排序的查询性能
新特性 7.x
  • Lucene 8.0
  • 重大改进 - 正式废除当额索引下多 Type 的支持
  • 7.1 开始。Security 功能免费使用
  • ECK - Elasticsearch Operator on Kubernetes
  • 新功能
    • New Cluster coordination
    • Feature - Complete High level REST client
    • Script Score Query
  • 性能优化
    • 默认的 Primary Shard 数从 5 改为 1,避免 Over sharding
    • 性能优化,更快的 Top K

二、ELK 家族成员介绍

搜索类:继承数据库同步数据 / 独立作为数据存储使用(不推荐)

日志型:Logstash 和 Beats 满足不同的数据源,Kafka作为消息队列

Logstash

数据处理通道

https://www.elastic.co/cn/logstash

  • 开源的服务端数据处理管道,支持从不同来源采集数据,转换数据,并将数据发送到不同的存储库中、
  • Logstash 诞生于 2009 年,最初涌过来做日志的采集与处理
  • Logstash 创始人 Jordan Sisel
  • 2013 年被 Elasticsearch 收购

特性:

  • 实时解析和转换数据
    • 从 IP 地址破译出地理坐标
    • 将PII 数据匿名化,完全排除敏感字段
  • 可扩展
    • 200 多个插件 (日志 / 数据库 / Arcsigh / Netflow
  • 可靠性安全性
    • Logstash 会通过持久化队列来保证至少将运行中的事件送达一次
    • 数据传输加密
  • 监控
Kibana

可视化分析利器,web

https://www.elastic.co/cn/kibana

  • Kibana 名字的含义 = Kiwifruit + Banana
  • 数据可视化工具,帮助用户解开对数据的任何疑问
  • 基于 Logstash 的工具,2013年加入 Elastic 公司
Elastic
  • 2015 年 3 月收购 Elastic Cloud ,提供 Cloud 服务
  • 2015 年 3 月收购 PacketBeat
  • 2016 年 9月收购 PreAlert - Machine Learning 异常检测
  • 2017 年 6 月收购 Opbeat 进军 APM
  • 2017 年 11 月收购 SaaS 厂商 Swiftype,提供网站和 App 搜索
  • 2018 年 X-Pack 开源
Beats

清理的数据采集器

https://www.elastic.co/cn/beats

X-Pack

商业化套件

  • 6.3 之前的版本,X-Pack 以插件方式安装
  • X-Pack 开源之后,Elasticsearch & Kibana 支持 OSS版 和 Basic 两种版本
    • 部分 X-Pack 功能支持免费使用,6.8 和 7.1 开始,Security 功能免费
  • OSS,Basic,黄金级,白金级
  • https://www.elastic.co/cn/subscriptions

三、Elasticsearch安装和配置

下载地址:https://www.elastic.co/cn/downloads/elasticsearch

jdk11下载:https://download.java.net/java/GA/jdk11/13/GPL/openjdk-11.0.1_linux-x64_bin.tar.gz

can not run elasticsearch as root

# 创建用户
adduser elasticsearch01
# 创建密码
passwd elasticsearch01
# 给文件赋予权限
chown -R elasticsearch01 elasticsearch-6.0.0
# 切换用户
su elasticsearch01
# 后台启动
./elasticsearch -d

其他异常处理:https://blog.csdn.net/happyzxs/article/details/89156068

集群搭建:https://www.cnblogs.com/sanduzxcvbnm/p/12016216.html

  • 注意配置的的data和log 会有权限问题,需要自己处理一下
1、目录结构
目录配置文件描述
bin脚本文件,包括启动elasticsearch,安装插件。运行统计数据等
configelasticsearch.yml集群配置文件,user,role based 相关配置
JDKJava 运行环境
datapath.data数据文件
libJava类库
logspath.log日志文件
modules包含所有 ES 模块
plugins包含所有已安装插件
2、jdk配置建议
  • Xmx 和 Xms 设置成一样
  • Xmx 不要超过机器内存的50%
  • 不要超过 30 GB – http://www.elastic.co/blog/a-heap-of-trouble
3、插件安装
  • 查看1:elasticsearch-plugin list
  • 查看2:http://localhost:9200/_cat/plugins
  • 安装插件:./elasticsearch-plugin install analysis-icu
4、多节点启动
  • 多节点启动

    ./elasticsearch -E node.name=node1 -E cluster.name=elktest -E path.data=/tmp/es/node1_data -E http.port=9200 -d
    
    ./elasticsearch -E node.name=node2 -E cluster.name=elktest -E path.data=/tmp/es/node2_data -E http.port=9201 -d
    
    ./elasticsearch -E node.name=node3 -E cluster.name=elktest -E path.data=/tmp/es/node3_data -E http.port=9202 -d
    
  • 查看节点:http://localhost:9200/_cat/nodes

四、Kibana安装

下载地址:https://www.elastic.co/cn/downloads/kibana

其他操作类似elastic,例如插件安装等等

  • 汉化加入配置:i18n.locale: "zh-CN"
  • 后台启动:nohup ./kibana &
  • 访问地址:http://localhost:5601
  • 注意,如果是集群,需要指定集群配置,elasticsearch.hosts

五、Cerebro安装

elastic集群监控

软件地址:https://github.com/lmenezes/cerebro/releases

相关安装和操作教程:https://www.jianshu.com/p/433d821f9667

六、Logstash安装

JRuby开发的(一个采用纯Java实现的Ruby解释器,由JRuby团队开发)

下载地址:https://www.elastic.co/cn/downloads/logstash

  • movielens测试数据集

    例:Small: 100,000 ratings and 3,600 tag applications applied to 9,000 movies by 600 users. Last updated 9/2018.
    
    #修改movielens目录下的logstash.conf文件
    #path修改为,你实际的movies.csv路径
    input {
      file {
        path => "YOUR_FULL_PATH_OF_movies.csv"
        start_position => "beginning"
        sincedb_path => "/dev/null"
      }
    }
    
    #启动Elasticsearch实例,然后启动 logstash,并制定配置文件导入数据
    bin/logstash -f /YOUR_PATH_of_logstash.conf
    
  • logstash.conf文件内容

    input {
      file {
        path => "/usr/local/soft/logstash-7.3.2/bin/movies.csv"
        start_position => "beginning"
        sincedb_path => "/dev/null"
      }
    }
    filter {
      csv {
        separator => ","
        columns => ["id","content","genre"]
      }
    
      mutate {
        split => { "genre" => "|" }
        remove_field => ["path", "host","@timestamp","message"]
      }
    
      mutate {
    
        split => ["content", "("]
        add_field => { "title" => "%{[content][0]}"}
        add_field => { "year" => "%{[content][1]}"}
      }
    
      mutate {
        convert => {
          "year" => "integer"
        }
        strip => ["title"]
        remove_field => ["path", "host","@timestamp","message","content"]
      }
    
    }
    output {
       elasticsearch {
         hosts => ["http://192.168.165.14:9200", "http://192.168.165.15:9200", "http://192.168.165.16:9200"]
         index => "movies"
         document_id => "%{id}"
       }
      stdout {}
    }
    
  • 指定elasticsearch地址和端口

  • 启动:./logstash -f logstash.conf

Elasticsearch基本概念

一、名词介绍

1、文档

Document

  • Elasticsearch是面向文档的额,文档是所有可搜索数据的最小单位
    • 日志文件的日志项
    • 一本电影的基本信息 / 一张唱片的详细信息
    • MP3播放器里的一首歌 / 一篇 PDF 文档的具体内容
  • 文档会被序列化成 JSON 格式,保存再 Elasticsearch中
    • JSON 对象由字段组成
    • 每个字段都有对应的字段类型(字符串 / 数值 / 布尔 / 日期 / 二进制 / 范围类型)
  • 每个文档都有一个 Unique ID
    • 你可以自己指定ID
    • 或者通过 Elasticsearch 自动生成

2、JSON 文档

  • 一篇文档包含了一系列的字段。类似数据库表中以条记录
  • JSON 文档,格式灵活,不需要预先定义格式
    • 字段的类型可以指定或者通过 Elasticsearch 自动推算
    • 支持数组 / 嵌套
    • CSV file 转换为 JSON(使用logstash)

3、文档的元数据

元数据,用于标注文档的相关信息

{
  "_index" : "movies",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 19,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "year" : 1995,
    "title" : "Toy Story",
    "id" : "1",
    "genre" : [
      "Adventure",
      "Animation",
      "Children",
      "Comedy",
      "Fantasy"
    ],
    "@version" : "1"
  }
}
key描述
_index文档所属的索引名
_type文档所属的类型名
_id文档唯一id
_source文档的原始json数据
_all整合所有字段内容到该字段,已被废除
_version文档的版本信息
_score相关性打分

4、索引

{
  "movies" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "@version" : {...},
        "genre" : {...},
        "id" : {...},
        "title" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "year" : {...}
      }
    },
    "settings" : {
      "index" : {
        "creation_date" : "1588399246401",
        "number_of_shards" : "1",
        "number_of_replicas" : "1",
        "uuid" : "ZC8ASqi2Rr-MBgjXRXTIxw",
        "version" : {
          "created" : "7030299"
        },
        "provided_name" : "movies"
      }
    }
  }
}
  • index:索引是文档的容器,是一类文档的结合
    • index 体现了逻辑空间的概念:每个索引都有自己的 Mapping 定义,用于定义包含的文档的字段名和字段类型
    • Shard 体现了物理空间的概念:索引中的数据分散再 Shard 上
  • 索引的 Mapping 与 Settings
    • Mapping 定义文档字段的类型
    • Setting 定义不同的数据分布

5、关系型数据库和ES对应

RDBMSElasticsearch
Table表index(type)7.0开始,一个索引只能创建一个Type=_doc
Row行数据Doucment(具体的数据)
Column字段Field字段
Schema(表定义,Schema是数据库,瞎说)Mapping 索引信息
SQLDSL

6、简单API操作

# 查看索引相关信息(setting\mapping)
GET movies 
GET .kibana_task_manager

# 查看索引的文档总数
GET movies/_count

# 查看前10条文档,了解文档格式
POST kibana_sample_data_ecommerce/_search
{}
POST movies/_search
{}

//  _cat 相关api
# 查看 indeces
GET /_cat/indices/kibana*?v
GET /_cat/indices/kibana*?v&s=index
GET /_cat/indices?bytes=b&v
GET /_cat/indices?format=json&pretty

# 查看状态为绿的索引
GET /_cat/indices?v&health=green

# 按照文档的某个字段排序
GET /_cat/indices?v&s=docs.count:desc
GET /_cat/indices?v&s=store.size:asc

# 查看具体的字段
GET /_cat/indices/kibana*?pri&v&h=health,index,pri,rep,docs,count,mt

二、节点、集群、分片及副本

一个节点代表一个实例,多个节点组成一个集群

1、节点

  • 每个节点都有自己的名字,通过配置文件配置,或者启动过的时候 -E node.name=node1指定
  • 每个节点再启动之后,会分配一个UID,保存在data目录下
a、Master-eligible nodes 和 Master Node
  • 每个节点启动后,默认就是一个Master Node节点
    • 可以设置 node. master:false 禁止
  • Master-eligible 节点可以参加选主流程,成为Master 节点
  • 当第一个节点启动的时候,它会将自己选举成Mater节点
  • 每个节点都保存了集群的状态,只有Master 节点才能修改集群的状态信息
    • 集群状态(Cluster State),维护了一个集群中,必要的信息
      • 所有的节点信息
      • 所有的索引和相关的Mapping 与 Setting 信息
      • 分片的路由信息
    • 除了master 节点,其他节点不可以修改集群状态信息
b、Data node & Coordinating Node
  • Data Node

    • 可以保存数据的节点,叫做Data Node,负责保存分片数据。在数据扩展上起到了至关重要的作用。
  • Coordinating Node

    • 负责接受Client 的请求,将请求分发到合适的节点,最终把结果汇集到一起
    • 每个节点默认都起到了Coordinating Node 的职责
c、其他的节点类型
  • Hot & Warm Node
    • 不同硬件配置的 Data Node,用来实现 Hot & Warm 架构,降低集群部署的成本
  • Machine Learning Node
    • 负责跑 机器学习的 Job,用来做异常检测
  • Tribe Node
    • Tribe Node 连接到不同的Elasticsearch 集群,并且支持将这些集群当作一个单独的集群处理
    • 5.3开始使用 Cross Cluster Serarch
d、配置节点类型

开发环境一个节点承担多种校角色,生产环境中,应该设置单一的角色的节点。(瞎说,看实际情况)

节点类型配置参数默认值
master eligiblenode.masterture
datanode.datature
ingestnode.ingestture
coordinating only每个节点默认都是 coordinating 节点。设置其他类型全部为false
machine learningnode.mltrue (需 enable x-parck)

2、分片/副本

Primary Shard & Replica Shard

  • 主分片

    用以解决数据水平扩展的问题。通过分片,可以将数据分布到集群内的所有节点上

    • 一个分片是一个运行的 Lucene 的实例
    • 主分片数在索引创建时指定,后续不允许修改,除非Reindex
  • 副本

    用以解决数据高可用的问题。分片是主分片的拷贝

    • 副本分片数,可以动态的调整
    • 增加副本数,还可以在一定程度上提高服务的可用性(读取的吞吐)
  • 对于生产环境中分片的设定,需要提前做好容量规划

    • 分片数设置过小
      • 导致后续无法增加节点实现水品扩展
      • 单个分片的数据量过大,导致数据重新分配耗时
    • 分片数设置过大(默认主分片设置成1,解决了over-sharding的问题)
      • 影响搜索结果的相关性打分,影响系统结果的准确性
      • 单个节点上过多的分片,会导致资源浪费,同时也会影响性能

3、集群信息查看

  • GET _cluster/health

    • Green:主分片与副本都正常分配
    • Yellow:主分片全部正常分配,有副本分片未能正常分配
    • Red:有主分片未能分配
      • 例如,当服务器的磁盘容量超过 85% 时,去创建了一个新的索引。
  • GET _cat/nodes

三、文档CRUD

1、普通CRUD操作

indexPUT users/_doc/1
{“user”:“Mike”,“post_data”:“2020-05-03T14:29:12”,“message”:“trying out Kibana”}
指定id,如果id已经存在,删除原来的 再创建新的,版本信息+1
createPOST users/_doc
{“user”:“Jack”,“post_data”:“2020-05-03T14:29:12”,“message”:“trying out Kibana”}

PUT users/_doc/1?op_type=create
{“user”:“Jack”,“post_data”:“2020-05-03T14:32:12”,“message”:“trying out Kibana”}
自动生成_id

如果_id已经存在,会失败
getGET users/_search

GET users/_doc/1
查看索引前十条记录

根据id查询文档
updatePOST users/_update/1/
{“doc”:{“post_data”:“2020-05-03T14:44:12”,“message”:“trying out Elasticsearch”,“test”:652}}
文档增加/修改字段
doc 是关键语法,payload需要包含再doc
指定id不存在报错
deleteDELETE users/_doc/1删除指定_id

2、批量操作_bulk

  • 支持再一次API调用中,对不同的索引进行操作
  • 支持四种类型操作
    • index
    • create
    • update
    • delete
  • 可以再URL中指定 index,也可以再请求的 Payload 中进行
  • 操作中单条失败,并不会影响其它结果
  • 返回结果包括了每一条操作执行的结果

例:

POST _bulk
{"index":{"_index":"users","_id":"1"}}
{"user":"qilou","test":520}
{"delete":{"_index":"users2","_id":3}}
{"create":{"_index":"users2","_id":4}}
{"field1":"qilou","field2":"520"}
{"update":{"_id":"4","_index":"users"}}
{"doc":{"field1":"qilou","field2":"520"}}
# 上面有index delete create update

3、批量读取_mget

批量操作,可以减少网络连接所产生的开源,提高性能

GET _mget
{"docs":[{"_index":"users","_id":11},{"_index":"movies","_id":4}]}

4、批量查询_mserch

  • 都是关键字,例如 from 代表开始索引,size 代表从from开始查询多少条
  • index 是查询条件,作用于下一条query查询语句的
POST kibana_sample_data_ecommerce/_msearch
{}
{"query":{"match_all":{}},"from":0,"size":10}
{}
{"query":{"match_all":{}},"size":10}
{"index":"twitter2"}
{"query":{"match_all":{}}}

5、常见错误返回结果

问题原因
无法连接网络故障或集群挂了
连接无法关闭网络故障或节点出错
429集群过于繁忙
4XX请求体格式有错
500集群内部错误

四、倒排索引

。。。

五、Analysis

文本分析是把全文本转换一系列单词(term / token)的过程,也叫分词

Analysis 是通过Analyzer 来实现的

数据写入和查询时采用的分析器需要相同

1、Analysis组成

  • Character Filters(针对原始文本处理,例如去除html)
  • Tokenizer(按照规则切分为单词)
  • Token Filter(将切分的单词进行加工,小写,删除stopwords,增加同义词)

2、Elasticsearch的分词器

​ ===========================================================

elasticsearch内置的分词器

​ ===========================================================

  • standard Analyzer 默认分词器,按词切分,小写处理

  • simple Analyzer 按照非字母切分(符号被过滤,非字符的都被去除),小写处理

  • stop Analyzer 按照非字母切分(符号被过滤,非字符的都被去除),小写处理,停用词过滤(the,a,is)

  • whitespace Analyzer 按照空格切分,不转小写

  • keyword Analyzer 不分词,直接将输入做输出

  • pattern Analyzer 正则表达式,默认 \W+ (非字符分隔)

  • language 提供了30 多种常见语言的分词器

    • arabic、armenian、basque、bengali、brazilian、bulgarian、catalan、cjk、czech、danish、dutch、english、finnish、french、galician、german、greek、hindi、hungarian、indonesian、irish、italian、latvian、lithuanian、norwegian、persian、portuguese、romanian、russian、sorani、spanish、swedish、turkish、thai。
  • customer Analyzer 自定义分词器

    ===========================================================

    ===========================================================

    相关的中文分词器

    ===========================================================

  • icu_analyzer 中文分词器

    • 需要安装plugin:elasticsearch-plugin install analysis-icu
    • 提供了 Unicode 的支持,更好的支持亚洲语言
  • IK 中文分词器

    • 支持自定义词库,支持热更新分词字典
    • https://github.com/medcl/elasticsearch-analysis-ik
  • THULAC 中文分词器

    • THU Lexucal Analyzer for chinese,清华大学自然语言处理和社会人文计算实验室的一套中文分词器
    • https://github.com/microbun/elasticsearch-thulac-plugin

3、测试分词器

# 使用分词器测试
GET /_analyze
{
  "analyzer": "stop",
  "text": "Mastering Elasticsearch,elasticsearch in Action"
}

六、Search API

URI Search

  • 在URL 中使用查询参数

Request Body Search

  • 使用Elasticsearch 提供的,基于 JSON 格式的更加完备的 Query Domain Specific Language (DSL)
  • 查询指定的索引

    语法范围
    /_search在集群上的所有索引查询,默认前10个文档
    /index1/_search同上,只是在指定的索引index1中查询
    /index1,index2/_search同上,只是在指定的索引index1和index2中查询
    /index*/_search同上,只是在以index开头的索引中查询,通配符

1、初体验

  • URL查询

    • 使用 “q” ,指定查询字符串

      • query string syntax,KV键值对

        curl -XGET "http://192.168.165.14:9200/kibana_sample_data_ecommerce/_search?q=customer_first_name:Eddie"
        
  • Request Body

    • 支持POST和GET

      curl -XGET "http://192.168.165.14:9200/kibana_sample_data_ecommerce/_search" -H'Content-Type:application/json' -d'{"query":{"match_all":{}}}'
      

2、URL Search

GET /movies/_search?q=2012&df=title,year&sort=year:desc&from=0&size=10&timeout=1s
{
  "profile": true
}
  • q 指定查询语句,使用 Query String Syntax
    • 也可以直接q=title:2012 直接用k:v查询,要在多个字段查询,可以直接用df
  • df 默认字段,不指定是所有字段中查询
  • sort 排序 / from 和size 用于分页
  • profile 可以查看查询时如何被执行的
a、Query String Syntax
  • 指定字段 v.s 范查询
    • q=title:2012
  • Term v.s Phrase(布尔条件)
    • q=title:Hello World 等效于 Hello OR World。
    • q=title:“Hello World” 等效于 Hello AND World。Phrase 查询,还要求前后顺序保持一致
  • 分组与引号
    • q=title:(beautiful AND mind)
    • q=title:“beautiful mind”
  • 布尔操作(尽量用括号括起来哈)
    • AND / OR / NOT 或者 && / || / !
      • 必须大写
      • q=title:(beautiful NOT nihao)
    • 分组
      • + 表示 必须
      • - 表示必须没有
      • q=titile:(+beautiful -mind)
      • 注意:自己测试
  • 范围查询
    • 区间表示:[] 闭区间,{}开区间,{}一定要用分组() 不然报错。

      [] 闭区间,包含它

      {}开区间,不包含

      • q=year:({2016 TO 2018}) 等同q=year:2017
      • q=year:[* TO 2010] 等同于<=2010
  • 算数符号
    • q=year:>2010
    • q=year:(>2010 AND<=2018) 。本人测试,这个用&& 会报语法错误
    • q=year:(+>2010 +<=2018) 这种写法没问题,但是,我就想问没逻辑的?year字段里面同时有2010和2018。脑子瓦特了。真的忍无可忍。讲的不清不楚,完全自己测试。浪费学习时间。花钱算是白花了
  • 通配符查询
    • ? 代表1个字符,* 代表0或多个字符
    • q=title:mi?d
    • q=title:be*
  • 正则表达
    • title:[bt]oy
  • 模糊匹配与近似查询
    • q=title:beautifl~1
      • 上面的意思就是和beautifl词差别在1个(含)之内
    • q=title:“lord rings”~2
      • 上面就是两个词之间最多2个(含)以下组合的都符合条件
        • “Lord of the Rings, The”,这个就服务,中间时2个词,没超过

2、Request Body Search

将查询语句通过 HTTP Request Body 发送给 Elasticsearch

Query DSL

POST /movies,404_idx/_search?ignore_unavailable=true
{
  "profile": true,
  "query": {
    "match_all": {}
  }
}
a、分页-from/size
  • 从from开始,返回20个数据,默认10个结果。获取越靠后的翻页成本较高
POST /movies/_search
{
  "from": 100,
  "size": 20,
  "query": {
    "match_all": {}
  }
}
b、排序-sort

最好在数字型和日期型字段上排序

POST /movies/_search
{
  "sort": [{"year": {"order": "desc"}}],
  "from": 100,
  "size": 20,
  "query": {
    "match_all": {}
  }
}

##################或者,这种更精简,推荐用下面这种#######
POST /movies/_search
{
  "sort": [{"year":"desc"},{"_id":"desc"}],
  "from": 100,
  "size": 20,
  "query": {
    "match_all": {}
  }
}
c、字段过滤-_source
  • 只显示year_i开头字段的数据,支持通配符
POST /movies/_search
{
  "_source": ["year","title"],  
  "sort": [{"year":"desc"},{"_i*":"desc"}],
  "from": 100,
  "size": 20,
  "query": {
    "match_all": {}
  }
}
d、脚本字段-script_fields
  • 对字段order_date的值与’hello’进行拼接,然后返回新的字段名为“new_field”,在元信息的fields里面
  • fields元信息和_source元信息同级。(实在不明白请看下面的相应信息,明白的可以跳过)
{
  "script_fields": {
    "new_field": {
      "script": {
        "lang": "painless",
        "source": "doc['order_date'].value+'hello'"
      }
    }
  },
  "_source": [
    "order_date",
    "order_id"
  ],
  "from": 10,
  "size": 1,
  "query": {
    "match_all": {}
  }
}
  • 返回结果
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4675,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "kibana_sample_data_ecommerce",
        "_type" : "_doc",
        "_id" : "INnh2HEBko7oswXuqL26",
        "_score" : 1.0,
        "_source" : {
          "order_date" : "2020-05-11T10:46:34+00:00",
          "order_id" : 727381
        },
        "fields" : {
          "new_field" : [
            "2020-05-11T10:46:34.000Zhello"
          ]
        }
      }
    ]
  }
}
e、使用查询表达式 query的match
  • 查询title中有 hello 或者 word单词的
POST /movies/_search
{
  "query": {
    "match": {
      "title": "hello word"
    }
  }
}
  • 查询title 有hello 和world 的结果
POST /movies/_search
{
  "query": {
    "match": {
      "title": {
        "query": "hello world",
        "operator": "and"
      }
    }
  }
}
f、短语搜索 query的match_phrase
  • 查询title字段中有one love的结果,位置必须是这样不能是 one I love
POST /movies/_search
{
  "query": {
    "match_phrase": {
      "title": {
        "query": "one love"
      }
    }
  }
}
  • 查询title字段中有one love的结果,slop代表他们中间可以有几个词,此时 one I love 就符合结果了
POST /movies/_search
{
  "query": {
    "match_phrase": {
      "title": {
        "query": "one love",
        "slop": 1
      }
    }
  }
}

3、Query String Query

主要是query里面支持的查询方式

之前已经讲了matchmatch_phrase以及match_all

a、query_string
  • 在单个字段下查询
POST movies/_search
{
  "query": {
    "query_string": {
      "default_field": "title",
      "query": "hello NOT word"
    }
  }
}
  • 在多个字段下,查询
POST movies/_search
{
  "query": {
    "query_string": {
      "fields": ["title","genre"],
      "query": "(hello AND word) OR (beautiful && +Girls)"
    }
  }
}
b、simple_query_string

类似query_string,但是会忽略语法错误,只支持部分查询语句

  • 不支持AND OR NOT,会当作字符串处理
  • 不支持&&等,会当作特殊符号给排除了
  • 单词之间默认关系是OR,指定default_operator
  • 支持用 ±| 代替 AND OR NOT
  • 查询单词hello并且不包含word的标题
POST movies/_search
{
  "query": {
    "simple_query_string": {
      "query": "(+hello -word)",
      "fields": ["title"],
      "default_operator": "AND"
    }
  }
}

七、Mapping和常见字段

Mapping 类似数据库中的 表的定义,作用如下:

  • 定义索引中的字段的名称
  • 定义字段的数据类型,例如字符串,数字,布尔……
  • 字段,倒排索引的相关配置(Analyzed or Not Analyzed,Analyzer)

Mapping 会把 JSON 文档映射成 Lucene 所需要的扁平格式。

7.0之前每个mapping都有一个type,7.0之后不需要在mapping中定义指定type信息

1、字段的数据类型

a、简单类型
  • text / keyword
  • date
  • integer / floating
  • boolean
  • ipv4 & ipv6
b、复杂类型-对象和嵌套对象
  • 对象类型 / 嵌套类型
c、特殊类型
  • geo_point & geo_shape / percolator

2、Dynamic Mapping

  • 在写入文档的瘦,如果索引不存在,会自动创建索引

  • Dynamic Mapping 的机制,使得我们不用手动定义Mapping,Elasticsearch可以自动推算出字段的类型

  • 但是有的时候也会推算不对,例如地址位置信息

  • 当类型设置不对的时候会导致一些功能无法正常运行,例如 Range 查询

  • # 查看mapping
    GET movies/_mapping
    
a、类型自动识别
JSON类型Elasticsearch类型
字符串匹配日期格式,设置成Date
匹配数字设置为 float 或者 long ,该选项默认关闭
设置为text,并且增加keyword字段
布尔值boolean
浮点数float
整数long
对象properties 也就是object
数组由第一个非空数值的类型所决定,如果是string 那么就是字符串类型
空值忽略
  • 测试
PUT mapping_test/_doc/1
{
  "uid": "123",
  "name": "lilei",
  "create_date": "2019-10-10T22:11:22+00:00",
  "isVip": false,
  "isAdmin": "true",
  "age": 22,
  "heigh": "180",
  "money": 12.3,
  "ip":"192.168.1.11",
  "language": [
    "java",
    "python"
  ],
  "children": {
    "number": 3
  },
  "geoip": {
    "lon": 31.3,
    "lat": 30.1
  }
}
# uid 是text类型
# name 是text类型
# create_date  是date类型
# isVip 是boolean类型
# isAdmin 是text类型
# age 是long类型
# height 是text类型
# money 是float类型
# ip 是 text类型
# language 是text类型,根据第一个值推断的类型
# children 是properties 也就是object类型
# geoip 是properties 也就是object类型,这也就是地理位置推算有问题的地方
b、Mapping的dynamic设定

不支持对已有字段类型进行改变,如果必须改变,就只能Reindex API来重建索引了

  • 设置Mapping,默认是true
PUT dynamic_mapping_test/_mapping
{
  "dynamic": false
}
设置文档索引字段索引Mapping更新描述
“true”YESYESYES一旦有新增字段的文档写入,Mapping也同时被更新
“false”YESNONO一旦有新增字段的文档写入,Mapping不会更新
新增的字段数据,也无法被索引,新增字段被丢弃
“strict”NONONO新增字段时,数据写入直接出错
  • 新增字段
PUT dynamic_mapping_test/_doc/1
{
  "newField":"someValue"
}

3、Mapping设置及常见参数

创建一个Index

PUT test_users
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "age": {
        "type": "integer"
      },
      "mobile": {
        "type": "long"
      }
    }
  }
}
a、自定义Mapping的建议
  • 可以参考 API 手册,纯手写
  • 为了减少输入的工作量,减少出错的概率,可以按照如下
    • 创建一个临时的 index,写入一些样本数据
    • 通过访问Mapping API 获得该临时文件的动态 Mapping 定义
    • 修改后用,使用该配置创建你的索引
    • 删除临时索引,避免类型人工推断错误。
b、设置某字段是否可被索引

index参数

  • 创建时可以设定字段是否被索引,默认都是true,注意只是不能被索引(使用会报错),不是不可见
PUT test_users
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "age": {
        "type": "integer"
      },
      "mobile": {
        "type": "long",
        "index": false
      }
    }
  }
}
c、设置倒排索引记录的内容

index_options 参数

PUT test_users
{
    "mappings": {
       "properties": {
         "name": {
           "type": "text"
         },
         "age": {
           "type": "integer"
         },
         "mobile": {
           "type": "long",
           "index": false
         },
         "bio": {
           "type": "text",
           "index_options": "docs"
         }
       }
    }
}
  • 四种级别
    • docs 记录doc id
      freqs 记录doc id 和 term frequencies
      positions 记录doc id 和 term frequencies / term position
      offsets 记录 doc id 和 term frequencies / term position / character offects
  • text类型默认记录 positions,其他默认为docs

  • 记录内容越多,占用存储空间越大

d、对null值实现搜索

null_value参数

只有keyword 类型支持设定 null_value,只有设置了才能支持"NULL"的搜索

  • 设置

    PUT test_users
    {
      "mappings": {
        "properties": {
          "name": {
            "type": "text"
          },
          "age": {
            "type": "integer"
          },
          "mobile": {
            "type": "long",
            "index": false
          },
          "bio": {
            "type": "text",
            "index_options": "docs"
          },
          "nullvalue":{
            "type": "keyword",
            "null_value": "NULL"
          }
        }
      }
    }
    
  • 添加数据时,传入null
    POST test_users/_doc/1
    {
      "name":"li,.ei",
      "age":123,
      "mobile":1234412313,
      "bio":123123,
      "nullvalue": null
    }
    
  • 查询数据时,查询NULL
    GET test_users/_search
    {
      "query": {"query_string": {
        "default_field": "nullvalue",
        "query":"NULL"
      }}
    }
    
e、copy_to设置

_all 在 7 中被 copy_to所代替

  • 用于满足一些特定的搜索
  • 通过配置。可以让搜索的时候聚合到多个字段
  • copy_to的字段不会出现在查询结果的_source中
  • 测试 新建索引 时指定copy_to字段
    PUT test_users
    {
      "mappings": {
        "properties": {
          "firstName": {
            "type": "text",
            "copy_to": "fullName"
          },
          "lastName": {
            "type": "text",
            "copy_to": "fullName"
          }
        }
      }
    }
    
  • 添加数据,注意默认的词法分析,中文是一个字一个哦。。
    POST test_users/_doc/1
    {
      "firstName":"李",
      "lastName":"雷"
    }
    # 测试上面的查询,注意注意,中文是一个字一个词。。。
    GET test_users/_search?q=fullName:(李 AND 雷)
    
    POST test_users/_search
    {
      "query": {
        "query_string": {
          "default_field": "fullName",
          "query": "李 AND 雷"
        }
      }
    }
    

4、多字段类型

后面自己去查询。这人的视频。。真无语。 看着头大。乱七八糟的。

好像就是子字段。。

5、精确值和全文本

exact_value

  • 包括数字 / 日志 / 具体的一个字符串(例如 App Store一个整体)
    • elasticsearch中的 keyword
    • 精确值不会分词。就是一个整体

full text

  • 全文本,非结构化的文本数据
    • elasticsearch中的 text,会根据分词器进行分词

八、自定义分词

当 Elasticsearch 自带的分词器无法满足时,可以自定义分词器。通过自组合不同的组件来实现:

  • Character Filter(针对原始文本处理,例:去除html)
  • Tokenizer(按照规则切分为单词)
  • TokenFilter(将切分的单词进行加工,小写,删除stopwords,增加同义词)

1、Character Filters

  • 在 Tokenizer 之前对文本进行处理,例如增加删除及替换字符。可以配置多个Character Filters。会影响 Tokenizer 的 position 和 offset 信息

  • 一些自带的 Character Filters

    • html_strip 去除 html 标签
      POST _analyze
      {
        "tokenizer": "keyword",
        "char_filter": ["html_strip"],
        "text": ["<b>hello world</b>"]
      }
      
      mapping 字符串替换
      # 中划线替换成下划线
      POST _analyze
      {
        "tokenizer": "standard",
        "char_filter": [
          {
            "type": "mapping",
            "mappings": ["- => _"]
          }
        ],
        "text": "test-id,123-456! test-900 650-423-1234"
      }
      
      # 表情符号替换成英文
      POST _analyze
      {
        "tokenizer": "standard",
        "char_filter": [
          {
            "type": "mapping",
            "mappings": [":) => happy",":( => sad"]
          }
        ],
        "text": ["I am felling :)","Feeling : :( today"]
      }
      
      pattern replace 正则匹配替换
      # 正则匹配,留下$1。。。
      POST _analyze
      {
        "tokenizer": "standard",
        "char_filter": [
          {
            "type": "pattern_replace",
            "pattern": "http://(.*)",
            "replacement": "$1"
          }
        ],
        "text": "http://www.elastic.co"
      }
      
      

2、Tokenizer

  • 将原始的文本按照一定的规则,切分为词(term or token)

  • elasticsearch 内置的 Tokenizer
    • whitespace / standard / uax_url_email / pattern / keyword / path hierarchy

      • path_hierarchy 测试用例 - 按照url拆分
        
        POST _analyze
        {
          "tokenizer": "path_hierarchy",
          "text": "/usr/local/soft/elasticsearch"
        }
        # /usr
        # /usr/local
        # /usr/local/soft
        # /usr/local/soft/elasticsearch
        
      • whitespace测试用例 - 空格拆分
        # 按照空格拆分
        POST _analyze
        {
          "tokenizer": "whitespace",
          "text": ["The rain in Spain falls mainly on the plain."]
        }
        
  • 可以用Java开发插件,实现自己的 Tokenizer

3、Token Filters

注意传递多个,一定要注意先后顺序

  • 将 Tokenizer 输出的单词(term),进行增加、修改、删除

  • 自带的 Token Filters
    • lowercase / stop / synonym(添加近义词)

      • stop和lowercase 测试用例 - 空格拆分 且 去掉停用词
        # The 虽然也是停用词,但是会保留。因为是大写,因为只会去掉是小写的停用词
        POST _analyze
        {
          "tokenizer": "whitespace",
          "filter": [
            "stop"
          ],
          "text": [
            "The rain in Spain falls mainly on the plain."
          ]
        }
        
        # 这个就是把不管大写小写的停用词都去掉,先小写,再去停用词
        POST _analyze
        {
          "tokenizer": "whitespace",
          "filter": [
            "lowercase","stop"
          ],
          "text": [
            "The rain in Spain falls mainly on the plain."
          ]
        }
        

4、设置一个Custom Analizer

可以在创建索引的时候设置一个自定义的分词器

只需要再settings里面设置好

a、创建自定义Analizer
PUT my_index
{
  "mappings": {},
  "settings": {
    "analysis": {
      "analyzer": {
        "my_custom_analyzer_自定义名": {
          "type": "custom",
          "char_filter": [
            "emoticons_自定义名"
          ],
          "tokenizer": "punctuation_自定义名",
          "filter": [
            "lowercase",
            "english_stop_自定义名"
          ]
        }
      },
      "tokenizer": {
        "punctuation_自定义名": {
          "type": "pattern",
          "pattern": "[ .,!?]"
        }
      },
      "char_filter": {
        "emoticons_自定义名": {
          "type": "mapping",
          "mappings": [
            ":) => _happy_",
            ":( => _sad_"
          ]
        }
      },
      "filter": {
        "english_stop_自定义名": {
          "type": "stop",
          "stopwords": "_english_"
        }
      }
    }
  }
}
b、测试自定义分词器
POST my_index/_analyze
{
  "analyzer": "my_custom_analyzer_自定义名",
  "text": ["I'm a :) person, and you?"]
}

九、自定义索引模板

集群上的索引会越来越多,例如,我们会对日志每天创建一个索引

  • 使用多个索引可以让我们更好的管理数据,提高性能
  • logs-2020-05-01
  • logs-2020-05-02
  • logs-2020-06-03

1、index template

  • Index template 帮助我们设定 mapping 和 settings,并按照一定过的规则,自动匹配到新创建的索引之上
    • 模板仅在一个索引被创建时,才会产生作用。修改模板不会影响已创建的索引。
    • 可以设定多个模板,这些设置会被 “merge” 在一起
    • 可以指定 “order” 的数值,控制 “merging” 的过程
    • GET _template/* 或 GET _template 查看所有模板

2、索引模板案例

  • 创建任何索引的时候,会设定分片为1,副本为1
PUT _template/template_default
{
  "index_patterns": ["*"],
  "order": 0,
  "version": 1,
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1
  }
}

# 测试模板
POST romdon_test/_doc/1
{
  "name":"李磊",
  "create_date":"2019-10-10T22:11:22+00:00",
  "age":"123"
}
# name 是text类型
# create_date 是date类型
# age 是text类型
  • 创建以test开头的索引,会设定分片为1,副本为2
  • 同时会把日期格式的探测关闭,数字的探测打开(数字探测默认是关闭)
PUT _template/template_test
{
  "index_patterns": ["test*"],
  "order": 1,
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 2
  },
  "mappings": {
    "date_detection": false,
    "numeric_detection": true
  }
}

# 测试模板
POST test_heihei/_doc/1
{
  "name":"李磊",
  "create_date":"2020-05-06T22:11:22+00:00",
  "age":"123"
}
# name 是text类型
# create_date 是text类型
# age 是long类型

3、索引模板的工作方式

  • 当一个索引被创建时
    • 1、应用elasticsearch 默认的 setting 和mappings
    • 2、应用 order 数值低的 index template 中的设定
    • 3、应用 order 数值高的 index template 中的设定,之前的索引设置相同的会被覆盖
    • 4、应用创建索引时,用户自定义的 setting 和mappings ,之前的索引模板设置相同的会被覆盖

4、动态字段模板

根据 Elasticsearch 识别的数据类型,结合字段名称,来动态设定字段类型

  • 所有的字符类型都设定成 keyword,或者关闭keyword字段
  • is 开头的字段都设置成 boolean 类型
  • long_开头的都设置成long 类型
  • 定义在某个索引的mappings中
    • template有名称、匹配规则是数组、为匹配到的字段设置mapping
    • match_mapping_tyoe:匹配自动识别的字段类型,string,boolean等
    • match,unmatch:匹配字段名
    • path_match,path_unmatch:
    • 注意数组的顺序,还有数组里面都是用的{},dynamic_templates、strings_as_boolean等都是关键字
  • 测试1,string转为boolean,根据名字前缀的正则
PUT my_test_index3
{
  "mappings": {
    "dynamic_templates": [
      {
        "strings_as_boolean_自定义": {
          "match_mapping_type": "string",
          "match": "is*",
          "mapping": {
            "type": "boolean"
          }
        }
      },
      {
        "strings_as_keyword_自定义": {
          "match_mapping_type": "string",
          "mapping": {
            "type": "keyword"
          }
        }
      }
    ]
  }
}

# 测试
POST my_test_index3/_doc/1
{
  "isVIP":"true",
  "name":"lilei"
} 
  • 测试2 自动把正则组成成一个copy_to
 
PUT my_test_index1
{
  "mappings": {
    "dynamic_templates": [
      {
        "full_name": {
          "path_match": "name.*",
          "path_unmatch": "*.middle",
          "mapping": {
            "type": "text",
            "copy_to": "full_name"
          }
        } 
      }
    ]
  }
}
# 测试 ,注意正则里面是name这个对象。
PUT my_test_index1/_doc/1
{
  "name": {
    "first":  "John",
    "middle": "Winston",
    "last":   "Lennon"
  }
}

GET my_test_index1

GET my_test_index/_search?q=full_name:John
GET my_test_index/_search?q=full_name:Winston  # 这个就没有被copy_to

十、聚合

就是语句支持统计分析。。。I fuck you

1、聚合的分类

  • Bucket Aggregation 一些列满足特定条件的文档的集合

    • 支持很多类型的Buccket,例如Term & Range (时间 / 年龄区间 / 地理位置)

    • 测试,查询航班目的地的统计信息,结果不在hits里,而在同级的aggregations中
      GET kibana_sample_data_flights/_search
      {
        "size": 0,
        "aggs": {
          "fligth_dest_自定义名字": {
            "terms": {
              "field": "DestCountry_待分组的字段"
            }
          }
        }
      }
      
  • Metric Aggregation 一些数学运算,可以对文档字段进行统计分析

    基于数据集计算结果,除了支持在字段上进行计算,同样也支持在脚本(painless script)产生的结果上进行计算

    • 大多数 metric 是数学计算,仅输出一个值
      • min / max / sum / avg / cardinality
    • 部分 metric 支持输出多个数值
      • stats / percentiles / percentile_ranks
    • 测试1,查看航班目的地的统计信息,增加均价,最高最低价格
      GET kibana_sample_data_flights/_search
      {
        "size": 0,
        "aggs": {
          "fligth_dest_自定义名字": {
            "terms": {
              "field": "DestCountry"
            },
            "aggs": {
              "average_proce_自定义": {
                "avg": {
                  "field": "AvgTicketPrice"
                }
              },
              "max_price_自定义": {
                "max": {
                  "field": "AvgTicketPrice"
                }
              },
              "min_price_自定义": {
                "min": {
                  "field": "AvgTicketPrice"
                }
              }
            }
          }
        }
      }
      
    • 测试2,查看航班目的地的统计信息,平均票价,以及天气状况
      GET kibana_sample_data_flights/_search
      {
        "size": 0,
        "aggs": {
          "flight_dest_自定义": {
            "terms": {
              "field": "DestCountry"
            },
            "aggs": {
              "average_price_自定义": {
                "avg": {
                  "field": "AvgTicketPrice"
                }
              },
              "weather_自定义": {
                "terms": {
                  "field": "DestWeather"
                }
              }
            }
          }
        }
      }
      
  • Pipeline Aggregation 对其他的聚合结果进行二次聚合

  • Matrix Aggregation 支持对多个字段的操作并提供一个结果矩阵

Elasticsearch深入搜索

Elasticsearch分布式特性及分布式搜索机制

Elasticsearch深入聚合分析

Elasticsearch数据建模

Elasticsearch保护你的数据

Elasticsearch水平扩展Elasticsearch集群

Elasticsearch生产环境的集群运维

Elasticsearch索引生命周期的管理

用Logstash 和 Beats 构建数据管道

用Kibana 进行数据可视化分析

探索 X-park 套件

实战1:电影搜索服务

实战2:stackoverflow用户调查问卷分析

Elastic认证

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值