ElasticSearch
ES检索服务器
应用:大数据量,全文检索引擎
Restful风格
相关安装包文后自取
安装和配置
解压缩在指定目录即可,执行bin下的elasticsearch文件即可。window执行批处理,linux执行另一个。
端口:9200
ES图形化界面head:
由javascript实现运行需要在node.js上
安装:解压至指定目录即可,进入该目录cmd执行grunt server
命令,如果失败则先执行npm install -g grunt-cli
和npm install
命令
端口:9100
配置:
连接9200端口时跨域操作
打开es安装目录下的config下的elasticsearch.yml文件添加
#配置跨域访问
http.cors.enabled: true
http.cors.allow-origin: "*"
即可。
专业术语
和数据库进行对比
Relational DB ‐> Databases ‐> Tables ‐> Rows ‐> Columns
Elasticsearch ‐> Indices ‐> Types ‐> Documents ‐> Fields
-
索引 index:数据库
一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。 -
类型 type:表
在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定。通常,会为具有一组共同字段的文档定义一个类型。比如说,我们假设你运营一个博客平台并且将你所有的数据存储到一个索引中。在这个索引中,你可以为用户数据定义一个类型,为博客数据定义另一个类型,当然,也可以为评论数据定义另一个类型。 -
字段Field:表字段
相当于是数据表的字段,对文档数据根据不同属性进行的分类标识
-
映射 mapping:表字段类型描述,一旦建立不可修改
mapping是处理数据的方式和规则方面做一些限制,如某个字段的数据类型、默认值、分析器、是否被索引等等,这些都是映射里面可以设置的,其它就是处理es里面数据的一些使用规则设置也叫做映射,按着最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。 -
文档 document:表中的一行数据
一个文档是一个可被索引的基础信息单元。比如,你可以拥有某一个客户的文档,某一个产品的一个文档,当然,也可以拥有某个订单的一个文档。文档以JSON(Javascript Object Notation)格式来表示,而JSON是一个到处存在的互联网数据交互格式。
在一个index/type里面,你可以存储任意多的文档。注意,尽管一个文档,物理上存在于一个索引之中,文档必须被索引/赋予一个索引的type。 -
接近实时 NRT
Elasticsearch是一个接近实时的搜索平台。这意味着,从索引一个文档直到这个文档能够被搜索到有一个轻微的延迟(通常是1秒以内) -
集群 cluster
一个集群就是由一个或多个节点组织在一起,它们共同持有整个的数据,并一起提供索引和搜索功能。一个集群由一个唯一的名字标识,这个名字默认就是“elasticsearch”。这个名字是重要的,因为一个节点只能通过指定某个集群的名字,来加入这个集群 -
节点 node
一个节点是集群中的一个服务器,作为集群的一部分,它存储数据,参与集群的索引和搜索功能。和集群类似,一个节点也是由一个名字来标识的,默认情况下,这个名字是一个随机的漫威漫画角色的名字,这个名字会在启动的时候赋予节点。这个名字对于管理工作来说挺重要的,因为在这个管理过程中,你会去确定网络中的哪些服务器对应于Elasticsearch集群中的哪些节点。
一个节点可以通过配置集群名称的方式来加入一个指定的集群。默认情况下,每个节点都会被安排加入到一个叫做“elasticsearch”的集群中,这意味着,如果你在你的网络中启动了若干个节点,并假定它们能够相互发现彼此,它们将会自动地形成并加入到一个叫做“elasticsearch”的集群中。
在一个集群里,只要你想,可以拥有任意多个节点。而且,如果当前你的网络中没有运行任何Elasticsearch节点,这时启动一个节点,会默认创建并加入一个叫做“elasticsearch”的集群。 -
分片和复制 shards&replicas
一个索引可以存储超出单个结点硬件限制的大量数据。比如,一个具有10亿文档的索引占据1TB的磁盘空间,而任一节点都没有这样大的磁盘空间;或者单个节点处理搜索请求,响应太慢。为了解决这个问题,Elasticsearch提供了将索引划分成多份的能力,这些份就叫做分片。当你创建一个索引的时候,你可以指定你想要的分片的数量。每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。分片很重要,主要有两方面的原因:
1)允许你水平分割/扩展你的内容容量。
2)允许你在分片(潜在地,位于多个节点上)之上进行分布式的、并行的操作,进而提高性能/吞吐量。
至于一个分片怎样分布,它的文档怎样聚合回搜索请求,是完全由Elasticsearch管理的,对于作为用户的你来说,这些都是透明的。
在一个网络/云的环境里,失败随时都可能发生,在某个分片/节点不知怎么的就处于离线状态,或者由于任何原因消失了,这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。为此目的,Elasticsearch允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片,或者直接叫复制。
复制之所以重要,有两个主要原因: 在分片/节点失败的情况下,提供了高可用性。因为这个原因,注意到复制分片从不与原/主要(original/primary)分片置于同一节点上是非常重要的。扩展你的搜索量/吞吐量,因为搜索可以在所有的复制上并行运行。总之,每个索引可以被分成多个分片。一个索引也可以被复制0次(意思是没有复制)或多次。一旦复制了,每个索引就有了主分片(作为复制源的原来的分片)和复制分片(主分片的拷贝)之别。分片和复制的数量可以在索引创建的时候指定。在索引创建之后,你可以在任何时候动态地改变复制的数量,但是你事后不能改变分片的数量。
默认情况下,Elasticsearch中的每个索引被分片5个主分片和1个复制,这意味着,如果你的集群中至少有两个节点,你的索引将会有5个主分片和另外5个复制分片(1个完全拷贝),这样的话每个索引总共就有10个分片。
ElasticSearch的客户端操作
实际开发中,主要有三种方式可以作为elasticsearch服务的客户端:
- 第一种,elasticsearch-head插件,编写json有点复杂,借助postman
- 第二种,使用elasticsearch提供的Restful接口直接访问
- 第三种,使用elasticsearch提供的API进行访问
- 创建索引和映射:创建数据库并设计表:尽量使用该方式创建
url:http://localhost:9200/indexName发送put请求前
指定type和字段,在body中编辑json请求体
demo3为index的name
json中可以有多个mapping
{
"mappings": {
"hello3": {
"properties": {
"id": {
"type": "long",
"store": true,
"index":"not_analyzed"
},
"title": {
"type": "text",
"store": true,
"index":"analyzed",
#拆词分析器选择
"analyzer":"standard"
},
"content": {
"type": "text",
"store": true,
"index":"analyzed",
"analyzer":"standard"
}
}
},
"hello2": {
"properties": {
"id": {
"type": "long",
"store": true,
"index":"not_analyzed"
},
"title": {
"type": "text",
"store": true,
"index":"analyzed",
"analyzer":"standard"
},
"content": {
"type": "text",
"store": true,
"index":"analyzed",
"analyzer":"standard"
}
}
}
}
}
- 创建索引后设置mapping映射:创建数据库后添加表
url:http://localhost:9200/demo4直接发送put请求
然后发送post请求进行设置映射
此时的请求路径需要添加type的名称,且由此名称决定es中该type的名称
http://localhost:9200/demo4/hello
其中hello和json中的一致
请求体body的json如下
{
"mappings": {
#type(表名)以url中的为准
"hello": {
"properties": {
"id": {
"type": "long",
"store": true,
"index":"not_analyzed"
},
"title": {
"type": "text",
"store": true,
"index":"analyzed",
"analyzer":"standard"
},
"content": {
"type": "text",
"store": true,
"index":"analyzed",
"analyzer":"standard"
}
}
}
}
}
- 删除索引库:删除数据库
设置请求方式为delete
url:http://localhost:9200/demo4 - 创建文档document:添加数据
post请求:url:http://localhost:9200/索引名(数据库名)/type名(表名)
or::url:http://localhost:9200/索引名(数据库名)/type名(表名)/_id,_id是ES默认生成的可以省略,默认生成的是String字符串,_id类似于数据库中的主键。
eg:http://localhost:9200/demo5/hello2
eg1:http://localhost:9200/demo5/hello2/1
{"id":2,"title":"ES中第二条是数据,指定了_id","content":"内容"}
5. 删除文档:删除数据库表中的数据
发送delete请求:
url:http://localhost:9200/索引名(数据库名)/type名(表名)/_id
eg:http://localhost:9200/demo5/hello2/1
6. 修改文档:修改表中数据
原理:在ES中是先删除后添加
发送post请求:
url:http://localhost:9200/索引名(数据库名)/type名(表名)/_id
请求体body中编辑要更改的json数据
{"id":2,"title":"修改后的数据。ES中第二条数据,指定了_id","content":"内2容"}
7. 查询文档:查询表中数据
- 根据_id查询:
发送get请求:
url:http://localhost:9200/索引名(数据库名)/type名(表名)/_id
http://localhost:9200/demo5/hello2/6
eg:
{
"_index": "demo5",
"_type": "hello2",
"_id": "6",
"_version": 1,
"found": true,
"_source": {
"id": 6,
"title": "数据6",
"content": "内6容"
}
}
- 根据关键词进行查询:默认的拆词器只能单个汉字查询,ik可以输入多个 非汉字为空
ur上需要加“_search”命令
发送post请求:url:
http://localhost:9200/索引名(数据库名)/type名(表名)/_search
在请求体中编辑关键词:
#固定写法
{
"query":{
#关键字查询
"term":{
#此处用于指定字段和关键字
"title":"中"
}
}
}
eg:http://localhost:9200/demo5/hello2/_search
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 0.58319575,
"hits": [
{
"_index": "demo5",
"_type": "hello2",
"_id": "2",
"_score": 0.58319575,
"_source": {
"id": 2,
"title": "ES中第二条是数据,指定了_id",
"content": "内容"
}
},
{
"_index": "demo5",
"_type": "hello2",
"_id": "1",
"_score": 0.26301134,
"_source": {
"id": 2,
"title": "修改后的数据。ES中第二条数据,指定了_id",
"content": "内2容"
}
}
]
}
}
- querystring查询:根据字符串进行查询(先分词后查询),当字符串中包含数据中文字时也可以查询到,不需要字符串完全一致
如百度的搜索推荐功能
ur上需要加“_search”命令
发送post请求:url:
http://localhost:9200/索引名(数据库名)/type名(表名)/_search
请求体内容如下:
#固定写法
{
"query":{
#字符串查询
"query_string":{
#默认检索域
"default_field":"title",
#查询字符串
"query":"ES"
}
}
}
eg:http://localhost:9200/demo5/hello2/_search
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 0.58319575,
"hits": [
{
"_index": "demo5",
"_type": "hello2",
"_id": "2",
"_score": 0.58319575,
"_source": {
"id": 2,
"title": "ES中第二条是数据,指定了_id",
"content": "内容"
}
},
{
"_index": "demo5",
"_type": "hello2",
"_id": "1",
"_score": 0.26301134,
"_source": {
"id": 2,
"title": "修改后的数据。ES中第二条数据,指定了_id",
"content": "内2容"
}
}
]
}
}
- 使用head的插件进行查询
多个条件之间可以组合
eg:
ES中的分词器
查看标准分词器效果
get请求:url:http://localhost:9200/_analyze?analyzer=standard&text=我是程序员
结果:一个字一个字进行分词。
IK分词器:中文分词器
集成IK分词器:
解压缩ik压缩包到es安装目录下的plugins下后,重启es服务即可。
提供两种算法:
IK提供了两个分词算法ik_smart 和 ik_max_word
其中 ik_smart 为最少切分,ik_max_word为最细粒度划分,拆分后排列组合。
如我是程序员—>我、是、程序员、程序、员
eg:
新建一个索引库和type指定ik拆次器,添加数据进行查询。
ES集群
架构图
ES集群是一个 P2P类型(使用 gossip 协议)的分布式系统,除了集群状态管理以外,其他所有的请求都可以发送到集群内任意一台节点上,这个节点可以自己找到需要转发给哪些节点,并且直接跟这些节点通信。所以,从网络架构及服务配置上来说,构建集群所需要的配置极其简单。在 Elasticsearch 2.0 之前,无阻碍的网络下,所有配置了相同 cluster.name 的节点都自动归属到一个集群中。2.0 版本之后,基于安全的考虑避免开发环境过于随便造成的麻烦,从 2.0 版本开始,默认的自动发现方式改为了单播(unicast)方式。配置里提供几台节点的地址,ES 将其视作 gossip router 角色,借以完成集群的发现。由于这只是 ES 内一个很小的功能,所以 gossip router 角色并不需要单独配置,每个 ES 节点都可以担任。所以,采用单播方式的集群,各节点都配置相同的几个节点列表作为 router 即可。
集群中节点数量没有限制,一般大于等于2个节点就可以看做是集群了。一般处于高性能及高可用方面来考虑一般集群中的节点数量都是3个及3个以上。
集群的搭建
1.创建elasticsearch-cluster文件夹,在内部复制三个elasticsearch服务(需要删除es下的data文件夹,不能有数据)
2.修改elasticsearch-cluster\node*\config\elasticsearch.yml配置文件
eg:
node01:
#节点1的配置信息:
#集群名称,保证唯一
cluster.name: my-elasticsearch
#节点名称,必须不一样
node.name: node-1
#必须为本机的ip地址
network.host: 127.0.0.1
#服务端口号,在同一机器下必须不一样
http.port: 9200
#集群间通信端口号,在同一机器下必须不一样
transport.tcp.port: 9300
#设置集群自动发现机器ip集合
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"]
3.依次启动即可
资源
链接:https://pan.baidu.com/s/1JpSMmiLzOlXGo_om6ZDf2w
提取码:3bdh