Lxxxxxxy_
Lxxxxxxy_
Published on 2021-10-21 / 131 Visits
0

ElasticSearch入门

ElasticSearch入门

一、ElasticSearch介绍

1、概述

ElasticSearch是基于Apache组织的Lucene开源搜索引擎开发的一个搜索引擎。

ElasticSearch编写的目的是使用简单的RESTfulAPI来实现全文搜索并摒弃Lucene的复杂操作。

除此之外,ElasticSearch还提供了:

(1)分布式的文件存储,存入的数据中每个字段都经过索引并可以通过API来搜索。

(2)实时分析的分布式搜索引擎。

(3)可以扩展到上百台的服务器上,处理海量级别的结构化或非结构化数据。

2、重要概念

(1)接近实时(NRT)

ElasticSearch得于Lucene的支持,它是一个趋近于实时的搜索引擎。它从索引一个文档到能通过搜索API搜索到这个文档,仅仅有一个忽略不计的延迟(1秒左右)。

(2)集群(Cluster)

由于ElasticSearch能支持海量数据搜索,所以集群是必要的。用户可以通过配置一个集群标识(默认是ElasticSearch),让其他节点加入这个集群,实现比如数据的分离和搜索的引导。

(3)节点(Node)

节点就是集群中的一个服务器,它作为集群的一部分,可以通过主备来实现主节点和备用节点,并存储用户的数据。如果在所有ElasticSearch服务器中没有运行任何一个节点,那么它会默认创建并加入一个ElasticSearch集群。

(4)索引(Index)

一个索引就是一个文档的集合,可以理解成关系型数据库中Database的概念,一个索引由它的名字(必须是小写字母)来作为标识,后续可以通过这个索引对文档进行增删改查的操作。

倒排索引:通过关键字来查找,这是ElasticSearch中全文检索速度快的原因。

正排(正向)索引:在关系型数据库中使用id等字段作为索引。

(5)类型(Type)

一个类型是一个索引的子类,多个类型组成了一个索引。类型主要存有一些拥有共同字段的文档。可以理解成关系型数据库中Table的概念。

(6)文档(Document)

一个文档是ElasticSearch中可以被搜索到的基础信息。在ElasticSearch中主要是使用JSON的格式来表示,你可以存有一个用户的文档,他的订单文档等。文档中除了这些数据外,还包括有_index、_type和_id字段。

(7)分片(Shards)

一个索引中能够存储超过某个节点硬件限制的数据,前提是对其进行了分片操作。比如一个索引占用了超过1TB的空间,但是在集群中没有任何一个节点有1TB的容量,此时就会对这个索引进行分片操作。当然,这也是为了能够将搜索的速度进行最优操作。

在创建一个索引的时候,可以指定分片的数量,此时由于定义了分片操作,这个索引可以在集群中的任何节点上找到。

在分片中,能够实现这两个重要的功能:

·可以通过分片来扩展某个索引的容量,以及实现数据的分割。

·实现分片后可以在集群中进行分布式/并行的操作,进而提高集群的处理能力。

(8)复制(Replicas)

在任何一个系统中,出现宕机等问题的可能性随时都会发生,ElasticSearch也不例外。

ElasticSearch提供了一种索引备份的机制,它允许用户创建分片的复制分片。

复制分片不会和原分片在同一个节点上,因为如果在集群中,某个节点发生宕机,如果同时存在于同一个节点上的话,此时这个索引备份机制是没有意义的。

在索引创建后,用户可以随时改变复制数量,但不能改变分片的数量,因为改变分片的数量时是会进行数据的重新切割,而复制则不会对分片造成任何影响。

默认情况下,ElasticSearch的每个索引会被设置成5个分片和1个复制索引,当然这是在有至少两个节点的前提下,如果只有一个节点,那么分片没有任何意义。

二、下载与启动

1、前置条件

环境说明:

服务器:阿里云轻量应用服务器

操作系统:CentOS8.2

内存:2G

ElasticSearch版本:7.15.1

运行ElasticSearch需要在服务器上安装jdk

yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel

2、下载tar.gz文件

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.15.1-linux-x86_64.tar.gz

3、解压

tar -vxf elasticsearch-7.15.1-linux-x86_64.tar.gz

4、ElasticSearch目录说明

目录配置文件描述
bin 放置脚本文件,如启动脚本 ElasticSearch, 插件安装脚本等。
configelasticserch.ymlElasticSearch配置文件,如集群配置、jvm 配置等。
jdk java 运行环境
datapath.data数据持久化文件
lib 依赖的相关类库
logspath.log日志文件
modulElasticSearch 包含的所有 ElasticSearch 模块
plugins 包含的所有已安装的插件

5、新用户配置

由于ElasticSearch不能使用root用户启动,所以需要新建一个elastic用户

CentOS8的添加用户命令

adduser elastic

给elastic用户赋予权限(使用root账号)

chown -R elastic:elastic /software/elasticsearch-7.15.1

6、启动

使用elastic用户,进入对应文件夹的bin目录下

使用命令启动,-d是在后台运行

./elasticsearch -d

7、验证

使用命令

curl localhost:9200

最终控制台显示以下内容就成功启动了

{
  "name" : "iZax8lw98s1xu9Z",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "D-A_yUfpSrmgxThbKSox6Q",
  "version" : {
    "number" : "7.15.1",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "83c34f456ae29d60e94d886e455e6a3409bba9ed",
    "build_date" : "2021-10-07T21:56:19.031608185Z",
    "build_snapshot" : false,
    "lucene_version" : "8.9.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

8、注意事项

(1)远程访问需要修改elasticsearch.yml中的network.host属性,将其改成0.0.0.0

(2)报错提示

bootstrap check failure [1] of [3]: max file dElasticSearchcriptors [4096] for elasticsearch procElasticSearchs is too low, increase to at least [65535]  

需要打开/etc/security/limits.conf文件

在结尾增加以下内容,其中elastic为创建的新用户

elastic soft nofile 65536
elastic hard nofile 65536

(3)报错提示

bootstrap check failure [2] of [3]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

需要打开/etc/sysctl.conf文件

在结尾增加以下内容

vm.max_map_count=262144

(4)报错提示

bootstrap check failure [3] of [3]: the default discovery settings are unsuitable for production use; at least one of [discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodElasticSearch] must be configured

需要进行对discovery.seed_hosts, discovery.seed_providers, cluster.initial_master_nodElasticSearch其中一个的配置

配置内容如下

    # 启动地址,如果不配置,只能本地访问
    network.host: 0.0.0.0
    # 节点名称
    node.name: node1
    # 初始化时master节点的选举列表
    cluster.initial_master_nodElasticSearch: [ "node1" ]
    # 集群名称
    cluster.name: elasticsearch
    # 对外提供服务的端口
    http.port: 9200
    # 内部服务端口
    transport.port: 9300    
    # 跨域支持
    http.cors.enabled: true
    # 跨域访问允许的域名地址(正则)
    http.cors.allow-origin: /.*/

三、ElasticSearch RESTful API的使用

ElasticSearch提供了非常多的基于HTTP协议的RESTful API,只需要向ElasticSearch发送RESR请求,就可以实现它提供的一系列功能。

目前的资料中大部分是使用的Linux的curl命令来发送请求,我使用Postman来发送,因为它图形化,并且相对于命令也更容易操作

1、健康检查

健康检查主要用来查看集群的运行情况,由于只有一个节点,所以暂时不用了解太多。

URL格式(GET)

/_cat/health?v

其中?v主要用来显示字段

最终效果如图所示

image-20211020161915270

其中,status为green表示正常,其他的还有yellow(所有数据都可用但复制分片不可用)、red(部分数据不可用)。

2、获取集群中节点列表

URL格式(GET)

/_cat/nodes?v

从下图可以看到集群中只有一个名为node1的节点。

image-20211020162405252

3、创建索引

URL格式(PUT)

/索引名

acknowledged为true表示索引创建成功,由于默认是进行了分片操作的,所以shards_acknowledged也为true,index则表示索引名称。

image-20211020162739272

4、列出索引

URL格式(GET)

/_cat/indices?v

节点中有一个默认的索引,另外有一个index1的索引,index1索引的health为yellow,是因为现在节点只有一个,不能对分片进行复制,等到添加第二个节点的时候就会恢复成green。

image-20211020164847334

5、创建文档

创建了索引之后就可以把文档存入到ElasticSearch中了。

URL格式(PUT/POST)

/索引名/_doc/文档id
/索引名/_create/文档id

ps:由于ElasticSearch在6.X版本之后就要逐步移除类型(Type)的概念,所以类型就不写上去了,直接用_doc代替。

需要向这个URL发送一个PUT请求,并在请求中带入一个JSON字符串,此时ElasticSearch会返回一个存入的状态,其中各个字段表示如表格所示

字段含义
_index索引,用于表示当前文档是在哪个索引中
_type类型,用于表示当前文档是在哪个类型中
_idid,文档的id
_version版本,文档的版本,如果对其进行了操作,那么这个值会增加
result结果,有created,updated,deleted等情况,表示新增,更新,删除
_shards分片情况
_seq_no索引的序列号
_primary_term和_seq_no组合使用

image-20211021101532071

当索引不存在时也能存入文档,当索引不存在时,会自动创建索引

image-20211021101804107

当文档id不存在时也能创建文档,此时id会由系统自动生成,但需要发送POST请求而不是PUT

image-20211021101840255

6、查询文档

URL格式(GET)

/索引名/_doc/文档id

其中found字段为true表示找到了id为1的文档,_source是文档的具体内容。

image-20211021101930447

7、查询索引下的所有文档

URL格式(GET)

/索引名/_search

ps:这种方式只能查询到10条,如果要查询到所有的数据,可以使用分页的查询条件。

image-20211021104841585

其中各个字段的说明:

字段含义
tookElasticSearch搜索所使用的时间(毫秒)
timed_out是否超时
_shards搜索的分片信息
hits搜索结果
hits.total搜索命中信息
hits.hits搜索结果
hits._score/max_scorescore是判断搜索条件匹配程度的指标,分数越高文档和搜索条件越相关

8、更新文档

URL格式(POST/PUT)

1、/索引名/_update/更新的文档id(POST)
2、/索引名/_doc/更新的文档id(PUT)

参数格式

1、
{
    "doc":{
        //更新的内容
    }
}
2、
{
    //更新的内容
}

更新文档和创建文档的方式是一样的,如果创建的文档已存在,那么就会自动更新它。

如果文档不存在则自动创建。(仅限_doc的方式)

此时result的值是updated,_version的值也增加。

image-20211021102025404

9、删除文档

URL格式(DELETE)

/索引名/_doc/删除的文档id

此时result的值是deleted,_version也变成了3.

image-20211020172420239

10、删除索引

URL格式(DELETE)

/索引名

执行后会返回true,表示已经删除成功。

image-20211020172528680

这时再查询索引,已经没有了。

image-20211020172624055

11、搜索文档

(1)按条件搜索文档

URL格式(GET)

/索引名/_search

参数格式

{
    "query":{
        "match":{
            //搜索条件:key:value
            //match表示匹配,可以替换成match_all,表示查询所有
        }
    }
}

image-20211020193341381

(2)分页查询

参数格式

{
    "query":{
        "match":{
            //搜索条件
        }
    },
    "from":0,
    "size":20
    //表示从0开始搜索,返回20条数据
}

image-20211021110824870

(3)排序

参数格式

{
    "query":{
        "match_all":{//查询所有
        }
    },
    "sort":{
        "age":{//表示按年龄排序
            "order":"asc"//表示排序方式是升序
        }
    }
}

image-20211021111413046

(4)数据过滤

参数格式

{
    "query":{
        "bool":{
            "must":{
                "match":{
                    "name":"lxy10"
                }
            },
            "filter":{
                "range":{
                    "age":{
                        "gt":30
                    }
                }
            }
        }
    },
    "sort":{
        "age":{
            "order":"asc"
        }
    }
}

上面查询条件表示name是"lxy10",并且年龄大于30,最后按照年龄的升序排序。

image-20211021111835472

12、全文检索

(1)全文检索

全文检索时会将用户输入的字符串给拆分出来,然后去倒排索引里面一一匹配,只要能匹配到某一个字或单词,那么就将结果返回。

URL格式(GET)

/索引名/_search

参数格式

{
    "query":{
        "match":{
            //搜索条件,可以是完整的名称,也可以是一个字或单词
        }
    }
}

(2)短语搜索

和全文检索相反,短语检索是必须要完全匹配才能将结果返回。

参数格式

{
    "query":{
        "match_phrase":{
            //搜索条件,必须和结果中包含了一样的才会返回
        }
    }
}

(3)高亮搜索结果

高亮搜索结果主要是将查询的条件给高亮出来,效果参考百度搜索。

{
    "query":{
        "match":{
            //搜索条件
        }
    },
    "highlight":{
        "fields":{
            //高亮字段
        }
    }
}

13、聚合

使用聚合检索可以对结果进行统计,如求平均或求和等运算。

在进行聚合检索之前,需要对文档的属性进行调整。

(1)文档属性调整

URL格式(POST)

/索引名/_mapping

参数格式

{
    "properties":{
        "name":{
            "type":"text",//text表示这个属性能够被分词
            "index":true,//true表示加入索引
            "fielddata":true//存储的数据结构是fielddata
        },
        "category":{
            "type":"keyword"
        },
        "price":{
            "type":"long",
            "index":true
        }
    }
}

ps:这个操作比较类似数据表中定义数据表结构。

(2)统计每个name下的数量

参数格式

{
    "aggs":{
        "phone_count":{
            "terms":{
                "field":"name"//后面跟文档的属性
            }
        }
    },
    "size":0//如果不加这个会把检索的结果也返回
}

(3)统计名称中包含X并计算每个name下的数量

参数格式

{
    "aggs":{
        "phone_count":{
            "terms":{
                "field":"name"
            }
        }
    },
    "size":0,
    "query":{
        "match":{
            "name":"X"
        }
    }
}

(4)统计商品的平均价格

参数格式

{
    "aggs":{
        "phone_avg":{
            "avg":{
                "field":"price"
            }
        }
    },
    "size":0
}

(5)检索某个范围内的商品数量

参数格式

{
    "aggs":{
        "phone_range":{
            "range":{
                "field":"price",
                "ranges":{
                    "from":0,
                    "to":1000
                }
            }
        }
    }
}