elasticsearch
elasticsearch是一个近实时分布式搜索和分析引擎,它用于全文搜索、结构化搜索、分析以及将这三者混合使用,使用java编写,基于Lucene 实现
优势:
-
分布式的实时文件存储,每个字段都被索引并可被搜索
-
实时分析的分布式搜索引擎
-
横向可扩展:支持上百台服务节点的扩展,集群增加机器简单,支持处理PB级数据
-
分片机制:
允许水平分割扩展数据,允许分片和并行操作从而提高性能和吞吐量
提供高性能:同一个索引可以分多个主分片(
primary shard
),每个主分片拥有自己的副本分片(replica shard
),每个副本分片都可以提供服务,提升系统搜索请求的吞吐量和性能提供高可用性:同一个索引可以分多个主分片,每个主分片拥有零个或者多个副本,如果主分片挂了,可以从副本分片中选择一个作为主分片继续提供服务
基本概念
-
Cluster
:集群一个集群包含多个节点,对外提供服务,每个节点属于哪个集群通过配置文件中的集群名称决定
-
Node
:节点集群中的一个节点,每个节点也有一个名称,默认是随机分配,也可以自己指定,在es集群中通过节点名称进行管理和通信
-
Index
:索引索引是具有相同结构的文档集合,作用相当于mysql中的库
-
Type
:类型一个索引可以对应一个或者多个类型,类型可以当做是索引的逻辑分区,作用相当于mysql中的表
-
Document
:文档存储在es中的一个
JSON
格式的字符串,每一个文档有一个文档ID,如果没有自己指定ID,系统会自动生成一个ID,文档的index/type/id必须是唯一的,作用相当于mysql中的行 -
field
:字段一个文档会包含多个字段,每个字段都对应一个字段类型,类似于mysql中的列
-
shard
:分片es中分为
primary shard
主分片和replica shard
副本分片主分片:当存一个文档的时候会先存储在主分片中,然后复制到不同的副本分片中,默认一个索引会有5个主分片,当然可以自己指定分片数量,当分片一旦建立,分片数量不能改变
副本分片:每一个主分片会有零个或者多个副本,副本主要是主分片的复制,通过副本分片可以提供高可用性,当一个主分片挂了,可以从副本分片中选择一个作为主分片,还可以提高性能,所以主分片不能和副本分片部署在相同的节点上
-
replica
:复制复制是为了防止单点问题,可以做到对故障进行转移,保证系统的高可用
-
映射
描述数据在每个字段内如何存储,是定义存储和索引的文档类型及字段的过程,索引中的每一个文档都有一个类型,每种类型都有它自己的映射,一个映射定义了文档结构内每个字段的数据类型
使用
GET /index/_mapping/type
获取对应的/index/type
的映射信息
可视化界面Kibana
建议安装Elasticsearch+Kibana,在Kibana的操作界面对es进行操作
Elasticsearch提供了RESTful接口可以对Elasticsearch进行操作
Kibana操作页面
在Kibana的Dev Tools界面可以对es进行操作,在console界面敲命令,点执行,会在右面输出结果
验证Elasticsearch是否安装成功
{
"name" : "UzOujcc", //节点名称
"cluster_name" : "mx", //集群名称,我自己设置的
"cluster_uuid" : "d2K1M95DRzG9XOPDOR_DEQ",
"version" : {
"number" : "6.2.4", //集群版本
"build_hash" : "ccec39f",
"build_date" : "2018-04-12T20:37:28.497551Z",
"build_snapshot" : false,
"lucene_version" : "7.2.1",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
es提供了一套api,叫做cat api,可以查看es中的信息数据
查看集群健康状况
命令:GET /_cat/health?v
status
代表着集群的健康程度
green
:每个索引的primary shard和replica shard都是active状态的yellow
:每个索引的primary shard都是active状态的,但是部分replica shard不是active状态,处于不可用的状态red
:不是所有索引的primary shard都是active状态的,部分索引有数据丢失了
索引操作
查看索引信息
命令:GET _cat/indices?v
有五个索引,都是的测试数据
新建索引
命令:PUT /myindex
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "myindex"
}
删除索引
命令:DELETE myindex
{
"acknowledged": true
}
文档操作
添加文档
添加文档是向索引中添加一条文档,让其能够搜索,文档格式是json串,如果es中有相同id的文档存在则更新这个文档
当创建文档的时候,如果索引不存在,则会自动创建该索引,而且es默认会对document每个field都建立倒排索引,让其可以被搜索
命令:
PUT /index/type/id
{
"json数据结构体 "
}
例:
PUT /school/student/1
{
"name":"张三",
"age":21,
"class":2,
"gender":"男"
}
返回:
{
"_index": "school", //索引
"_type": "student", //类型
"_id": "1", //id,如果不指定则会系统生成一个20位的id,文档被分到那个分片上就是根据id的散劣值进行控制
"_version": 1, //文档版本号,通过这个进行并发控制
"result": "created", //操作类型
"_shards": { //分片信息
"total": 2, //文档被创建时在多少个分片进行了操作(包括主分片和副本分片)
"successful": 1, //添加成功的索引分片数量
"failed": 0 //失败的索引分片数量
},
"_seq_no": 0,
"_primary_term": 1
}
修改文档
方式1:使用put方式更新文档
PUT /school/student/1
{
"name":"吕布",
"age":21,
"class":2,
"gender":"男"
}
返回:
{
"_index": "school",
"_type": "student",
"_id": "1",
"_version": 2, //版本号+1
"result": "updated", // 修改
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
这种方式替换需要带上所有的field,才能进行信息的修改,操作类似于覆盖
方式2:post更新文档
POST /school/student/1/_update
{
"doc": {
"name":"吕布1"
}
}
使用post更新文档,可以只更新部分字段
查询文档
查询单条文档
命令:GET /school/student/1
返回:
{
"_index": "school",
"_type": "student",
"_id": "1",
"_version": 3,
"found": true,
"_source": {
"name": "吕布1",
"age": 21,
"class": 2,
"gender": "男"
}
}
删除文档
命令:DELETE school/student/1
返回:
{
"_index": "school",
"_type": "student",
"_id": "1",
"_version": 4,
"result": "deleted", //删除
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 3,
"_primary_term": 1
}
这时在查询就会显示"found": false
映射
es中的映射(mapping
)用来描述数据在每个字段内如何存储,是定义存储和索引的文档类型及字段的过程,索引中的每一个文档都有一个类型,每种类型都有它自己的映射,一个映射定义了文档结构内每个字段的数据类型,作用相当于mysql
中的DDL
语句
查询索引类型的映射
GET /ad/_mapping/phone
{
"school": {
"mappings": {
"student": {
"properties": {
"age": {
"type": "long"
},
"class": {
"type": "long"
},
"gender": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
动态映射
动态映射不需要事先定义映射,文档在写入es的时候,会根据文档字段自动识别类型
映射规则:
Json 数据类型 | es 数据类型 |
---|---|
null | 没有字段添加 |
true,false | boolean |
Integer | long |
object | object |
array | 依赖于数组中首个非空值 |
string | text和keyword |
日期 | date或text |
静态映射
静态映射需要事先定义好映射,包含文档的各个字段及其类型
PUT books
{
"mappings": {
"book":{
"properties": {
"id":{"type": "long"},
"bookName":{"type": "text"},
"ad":{"type": "text"}
}
}
}
}
Elasticsearch 中的数据可以概括的分为两类:精确值和全文
- 精确值:精确值是确定的值,比如用户ID,字符串也可以表示精确值,例如用户名或邮箱地址。对于精确值来讲,
Foo
和foo
是不同的,精确值的查询简单,要么匹配查询,要么不匹配 - 全文:全文是指文本数据(通常以人类容易识别的语言书写),例如一个推文的内容或一封邮件的内容,全文的查询较为复杂,他需要的是匹配查询的程度有多大
在es中使用 倒排索引来进行快速的全文搜索。一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,有一个包含它的文档列表,倒排索引具体内容请戳:www.elastic.co/guide/cn/el…
es中的字符串类型分为keyword
和text
keyword
:用于索引结构化内容的字段,例如电子邮件地址,主机名,状态代码,邮政编码或标签。它们通常用于过滤,排序,和聚合。keyword字段只能按其确切值进行搜索。如果您需要索引电子邮件正文或产品说明等全文内容,则可能应该使用text字段text
:用于索引全文值的字段,例如电子邮件正文或产品说明。这些字段是analyzed,它们通过分词器传递 ,以在被索引之前将字符串转换为单个术语的列表。分析过程允许Elasticsearch搜索单个单词中 每个完整的文本字段。文本字段不用于排序,很少用于聚合
有时候一个字段同时拥有全文类型(text)和关键字类型(keyword)是有用的:一个用于全文搜索,另一个用于聚合和排序。这可以通过多字段类型来实现(动态映射是字符串的默认映射类型)
参考: Elasticsearch: 权威指南 www.elastic.co/guide/cn/el…