Elasticsearch超详细笔记

Elasticsearch超详细笔记

引言:

          本文主要分享了有关Elasticsearch(简称ES)的知识,包括:ES的简介、基本概念、倒序索引、ES的安装以及使用、Kibana可视化工具的安装与使用、分词的使用、使用可视化工具Kibana实现索引和文档的增删查改、以及一些高级的ES查询,如:批量获取文档信息、使用Bulk API实现批量操作、采用乐观锁机制实现并发控制、Mapping、通用查询(分词查找、短语查询、返回指定字段、高亮查询、范围查询 )、Bool过滤查询、范围查询、聚合查询等等;

1. Elasticsearch简介

          Elasticsearch 是一个开源的搜索引擎, 建立在全文搜索引擎库 Apache Lucene 基础上;内部使用 Lucene 做索引与搜索,但是它的目的是使全文检索变得简单,通过隐藏 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTFUL API;

Elasticsearch 不仅仅只是一个全文搜索引擎是一个分布式的实时文档存储,每个字段可以被索引与搜索可以作数据库用;还是一个分布式实时分析搜索引擎,能胜任上百个服务节点的扩展,并支持PB级别(大数据级别)的结构化(定死的,进去多少出来多少,多余的全部抛弃)或者非结构化数据(只需要直到其属性即可);

1.1 衍生的开源软件

  • Elasticsearch :分布式搜索引擎
  • Logstash:日志的采集与解析工具
  • Kibana:可视化分析平台
  • Beats:数据采集工具家族(替换Logstash)
  • X-Pack:功能包

1.2 ES特性

  1. 速度快、易扩展、弹性、灵活、操作简单、多语言客户端
  2. 分布式:横向扩展非常灵活
  3. 全文检索:基于lucene的强大的全文检索能力;
  4. **近实时搜索和分析:**数据进入ES,可达到近实时搜索,还可进行聚合分析
  5. 高可用:容错机制,自动发现新的或失败的节点,重组和重新平衡数据
  6. 模式自由:ES的动态mapping机制可以自动检测数据的结构和类型,创建索引并使数据可搜索。
  7. RESTful API:JSON + HTTP

1.3 ES核心概念

  • Near Realtime(NRT) 近实时:数据提交索引后,立马就可以搜索到。

  • Cluster 集群:一个集群由一个唯一的名字标识,默认为“elasticsearch”。集群名称非常重要,具有相同集群名的节点才会组成一个集群。集群名称可以在配置文件中指定。

  • Node 节点:存储集群的数据,参与集群的索引和搜索功能。像集群有名字,节点也有自己的名称,默认在启动时会以一个随机的UUID的前七个字符作为节点的名字,你可以为其指定任意的名字。通过集群名在网络中发现同伴组成集群。一个节点也可是集群。

  • Index 索引:一个索引是一个文档的集合(等同于solr中的集合)。每个索引有唯一的名字,通过这个名字来操作它。一个集群中可以有任意多个索引。Type 类型:指在一个索引中,可以索引不同类型的文档,如用户数据、博客数据。从6.0.0 版本起已废弃,一个索引中只存放一类数据。

  • Document 文档:被索引的一条数据,索引的基本信息单元,以JSON格式来表示。

  • Shard 分片:在创建一个索引时可以指定分成多少个分片来存储。每个分片本身也是一个功能完善且独立的“索引”,可以被放置在集群的任意节点上。分片的好处:允许我们水平切分/扩展容量、可在多个分片上进行分布式的、并行的操作,提高系统的性能和吞吐量。

    注意:分片数创建索引时指定,创建后不可改了。备份数可以随时改。

  • Replication 备份: 一个分片可以有多个备份(副本)。备份的好处:高可用。一个主分片挂了,副本分片就顶上去
    扩展搜索的并发能力、吞吐量。搜索可以在所有的副本上并行运行。-高并发下副本也可搜索
    在这里插入图片描述

1.4 结构化数据与非结构化数据

平时的数据可以分为结构化数据和非结构化数据:

  • 结构化数据是指格式和长度固定的数据,如一个人的年龄,姓名等;
  • 非结构化数据是指格式和长度不固定的数据,如一个文章的内容等;

           对于结构化数据,可以存储在DB中通过精确匹配找到。但是对于非结构化数据,一般查询时只能提供查询的局部信息或模糊信息,传统数据库无法根据这些信息进行查询,效率差;

1.5 倒排索引

在这里插入图片描述

倒排索引是相对于正排索引而言的,可以有效的解决该问题;

  • 正排索引可以通过id查找到对应的文章,但是无法通过给的部分内容如elasticsearch,找出含有该关键字的文档。

  • 倒排索引会先对文档进行分析将其拆分成单个Term, 并存储包含该Term的文档id,这样便可以实现通过内容查找对应文档,如包含elasticsearch的文档为文档1;

倒排索引的过程:

  1. 通过倒排索引获得“搜索引擎”对应的文档id列表,有1和3;
  2. 通过正排索引查询1和3的完整内容;
  3. 返回最终结果;

2. ES的安装使用

2.1 安装

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

推荐到华为云镜像下载:https://mirrors.huaweicloud.com/

JDK版本: 1.8

2.2 启动

解压安装包,进入bin目录中双击elasticsearch.bat等待启动完毕;

在这里插入图片描述

打开浏览器,输入 http://localhost:9200 出现以下画面,说明ES安装成功;

在这里插入图片描述

2.3 ES端口

  • 9300端口: ES节点之间通讯使用,9300是tcp通讯端口,集群间和TCPClient 都走它;
  • 9200端口: ES节点和外部通讯使用,9200是http协议的RESTful接口;

2.4 可视化工具Kibana

Kibana是一个针对Elasticsearch的开源分析及可视化平台,使用Kibana可以查询、查看并与存储在ES索引的数据进行交互操作,同时也能执行高级的数据分析,并能以图表、表格和地图的形式查看数据 ;

2.4.1 下载安装Kibana

下载安装包,需要和ES版本匹配,下载完毕后安装到相应的目录就行;

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

2.4.2 配置

在目录config/kibana.yml中配置 elasticsearch.hosts: 的值为ES的访问地址;

在这里插入图片描述

2.4.3 启动Kibana

双击bin/kibana.bat

  • 访问地址:http://localhost:5601

在这里插入图片描述

2.5 集成Ikanalyzer

IK Analyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包;从3.0版本开始,IK发展为面向Java的公用分词组件,独立于Lucene项目,同时提供了对Lucene的默认优化实现。在2012版本中,IK实现了简单的分词歧义排除算法,标志着IK分词器从单纯的词典分词向模拟语义分词衍化;

2.5.1 下载安装Ikanalyzer

获取 ES-IKAnalyzer插件,需要和ES版本一致;

将ik的压缩包解压到 ES安装目录的plugins/目录下(新建文件夹analysis-ik),重启ES;

下载地址: https://github.com/medcl/elasticsearch-analysis-ik/releases

2.5.2 两种分词模式

Ik分词器有ik_max_word和ik_smart两种模式:

  • ik_max_word:会将文本做最细粒度的拆分;
  • ik_smart:会做最粗粒度的拆分;

2.5.3 测试分词_细粒度拆分

{
    
    
"text":"我爱学习,最爱学Java",
"analyzer":"ik_max_word" 
}

在这里插入图片描述

2.5.4 测试分词_粗粒度拆分

{
    
    
"text":"我爱学习,最爱学Java",
"analyzer":"ik_smart" 
}

在这里插入图片描述

2.5.5 自定义分词库

首先在IKAnalyzer.cfg.xml里面定义自定义的字典,我这里是main.dic(自己随意命名);

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
	<comment>IK Analyzer 扩展配置</comment>
	<!--用户可以在这里配置自己的扩展字典 -->
	<entry key="ext_dict">main.dic</entry>
	 <!--用户可以在这里配置自己的扩展停止词字典-->
	<entry key="ext_stopwords"></entry>
	<!--用户可以在这里配置远程扩展字典 -->
	<!-- <entry key="remote_ext_dict">words_location</entry> -->
	<!--用户可以在这里配置远程扩展停止词字典-->
	<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

在这里插入图片描述

3. 使用Kibana实现增删查改

3.1 创建索引

PUT /kak
{
    
    
  "settings": {
    
    
    "index":{
    
    
      "number_of_shards":5,
      "number_of_replicas":3
    }
  }
}

在这里插入图片描述

3.2 查看索引

#查看单个
GET /kak/_settings
#查看所有
GET /_all/_settings

在这里插入图片描述

3.3 添加文档

PUT /kak/student/1
{
  "name":"kaka",
  "sex":"man",
  "age":23,
  "score":100
}
POST /kak/student/2
{
  "name":"taotao",
  "sex":"woman",
  "age":23,
  "score":100
}

在这里插入图片描述

3.4 查询文档

GET /kak/student/1
GET /kak/student/_search

在这里插入图片描述

在这里插入图片描述

3.5 修改文档

PUT方法:存在就修改,不存在就新增;

PUT /kak/student/1
{
    
    
  "name":"kaka",
  "sex":"man",
  "age":23,
  "score":150
}

在这里插入图片描述

3.6 删除文档

#删除单个
DELETE /kak/student/2
#删除全部
DELETE /kak

在这里插入图片描述

在这里插入图片描述

4. 批量获取文档信息

创建索引、添加文档

PUT kak_01
PUT kak_01/student/1
{
    
    
  "name":"kaka",
  "age":23,
  "sex":"man"
}
PUT kak_01/student/2
{
    
    
  "name":"zhuangzhuang",
  "age":23,
  "sex":"woman"
}
PUT kak_02
PUT kak_02/student/1
{
    
    
  "name":"zhangsan",
  "age":23,
  "sex":"man"
}
PUT kak_02/student/2
{
    
    
  "name":"lisi",
  "age":23,
  "sex":"woman"
}

4.1 获取多个索引下面的多个文档对象

GET /_mget
{
    
    
	"docs":[
		{
    
    
			"_index": "kak_01",
			"_type": "student",
			"_id": 1
		},
		{
    
    
			"_index": "kak_01",
			"_type": "student",
			"_id": 2
		}
	]
}

在这里插入图片描述

4.2 指定具体的字段

GET /_mget
{
    
    
  "docs":[
    {
    
    
      "_index":"kak_01",
      "_type":"student",
      "_id":1,
      "_source":["name","age"]
    },
    {
    
    
      "_index":"kak_01",
      "_type":"student",
      "_id":2,
      "_source":["name","age","sex"]
    }
    ]
}

在这里插入图片描述

4.3 简化批量获取的方式

GET /kak_01/student/_mget
{
    
    
  "docs":[
    {
    
    
      "_id":1
    },
    {
    
    

      "_id":2
    }
    ]
}

在这里插入图片描述

5. 使用Bulk API实现批量操作

语法格式:

  • {action:{metadata}}

  • {requstbody}

  • action:(行为)

    • create:文档不存在时创建
    • update:更新文档
    • index:创建新文档或替换已有文档
    • delete:删除一个文档

create 和index的区别:

  • 如果数据存在,使用create操作失败,会提示文档已经存在;
  • 如果数据存在,使用index则可以成功执行;

5.1 批量添加

POST kak_01/student/_bulk
{
    
    "index":{
    
    "_id":3}}
{
    
    "name":"kak_03","age":23,"sex":"woman"}
{
    
    "index":{
    
    "_id":4}}
{
    
    "name":"kak_04","age":23,"sex":"woman"}
{
    
    "index":{
    
    "_id":5}}
{
    
    "name":"kak_05","age":23,"sex":"man"}

在这里插入图片描述

5.2 批量查询

GET kak_01/student/_mget
{
    
    
  "ids":[1,2,3]
}

在这里插入图片描述

5.3 批量删除

POST kak_01/student/_bulk
{
    
    "delete":{
    
    "_index":"kak_01","_type":"student","_id":4}}
{
    
    "delete":{
    
    "_index":"kak_01","_type":"student","_id":5}}

在这里插入图片描述

在这里插入图片描述

5.4 注意事项

操作的大小建议:

Bulk会把将要处理的数据载入内存中,所以数据量是有限制的,最佳的数据量不是一个确定的数值取决于硬件;

  • 一般建议是1000-5000个文档,大小建议是5-15MB,默认不能超过100M,可以在ES的配置文件($ES_HOME下的config下的elasticsearch.yml)中设置;

6. 采用乐观锁机制实现并发控制

6.1 内部版本

         ElasticSearch采用了乐观锁来保证数据的一致性,当用户对document进行操作时,并不需要对该document作加锁和解锁的操作,只需要指定要操作的版本;当版本号一致时,ElasticSearch会允许该操作顺利执行,当版本号存在冲突时,ElasticSearch会提示冲突并抛出异常(VersionConflictEngineException异常);

  • ElasticSearch的版本号的取值范围为1到2^63-1。
  • 使用的是_version(每修改一个版本加一)

6.2 外部版本

         Elasticsearch在处理外部版本号时会与对内部版本号的处理有些不同。它不再是检查version是否与请求中指定的数值相同,而是检查当前的version是否比指定的数值小。如果请求成功,那么外部的版本号就会被存储到文档中的version中。为了保持version与外部版本控制的数据一致使用version_type=external ;

7. Mapping

查看自动生成的映射情况

GET kak_01/_mapping

在这里插入图片描述

核心数据类型:

字符型:string

  • string类型包括,text 和 keyword

    • text类型被用来索引长文本,在建立索引前会将这些文本进行分词,转化为词的组合,建立索引。允许es来检索这些词语。text类型不能用来排序和聚合。
    • Keyword类型不需要进行分词,可以被用来检索过滤、排序和聚合。
    • keyword 类型字段只能用本身来进行检索
  • 数字型:long, integer, short, byte, double, float

  • 日期型:date

  • 布尔型:boolean

  • 二进制型:binary

关键的属性:

  • “index”: true分词,false不分词,设置成false,字段将不会被索引;

  • “analyzer”:"ik"指定分词器,默认分词器为standard analyzer

PUT /lib
{
    
    
	"settings":{
    
    
	"number_of_shards" : 3,
	"number_of_replicas" : 0
	},
	"mappings":{
    
    
			"properties":{
    
    
			"title":{
    
    "type":"text"},
			"name":{
    
    "type":"text","analyzer":"standard"},
			"publish_date":{
    
    "type":"date","index":false},
			"price":{
    
    "type":"double"}
			}
	}
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 定义Mapping没有类型,之前能写进去是因为通过PUT,放文档放进去的;

8. 通用查询

8.1 准备数据

PUT /lib2
{
    
    
	"settings":{
    
    
	"number_of_shards" : 3,
	"number_of_replicas" : 0
	},
	"mappings":{
    
    
			"properties":{
    
    
			"name": {
    
    "type":"text"},
			"address": {
    
    "type":"text"},
			"age": {
    
    "type":"integer"},
			"interests": {
    
    "type":"text"},
			"birthday": {
    
    "type":"date"}
			}
	}
} 
PUT /lib2/_doc/1
{
    
    
	"name" : "kak",
	"address" : "sx",
	"age" : 32,
	"interests" : "java,music",
	"birthday": "1988-08-08"
} 

PUT /lib2/_doc/2
{
    
    
	"name" : "taotao",
	"address" : "sz",
	"age" : 33,
	"interests" : "java,music,money",
	"birthday": "1983-08-08"
}

PUT /lib2/_doc/2
{
    
    
	"name" : "taotao",
	"address" : "sz",
	"age" : 33,
	"interests" : "java,music,money",
	"birthday": "1983-08-08"
}

8.2 精确查找

term查询

8.2.1 查询某个字段里含有某个关键词的文档

GET /lib2/_search/
{
    
    
  "query": {
    
    
    "term": {
    
    
      "name": {
    
    
        "value": "kak"
      }
    }
  }
} 

在这里插入图片描述

8.2.2 查询某个字段里含有多个关键词的文档

GET /lib2/_search/
{
    
    
  "query": {
    
    
    "terms": {
    
    
      "interests": [
        "java",
        "music"
      ]
    }
  }
}

在这里插入图片描述

8.3 设值返回的条数

GET /lib2/_search
{
    
    
  "from": 0,
  "size": 2,
  "query": {
    
    
    "terms": {
    
    
      "interests": [
        "java",
        "music"
      ]
    }
  }
}

8.4 设值返回的版本

GET /lib2/_search
{
    
    
  "version": true,
  "from":0,
  "size": 2,
  "query": {
    
    
    "terms": {
    
    
      "interests": [
        "java",
        "money"
      ]
    }
  }
}

在这里插入图片描述

8.5 分词查找

match query知道分词器的存在,会对filed进行分词操作,然后再查询

GET /lib2/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "name": "kak helloworld"
    }
  }
}

在这里插入图片描述

8.6 指定多个字段进行查询

GET /lib2/_search
{
    
    
  "query": {
    
    
    "multi_match": {
    
    
      "query": "java",
      "fields": ["interests","name"]
    }
  }
}

在这里插入图片描述

8.7 短语查询

ElasticSearch引擎首先分析查询字符串,从分析后的文本中构建短语查询,这意味着必须匹配短语中的所有分词,并且保证各个分词的相对位置不变

GET /lib2/_search
{
    
    
  "query": {
    
    
    "match_phrase": {
    
    
      "interests": "java,music"
    }
  }
}

在这里插入图片描述

8.8 指定返回的字段

GET /lib2/_search
{
    
    
  "_source": ["address","name"],
  "query": {
    
    
    "match": {
    
    
      "interests": "java"
    }
  }
}

在这里插入图片描述

8.9 排序

GET /lib2/_search
{
    
    
  "query": {
    
    
    "match_all": {
    
    }
  },
  "sort": [
    {
    
    
      "age": {
    
    
        "order": "desc"
      }
    }
  ]
}

在这里插入图片描述

8.10 前缀匹配

GET /lib2/_search
{
    
    
  "query": {
    
    
    "match_phrase_prefix": {
    
    
      "name": {
    
    
        "query": "kak"
      }
    }
  }
}

在这里插入图片描述

8.11 范围查询

GET /lib2/_search
{
    
    
  "query": {
    
    
    "range": {
    
    
      "birthday": {
    
    
        "from": "1988-08-08",
        "to": "2020-08-08",
        "include_lower": true,
				"include_upper": false
      }
    }
  }
}

在这里插入图片描述

8.12 通配符

允许使用通配符* 和 ?来进行查询:

  • *代表0个或多个字符
  • ?代表任意一个字符
GET /lib2/_search
{
    
    
  "query": {
    
    
    "wildcard": {
    
    
        "name": "kak*"
    }
  }
}

在这里插入图片描述

8.13 高亮查询

GET /lib2/_search
{
    
    
  "query": {
    
    
    "match": {
    
    
      "interests": "java"
    }
  },
  "highlight": {
    
    
    "fields": {
    
    
      "interests": {
    
    }
    }
  }
}

在这里插入图片描述

9. Bool过滤查询

  • 可以实现组合过滤查询
  • must:必须满足的条件(and)
  • should:可以满足也可以不满足的条件(or)
  • must_not:不需要满足的条件(not )
GET /lib2/_search
{
    
    
  "post_filter": {
    
    
    "bool": {
    
    
      "should":[
        {
    
    "term":{
    
    "age":32}},
        {
    
    "term":{
    
    "interests":"java"}}
      ],
      "must_not":{
    
    
        "term":{
    
    "age":90}
      }
    }
  }
}

在这里插入图片描述

GET /lib2/_search
{
    
    
  "post_filter": {
    
    
    "bool": {
    
    
      "must":[
        {
    
    "term":{
    
    "age":32}},
        {
    
    "term":{
    
    "interests":"java"}}
      ]
    }
  }
}

在这里插入图片描述

10. 范围查找

  • gt:>
  • lt: <
  • gte: >=
  • lte: <=
GET /lib2/_search
{
    
    
  "post_filter": {
    
    
    "range": {
    
    
      "age": {
    
    
        "gte": 10,
        "lte": 32
      }
    }
  }
}

在这里插入图片描述

11. 聚合查询

11.1 求和

sum:求和

GET /lib2/_search
{
    
    
  "size": 0,
  "aggs": {
    
    
    "agesum": {
    
    
      "sum": {
    
    
        "field": "age"
      }
    }
  }
}

在这里插入图片描述

11.2 最小值

min:最小值

GET /lib2/_search
{
    
    
  "size": 0,
  "aggs": {
    
    
    "agemin": {
    
    
      "min": {
    
    
        "field": "age"
      }
    }
  }
}

在这里插入图片描述

11.3 最大值

  • max:最大值
GET /lib2/_search
{
    
    
  "size": 0,
  "aggs": {
    
    
    "agemax": {
    
    
      "max": {
    
    
        "field": "age"
      }
    }
  }
}

在这里插入图片描述

11.4 平均值

  • avg:平均值
GET /lib2/_search
{
    
    
  "size": 0,
  "aggs": {
    
    
    "ageavg": {
    
    
      "avg": {
    
    
        "field": "age"
      }
    }
  }
}

在这里插入图片描述

11.5 求基数

  • cardinality:基数(互不相同的值的个数 )
GET /lib2/_search
{
    
    
  "size": 0,
  "aggs": {
    
    
    "agecardinality": {
    
    
      "cardinality": {
    
    
        "field": "age"
      }
    }
  }
}

在这里插入图片描述

11.6 分组

  • terms:分组
GET /lib2/_search
{
    
    
  "size": 0,
  "aggs": {
    
    
    "ageterms": {
    
    
      "terms": {
    
    
        "field": "age"
      }
    }
  }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42601136/article/details/108877827
今日推荐