实时搜索引擎Elasticsearch
Elasticsearch(简称ES)是一个基于Apache Lucene(TM)的开源搜索引擎,无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。
Elasticsearch简介
Elasticsearch是什么
Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎,无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。 但是,Lucene只是一个库。想要发挥其强大的作用,你需使用Java并要将其集成到你的应用中。Lucene非常复杂,你需要深入的了解检索相关知识来理解它是如何工作的。 Elasticsearch也是使用Java编写并使用Lucene来建立索引并实现搜索功能,但是它的目的是通过简单连贯的RESTful API让全文搜索变得简单并隐藏Lucene的复杂性。 不过,Elasticsearch不仅仅是Lucene和全文搜索引擎,它还提供:
- 分布式的实时文件存储,每个字段都被索引并可被搜索
- 实时分析的分布式搜索引擎
- 可以扩展到上百台服务器,处理PB级结构化或非结构化数据
而且,所有的这些功能被集成到一台服务器,你的应用可以通过简单的RESTful API、各种语言的客户端甚至命令行与之交互。上手Elasticsearch非常简单,它提供了许多合理的缺省值,并对初学者隐藏了复杂的搜索引擎理论。它开箱即用(安装即可使用),只需很少的学习既可在生产环境中使用。Elasticsearch在Apache 2 license下许可使用,可以免费下载、使用和修改。 随着知识的积累,你可以根据不同的问题领域定制Elasticsearch的高级特性,这一切都是可配置的,并且配置非常灵活。
以上内容来自 [百度百科]
Elasticsearch中涉及到的重要概念
Elasticsearch有几个核心概念。从一开始理解这些概念会对整个学习过程有莫大的帮助。
(1) 接近实时(NRT) Elasticsearch是一个接近实时的搜索平台。这意味着,从索引一个文档直到这个文档能够被搜索到有一个轻微的延迟(通常是1秒)。
(2) 集群(cluster) 一个集群就是由一个或多个节点组织在一起,它们共同持有你整个的数据,并一起提供索引和搜索功能。一个集群由一个唯一的名字标识,这个名字默认就是“elasticsearch”。这个名字是重要的,因为一个节点只能通过指定某个集群的名字,来加入这个集群。在产品环境中显式地设定这个名字是一个好习惯,但是使用默认值来进行测试/开发也是不错的。
(3) 节点(node) 一个节点是你集群中的一个服务器,作为集群的一部分,它存储你的数据,参与集群的索引和搜索功能。和集群类似,一个节点也是由一个名字来标识的,默认情况下,这个名字是一个随机的漫威漫画角色的名字,这个名字会在启动的时候赋予节点。这个名字对于管理工作来说挺重要的,因为在这个管理过程中,你会去确定网络中的哪些服务器对应于Elasticsearch集群中的哪些节点。
一个节点可以通过配置集群名称的方式来加入一个指定的集群。默认情况下,每个节点都会被安排加入到一个叫做“elasticsearch”的集群中,这意味着,如果你在你的网络中启动了若干个节点,并假定它们能够相互发现彼此,它们将会自动地形成并加入到一个叫做“elasticsearch”的集群中。
在一个集群里,只要你想,可以拥有任意多个节点。而且,如果当前你的网络中没有运行任何Elasticsearch节点,这时启动一个节点,会默认创建并加入一个叫做“elasticsearch”的集群。
(4) 索引(index) 一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。索引类似于关系型数据库中Database的概念。在一个集群中,如果你想,可以定义任意多的索引。
(5) 类型(type) 在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定。通常,会为具有一组共同字段的文档定义一个类型。比如说,我们假设你运营一个博客平台并且将你所有的数据存储到一个索引中。在这个索引中,你可以为用户数据定义一个类型,为博客数据定义另一个类型,当然,也可以为评论数据定义另一个类型。类型类似于关系型数据库中Table的概念。
(6)文档(document)
一个文档是一个可被索引的基础信息单元。比如,你可以拥有某一个客户的文档,某一个产品的一个文档,当然,也可以拥有某个订单的一个文档。文档以JSON(Javascript Object Notation)格式来表示,而JSON是一个到处存在的互联网数据交互格式。
在一个index/type里面,只要你想,你可以存储任意多的文档。注意,尽管一个文档,物理上存在于一个索引之中,文档必须被索引/赋予一个索引的type。文档类似于关系型数据库中Record的概念。实际上一个文档除了用户定义的数据外,还包括_index
、_type
和_id
字段。
(7) 分片和复制(shards & replicas) 一个索引可以存储超出单个结点硬件限制的大量数据。比如,一个具有10亿文档的索引占据1TB的磁盘空间,而任一节点都没有这样大的磁盘空间;或者单个节点处理搜索请求,响应太慢。
为了解决这个问题,Elasticsearch提供了将索引划分成多份的能力,这些份就叫做分片。当你创建一个索引的时候,你可以指定你想要的分片的数量。每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。 分片之所以重要,主要有两方面的原因:
- 允许你水平分割/扩展你的内容容量
- 允许你在分片(潜在地,位于多个节点上)之上进行分布式的、并行的操作,进而提高性能/吞吐量
至于一个分片怎样分布,它的文档怎样聚合回搜索请求,是完全由Elasticsearch管理的,对于作为用户的你来说,这些都是透明的。
在一个网络/云的环境里,失败随时都可能发生,在某个分片/节点不知怎么的就处于离线状态,或者由于任何原因消失了。这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。为此目的,Elasticsearch允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片,或者直接叫复制。复制之所以重要,主要有两方面的原因:
- 在分片/节点失败的情况下,提供了高可用性。因为这个原因,注意到复制分片从不与原/主要(original/primary)分片置于同一节点上是非常重要的。
- 扩展你的搜索量/吞吐量,因为搜索可以在所有的复制上并行运行
总之,每个索引可以被分成多个分片。一个索引也可以被复制0次(意思是没有复制)或多次。一旦复制了,每个索引就有了主分片(作为复制源的原来的分片)和复制分片(主分片的拷贝)之别。分片和复制的数量可以在索引创建的时候指定。在索引创建之后,你可以在任何时候动态地改变复制数量,但是不能改变分片的数量。
默认情况下,Elasticsearch中的每个索引被分片5个主分片和1个复制,这意味着,如果你的集群中至少有两个节点,你的索引将会有5个主分片和另外5个复制分片(1个完全拷贝),这样的话每个索引总共就有10个分片。一个索引的多个分片可以存放在集群中的一台主机上,也可以存放在多台主机上,这取决于你的集群机器数量。主分片和复制分片的具体位置是由ES内在的策略所决定的。
以上部分内容转自Elasticsearch基础教程,并对其进行了补充。
Elasticsearch安装与配置
安装与运行
(1) 从这里下载Elasticsearch安装包。一共提供4种格式的安装包(ZIP、TAR.GZ、DEB和RPM),可以根据自己所使用的系统平台选择相应格式的安装包进行下载。(建议使用Linux系统,本人在2台windows机器上尝试启动过,一台机器上无法正常启动,另外一台可以)
(2) 对下载的安装包进行解压缩即可完成安装操作。下面以在Ubuntu操作系统下使用TAR.GZ格式的1.5.0版本的安装包为例进行安装。在Linux shell中输入下面的命令解压缩。
代码语言:text复制tar –vxf elasticsearch-1.5.0.tar.gz
安装成功,下面运行ES。
代码语言:javascript复制 注意:Elasticsearch需要Java虚拟机的支持,在运行之前保证机器上安装了JDK,并且JDK版本不能低于1.7_55。
(3) 现在可以直接使用默认配置启动Elasticsearch了。 假设安装包解压后的目录路径为【/home/elasticsearch/elasticsearch-1.5.0】,下面军用$ES_HOME来表示这个路径。执行下面的命令:
代码语言:shell复制 cd /home/elasticsearch/elasticsearch-1.5.0/bin/
chmod x *
./elasticsearch
如果出现如图所示的界面(最后打印出started),则说明Elasticsearch启动成功。
下面来验证一下是否真的启动成功。打开浏览器,访问网址这里的host是ES的安装主机地址,如果安装在本机。如果显示下面的信息,则表示ES安装成功。
代码语言:json复制{
"status" : 200,
"name" : "Captain Zero",
"cluster_name" : "elasticsearch",
"version" : {
"number" : "1.5.0",
"build_hash" : "544816042d40151d3ce4ba4f95399d7860dc2e92",
"build_timestamp" : "2015-03-23T14:30:58Z",
"build_snapshot" : false,
"lucene_version" : "4.10.4"
},
"tagline" : "You Know, for Search"
}
上面是前台启动方式,一旦关闭Linux shell,ES服务就会停止。所以是实际使用过程中,绝对不会使用这种方式去启动ES。除了上面的启动方式外,还可以加上一定的启动参数。例如:
代码语言:shell复制 ./elasticsearch –d #在后台运行Elasticsearch
代码语言:shell复制 ./elasticsearch -d -Xmx2g -Xms2g #后台启动,启动时指定内存大小(2G)
代码语言:text复制 ./elasticsearch -d -Des.logger.level=DEBUG #可以在日志中打印出更加详细的信息。
ES的配置
配置文件所在的目录路径如下:$ES_HOME/config/elasticsearch.yml。 下面介绍一些重要的配置项及其含义。
(1)cluster.name: elasticsearch
配置elasticsearch的集群名称,默认是elasticsearch。elasticsearch会自动发现在同一网段下的集群名为elasticsearch的主机,如果在同一网段下有多个集群,就可以用这个属性来区分不同的集群。生成环境时建议更改。
(2)node.name: “Franz Kafka”
节点名,默认随机指定一个name列表中名字,该列表在elasticsearch的jar包中config文件夹里name.txt文件中,其中有很多作者添加的有趣名字,大部分是漫威动漫里面的人物名字。生成环境中建议更改以能方便的指定集群中的节点对应的机器
(3)node.master: true
指定该节点是否有资格被选举成为node,默认是true,elasticsearch默认集群中的第一台启动的机器为master,如果这台机挂了就会重新选举master。
(4)node.data: true
指定该节点是否存储索引数据,默认为true。如果节点配置node.master:false并且node.data: false,则该节点将起到负载均衡的作用
(5)index.number_of_shards: 5
设置默认索引分片个数,默认为5片。经本人测试,索引分片对ES的查询性能有很大的影响,在应用环境,应该选择适合的分片大小。
(6)index.number_of_replicas:
设置默认索引副本个数,默认为1个副本。此处的1个副本是指index.number_of_shards的一个完全拷贝;默认5个分片1个拷贝;即总分片数为10。
(7)path.conf: /path/to/conf
设置配置文件的存储路径,默认是es根目录下的config文件夹。
(8)path.data:/path/to/data1,/path/to/data2
设置索引数据的存储路径,默认是es根目录下的data文件夹,可以设置多个存储路径,用逗号隔开。
(9)path.work:/path/to/work
设置临时文件的存储路径,默认是es根目录下的work文件夹。
(10)path.logs: /path/to/logs
设置日志文件的存储路径,默认是es根目录下的logs文件夹
(11)path.plugins: /path/to/plugins
设置插件的存放路径,默认是es根目录下的plugins文件夹
(12)bootstrap.mlockall: true
设置为true来锁住内存。因为当jvm开始swapping时es的效率会降低,所以要保证它不swap,可以把ES_MIN_MEM和ES_MAX_MEM两个环境变量设置成同一个值,并且保证机器有足够的内存分配给es。同时也要允许elasticsearch的进程可以锁住内存,linux下可以通过
ulimit -l unlimited
命令。
(13)network.bind_host: 192.168.0.1
设置绑定的ip地址,可以是ipv4或ipv6的,默认为0.0.0.0。
(14)network.publish_host: 192.168.0.1
设置其它节点和该节点交互的ip地址,如果不设置它会自动判断,值必须是个真实的ip地址。
(15)network.host: 192.168.0.1
这个参数是用来同时设置bind_host和publish_host上面两个参数。
(16)transport.tcp.port: 9300
设置节点间交互的tcp端口,默认是9300。
(17)transport.tcp.compress: true
设置是否压缩tcp传输时的数据,默认为false,不压缩。
(18)http.port: 9200
设置对外服务的http端口,默认为9200。
(19)http.max_content_length: 100mb
设置内容的最大容量,默认100mb
(20)http.enabled: false
是否使用http协议对外提供服务,默认为true,开启。
(21)gateway.type: local
gateway的类型,默认为local即为本地文件系统,可以设置为本地文件系统,分布式文件系统,hadoop的HDFS,和amazon的s3服务器,其它文件系统的设置。
(22)gateway.recover_after_nodes: 1
设置集群中N个节点启动时进行数据恢复,默认为1。
(23)gateway.recover_after_time: 5m
设置初始化数据恢复进程的超时时间,默认是5分钟。
(24)gateway.expected_nodes: 2
设置这个集群中节点的数量,默认为2,一旦这N个节点启动,就会立即进行数据恢复。
(25)cluster.routing.allocation.node_initial_primaries_recoveries: 4
初始化数据恢复时,并发恢复线程的个数,默认为4。
(26)cluster.routing.allocation.node_concurrent_recoveries: 2
添加删除节点或负载均衡时并发恢复线程的个数,默认为4。
(27)indices.recovery.max_size_per_sec: 0
设置数据恢复时限制的带宽,如入100mb,默认为0,即无限制。
(28)indices.recovery.concurrent_streams: 5
设置这个参数来限制从其它分片恢复数据时最大同时打开并发流的个数,默认为5。
(29)discovery.zen.minimum_master_nodes: 1
设置这个参数来保证集群中的节点可以知道其它N个有master资格的节点。默认为1,对于大的集群来说,可以设置大一点的值(2-4)
(30)discovery.zen.ping.timeout: 3s
设置集群中自动发现其它节点时ping连接超时时间,默认为3秒,对于比较差的网络环境可以高点的值来防止自动发现时出错。
(31)discovery.zen.ping.multicast.enabled: false
设置是否打开多播发现节点,默认是true。
(32)discovery.zen.ping.unicast.hosts: [“host1”, “host2:port”, “host3 [portX-portY] “]
设置集群中master节点的初始列表,可以通过这些节点来自动发现新加入集群的节点。
除了上面的在安装时配置文件中就自带的配置项外,本人在实际使用过程还使用到了下面的配置:
代码语言:text复制threadpool:
search:
type: fixed
min: 60
max: 80
queue_size: 1000
// 配置es服务器的执行查询操作时所用线程池,fix固定线程数的线程池。
代码语言:text复制index :
store:
type: memory
// 表示索引存储在内存中,当然es不太建议这么做。经本人测试,做查询时,使用内存索引并不会比正常的索引快。
代码语言:text复制index.mapper.dynamic: false
// 禁止自动创建mapping。默认情况下,es可以根据数据类型自动创建mapping。配置成这样,可以禁止自动创建mapping的行为。至于什么是mapping,在之后的博文中再介绍。
代码语言:text复制index.query.parse.allow_unmapped_fields: false
// 不能查找没有在mapping中定义的属性
以上总结介绍了Elasticsearch中的一些基础知识,包括其中的一些核心概念。只有理解了ES中的这些核心概念,才能对更加得心应手地使用ES,发挥其强大的搜索能力。同时,也介绍了ES的安装和运行,ES的安装和运行是很简单的,只需要极少的简单步骤,就可以开始体验ES。ES的配置非常丰富,安装时自带的配置文件只包含一部分比较核心的配置项,更多的配置内容需要自己去阅读ES的源码时才能被发现。
ES Restful API基本使用:
ES为开发者提供了非常丰富的基于HTTP协议的Rest API,只需要向ES服务端发送简单的Rest请求,就可以实现非常强大的功能。本篇文章主要介绍ES中常用操作的Rest API的使用,同时会讲解ES的源代码工程中的API接口文档,通过了解这个API文档的接口描述结构,就基本上可以实现ES中的绝大部分功能。
注意:查询是ES的核心。作为一个先进的搜索引擎,ES中提供了多种查询接口。本篇仅仅会涉及查询API的结构,而具体如何使用ES所提供的各种查询API,会在接下来的博文中做详细介绍。
基础知识
如果之前没有用过类似于ES这样的索引数据库(暂且将ES归为数据库类,与传统的数据库有较大的区别),要理解本篇博文介绍的API是有些难度的。本节先介绍一些基础知识,对理解全文有很帮助。
Rest介绍
笔者在学习软件开发过程中,多次听到过Rest Http这个概念,但在很长的一段时间里,死活搞不懂这玩意到底是个什么东西。刚开始看相关资料时,看得云里雾里,完全不知所云 _。这玩意太过于抽象和理论,心里觉得有必要搞这么复杂么。随着自己动手开发的东西越来越多,才开始对它有了一丢丢感觉。
Rest完全不是三言两语就能将清楚的,它有自己的一套体系,所以笔者打算以后单独写一些有关Rest的博文。在这里推荐一篇优秀的文章,它对Rest讲的相当清楚,本人看完之后真有醍醐灌顶的感觉!
Mapping详解
Mapping是ES中的一个很重要的内容,它类似于传统关系型数据中table的schema,用于定义一个索引(index)的某个类型(type)的数据的结构。
在传统关系型数据库,我们必须首先创建table并同时定义其schema,如下面的SQL语句。下面代码中小括号内的代码的作用就是定义person_info的schema(模式)。
代码语言:javascript复制create table person_info
(
name varchar(20),
age tinyint
)
在ES中,我们无需手动创建type(相当于table)和mapping(相关与schema)。在默认配置下,ES可以根据插入的数据自动地创建type及其mapping。在下面的API介绍部分中,会做相关的试验。当然,在实际使用过程中我们可能就想硬性规定mapping,可以通过配置文件关闭ES的自动创建mapping功能。
mapping中主要包括字段名、字段数据类型和字段索引类型这3个方面的定义。
字段名:这就不用说了,与传统数据库字段名作用一样,就是给字段起个唯一的名字,好让系统和用户能识别。
字段数据类型:定义该字段保存的数据的类型,不符合数据类型定义的数据不能保存到ES中。下表列出的是ES中所支持的数据类型。(大类是对所有类型的一种归类,小类是实际使用的类型。)
大类 | 包含的小类 |
---|---|
String | string |
Whole number | byte, short, integer, long |
Floating point | float, double |
Boolean | boolean |
Date | date |
字段索引类型:索引是ES中的核心,ES之所以能够实现实时搜索,完全归功于Lucene这个优秀的Java开源索引。在传统数据库中,如果字段上建立索引,我们仍然能够以它作为查询条件进行查询,只不过查询速度慢点。而在ES中,字段如果不建立索引,则就不能以这个字段作为查询条件来搜索。也就是说,不建立索引的字段仅仅能起到数据载体的作用。string类型的数据肯定是日常使用得最多的数据类型,下面介绍mapping中string类型字段可以配置的索引类型。
索引类型 | 解释 |
---|---|
analyzed | 首先分析这个字符串,然后再建立索引。换言之,以全文形式索引此字段。 |
not_analyzed | 索引这个字段,使之可以被搜索,但是索引内容和指定值一样。不分析此字段。 |
no | 不索引这个字段。这个字段不能被搜索到。 |
如果索引类型设置为analyzed,在表示ES会先对这个字段进行分析(一般来说,就是自然语言中的分词),ES内置了不少分析器(analyser),如果觉得它们对中文的支持不好,也可以使用第三方分析器。由于笔者在实际项目中仅仅将ES用作普通的数据查询引擎,所以并没有研究过这些分析器。如果将ES当做真正的搜索引擎,那么挑选正确的分析器是至关重要的。
mapping中除了上面介绍的3个主要的内容外,还有其他的定义内容,详见官网文档。
常用的Rest API介绍
下面介绍一下ES中的一些常用的Rest API。掌握了这些API的用法,基本上就可以简单地使用ES了。
我们需要借助能够发送HTTP请求的工具调用这些API,工具是可以任意的,包括网页浏览器。这里利用Linux上的curl命令来发送HTTP请求。基本的命令结构为:
代码语言:shell复制 curl <-Xaction> url -d 'body'
# 这里的action表示HTTP协议中的各种动作,包括GET、POST、PUT、DELETE等。
注意。文中的示例代码里面包含了用户注释的文字,就是 # 号后面的文字。运行代码时,请注意删除这些注释。
查看集群(Cluster)信息相关API
(1)查看集群健康信息。
代码语言:text复制 curl -XGET "localhost:9200/_cat/heath?v"
返回结果为:
代码语言:css复制epoch timestamp cluster status node.total node.data shards pri relo init unassign pending_tasks
1440206633 18:23:53 elasticsearch green 1 1 0 0 0 0 0 0
返回结果的主要字段意义:
- cluster:集群名,是在ES的配置文件中配置的cluster.name的值。
- status:集群状态。集群共有green、yellow或red中的三种状态。green代表一切正常(集群功能齐全),yellow意味着所有的数据都是可用的,但是某些复制没有被分配(集群功能齐全),red则代表因为某些原因,某些数据不可用。如果是red状态,则要引起高度注意,数据很有可能已经丢失。
- node.total:集群中的节点数。
- node.data:集群中的数据节点数。
- shards:集群中总的分片数量。
- pri:主分片数量,英文全称为private。
- relo:复制分片总数。
- unassign:未指定的分片数量,是应有分片数和现有的分片数的差值(包括主分片和复制分片)。
我们也可以在请求中添加help参数来查看每个操作返回结果字段的意义。
代码语言:text复制 curl -XGET "localhost:9200/_cat/heath?help"
返回结果如下:
代码语言:text复制epoch | t,time | seconds since 1970-01-01 00:00:00
timestamp | ts,hms,hhmmss | time in HH:MM:SS
cluster | cl | cluster name
status | st | health status
node.total | nt,nodeTotal | total number of nodes
node.data | nd,nodeData | number of nodes that can store data
shards | t,sh,shards.total,shardsTotal | total number of shards
pri | p,shards.primary,shardsPrimary | number of primary shards
relo | r,shards.relocating,shardsRelocating | number of relocating nodes
init | i,shards.initializing,shardsInitializing | number of initializing nodes
unassign | u,shards.unassigned,shardsUnassigned | number of unassigned shards
pending_tasks | pt,pendingTasks | number of pending tasks
确实是很好很强大。有了这个东东,就可以减少看文档的时间。ES中许多API都可以添加help参数来显示字段含义,哪些可以这么做呢?每个API都试试就知道了。
当然,如果你觉得返回的东西太多,看着眼烦,我们也可以人为地指定返回的字段。
代码语言:text复制 curl -XGET "localhost:9200/_cat/health?h=cluster,pri,relo&v"
这次的返回结果就简单很多罗。对于患有严重强迫症的患者来说,这是福音啊!
代码语言:text复制cluster pri relo
elasticsearch 0 0
(2)查看集群中的节点信息。
代码语言:text复制 curl -XGET "localhost:9200/_cat/nodes?v"
返回节点的详细信息如下:
代码语言:text复制host ip heap.percent ram.percent load node.role master name
master.hadoop localhost 3 35 0.00 d * Ezekiel
(3)查看集群中的索引信息。
代码语言:text复制 curl -XGET "localhost:9200/_cat/indices?v"
返回集群中的索引信息如下:
代码语言:text复制health status index pri rep docs.count docs.deleted store.size pri.store.size
yellow open index_test 5 1 0 0 575b 575b
更多的查看和监视ES的API参见官网文档。
索引(Index)相关API
(1)创建一个新的索引。
代码语言:text复制curl -XPUT "localhost:9200/index_test"
如果返回下面的信息,则说明索引创建成功。如果不是,则ES会返回相应的异常信息。通常可以通过异常信息的最后一项推断出失败的原因。
代码语言:json复制{
"acknowledged": true
}
上面的操作使用默认的配置信息创建一个索引。大多数情况下,我们想在索引创建的时候就将我们所需的mapping和其他配置确定好。下面的操作就可以在创建索引的同时,创建settings和mapping。
代码语言:shell复制curl -XPUT "localhost:9200/index_test" -d ' # 注意这里的'号
{
"settings": {
"index": {
"number_of_replicas": "1", # 设置复制数
"number_of_shards": "5" # 设置主分片数
}
},
"mappings": { # 创建mapping
"test_type": { # 在index中创建一个新的type(相当于table)
"properties": {
"name": { # 创建一个字段(string类型数据,使用普通索引)
"type": "string",
"index": "not_analyzed"
},
"age": {
"type": "integer"
}
}
}
}
}'
(2)删除一个索引。
代码语言:text复制curl -XDELETE "localhost:9200/index_test"
如果返回与创建索引同样的信息,则说明删除成功。反之,则返回相应的异常信息。更多的索引操作参见ES官网文档。
映射(Mapping)相关API
(1)创建索引的mapping。
代码语言:text复制curl -XPUT 'localhost:9200/index_test/_mapping/test_type' -d '
{
"test_type": { # 注意,这里的test_type与url上的test_type名保存一致
"properties": {
"name": {
"type": "string",
"index": "not_analyzed"
},
"age": {
"type": "integer"
}
}
}
}'
如果不想单独创建mapping,可以使用上一节的方法(创建索引时创建mappings)。
假设我们的项目中有多个环境(开发环境、测试环境等),那每一个环境的mapping总要一致的吧,那每次创建一次mappings就比较麻烦了,而且还容易导致数据不一致。莫急,ES还给我们准备另外一种创建mapping的方式。可以按照下面的步骤来做。
步骤1 创建一个扩展名为test_type.json的文件名,其中type_test就是mapping所对应的type名。
步骤2 在test_type.json中输入mapping信息。假设你的mapping如下:
代码语言:javascript复制{
"test_type": { # 注意,这里的test_type与json文件名必须一致
"properties": {
"name": {
"type": "string",
"index": "not_analyzed"
},
"age": {
"type": "integer"
}
}
}
}
步骤3 在$ES_HOME/config/路径下创建mappings/index_test子目录,这里的index_test目录名必须与我们要建立的索引名一致。将test_type.json文件拷贝到index_tes目录下。
步骤4 创建index_test索引。操作如下:
代码语言:shell复制curl -XPUT "localhost:9200/index_test" # 注意,这里的索引名必须与mappings下新建的index_test目录名一致
这样我们就创建了一个新的索引,并且使用了test_type.json所定义的mapping作为索引的mapping。就是这么简单方便!
(2)删除mapping。
代码语言:text复制curl -XDELETE 'localhost:9200/index_test/_mapping/test_type'
(3)查看索引的mapping。
代码语言:text复制curl -XGET 'localhost:9200/index_test/_mapping/test_type'
更多的mapping相关操作参加官网文档。
文档(document)相关API
(1)新增一个文档。
代码语言:text复制curl -XPUT 'localhost:9200/index_test/test_type/1?pretty' -d ' # 这里的pretty参数的作用是使得返回的json显示地更加好看。1是文档的id值(唯一键)。
{
"name": "zhangsan",
"age" : "12"
}'
(2)更新一个文档
代码语言:text复制curl -XPOST 'localhost:9200/index_test/test_type/1?pretty' -d ' # 这里的1必须是索引中已经存在id,否则就会变成新增文档操作
{
"name": "lisi",
"age" : "12"
}'
(3)删除一个文档
代码语言:shell复制curl -XDELETE 'localhost:9200/index_test/test_type/1?pretty' # 这里的1必须是索引中已经存在id
(4)查询单个文档
代码语言:text复制curl -XGET 'localhost:9200/index_test/test_type/1?pretty'
上面的操作仅仅查询id为1的一条文档,这样看似乎ES的查询也太弱了。前面已经说过了,查询操作是ES中的核心,是其立身的根本。但是本文的重点并不在这里,为了防止文章的篇幅过长,之后将专本介绍ES中的查询操作。
源代码中提供的Rest API文档结构
ES的源代码托管在Github上。将源代码下载下来之后,里面有一个文件夹专门存放ES中绝大部分的Rest API。有了这些文档,就不必每次都要到官网上查询接口文档了(PS:ES的官网真的很慢)。 下面以cat.health.json文件为例简单地介绍这些Rest API文档的结构。一旦结构搞清楚了,文档看起来就比较顺心,ES用起来就更加得心应手了!
代码语言:c#复制{
"cat.health": {
"documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/master/cat-health.html", # 该文档对应的官方站点
"methods": ["GET"],
"url": { # url部分可选
"path": "/_cat/health",
"paths": ["/_cat/health"],
"parts": {
},
"params": {
"local": {
"type" : "boolean",
"description" : "Return local information, do not retrieve the state from master node (default: false)"
},
"master_timeout": {
"type" : "time",
"description" : "Explicit operation timeout for connection to master node"
},
"h": {
"type": "list",
"description" : "Comma-separated list of column names to display"
},
"help": {
"type": "boolean",
"description": "Return help information",
"default": false
},
"ts": {
"type": "boolean",
"description": "Set to false to disable timestamping",
"default": true
},
"v": {
"type": "boolean",
"description": "Verbose mode. Display column headers",
"default": true
}
}
},
"body": null
}
}
上面文档接口所对应的Reqeust操作如下:
代码语言:text复制curl -XGET "localhost:9200/_cat/health?v" -d 'body'
该操作命令可划分为5个部分,下面把这5个部分与文档对应起来。通过这个例子,就可以在阅读其他文档后,使用正确的操作了。
- 第1部分(-XGET):对应文档中methods所包含的GET操作。
- 第2部分(localhost:9200):是ES服务端所在主机的hostname和port。
- 第3部分(/_cat/health):对应文档中的url。其中path是最简单的url;paths是除了path之外的其他url;parts描述和解释paths里面的url的可变部分(通常用{}包裹,如{index})。
- 第4部分v:表示参数,对应文档中的params。像“v”这种boolean类型的参数,不需要特意指定其布尔值(true或者false),出现即表示true,否则为false。
- 第5部分body:表示要传递的数据主体,对应文档中的body。如果body里面指明“required=true”,则表示必须传入body数据。具体body里面需要传怎样的数据,则可以访问文档中的documentation字段所指明的官方站点进行查询。
总结
本文重点介绍了ES中的一些常用Rest API的用法,并在开始部分简单地介绍了一些基础知识(Rest和mapping)。掌握了这些API的调用,就可以利用ES完成简单的应用程序了。当然,ES的API远不止这些,如果想要更加深入地了解ES的使用及其内部原理,建议先仔细地阅读ES的官网文档。然后下载其源代码进行研究。
想进阶的同学,请参考: