elasticsearch使用 JSON (或称作JavaScript Object Notation ) 作为文档序列化的格式。JSON 已经被大多数语言支持,也成为 NoSQL 领域的一个标准格式。它简单、简洁、易于阅读。
为了能让你感受一下 Elasticsearch 能做什么以及它是有多么的易用,我们会先为你简单展示一下,其中包括了基本的 创建索引,搜索 以及 聚合。
2.rest api
上文我们讲解了elasticsearch的安装,已经插件head的安装,此时我们可以看到http://localhost:9200/_plugin/head/ 页面显示是空的,
2.1 命令行查看elasticsearch状态:
2.1.1 检测集群是否健康
curl 'localhost:9200/_cat/health?v'
- 1
绿色表示一切正常, 黄色表示所有的数据可用但是部分副本还没有分配,红色表示部分数据因为某些原因不可用。
2.1.2 获取集群的节点列表
curl 'localhost:9200/_cat/nodes?v'
- 1
2.1.3 列出所有索引
curl 'localhost:9200/_cat/indices?v'
- 1
2.2 索引crud
此时,es里面是没有索引的,我们现在开始创建一个员工索引,在 Elasticsearch 中,存储数据的行为就叫做 索引(indexing) ,但是在我们索引数据前,我们需要决定将数据存储在哪里。
在 Elasticsearch 中,文档属于一种 类型(type),各种各样的类型存在于一个 索引 中。你也可以通过类比传统的关系数据库得到一些大致的相似之处:
关系数据库 ⇒ 数据库 ⇒ 表 ⇒ 行 ⇒ 列(Columns)
Elasticsearch ⇒ 索引 ⇒ 类型 ⇒ 文档 ⇒ 字段(Fields)
- 1
- 2
一个 Elasticsearch 集群可以包含多个 索引(数据库),也就是说其中包含了很多 类型(表)。这些类型中包含了很多的 文档(行),然后每个文档中又包含了很多的 字段(列)。
2.2.1 创建索引
curl -XPUT 'localhost:9200/company?pretty'
- 1
上图中红框所表示的是:我们有一个叫company的索引,它有五个私有的分片以及一个副本,在它里面有0个文档。此时的索引company就类似传统数据库中的数据库名字。
2.2.2 插入数据
curl -XPUT 'localhost:9200/company/employee/1?pretty' -d '
{"first_name":"master",
"last_name":"tian",
"age":25,
"about":"I am master tian",
"interests":["sport","basketball"]
}'
- 1
- 2
- 3
- 4
- 5
- 6
- 7
ps:单引号是可以不用写的,但是这里写上去是因为,命令行太长,直接转行的话,命令就会执行前半截,忽视后半截;
curl -XPUT 'localhost:9200/company/employee/2?pretty' -d '
{"first_name":"dada",
"last_name":"tian",
"age":30,
"about":"I am a strong man",
"interests":["game","sport"]
}'
- 1
- 2
- 3
- 4
- 5
- 6
- 7
curl -XPUT 'localhost:9200/company/employee/3?pretty' -d '
{"first_name":"baojian",
"last_name":"zou",
"age":28,
"about":"I am a little Nanjing",
"interests":["seafood","eat"]
}'
- 1
- 2
- 3
- 4
- 5
- 6
- 7
我们插入了三条employee信息,简易搜索一下:
curl -XGET localhost:9200/company/employee/_search?pretty
- 1
可以查到我们插入的三条信息,这边就粘贴结果了。
2.2.3 修改数据
curl -XPUT 'localhost:9200/company/employee/1?pretty' -d '
{"first_name":"master",
"last_name":"tian",
"age":25,
"about":"I am master tian",
"interests":["game","basketball"]
}'
- 1
- 2
- 3
- 4
- 5
- 6
- 7
其实跟插入一样,也就是如果不存在该id就插入,如果存在就修改。
2.2.4 删除
删除数据:
curl -XDELETE localhost:9200/company/employee/3?pretty
- 1
删除索引:
curl -XDELETE localhost:9200/company?pretty
- 1
我们通过将HTTP后的请求方式由 PUT 改变为 GET 来获取文档,同理,我们也可以将其更换为 DELETE 来删除这个文档,HEAD 是用来查询这个文档是否存在的。如果你想替换一个已经存在的文档,你只需要使用 PUT 再次发出请求即可。
2.3 查询
elasticsearch最主要的就是查询,所有查询是重中之重。
2.3.1 简易查询
我们上面讲过了,
curl -XGET localhost:9200/company/employee/_search?pretty
- 1
简易查询类似与sql语句中的select * from table;
2.3.2 查询字符串
下面我们尝试着实现搜索一下哪些员工的姓氏中包含 tian。为了实现这个,我们需要使用一种轻量的搜索方法。这种方法经常被称做 查询字符串(query string) 搜索,因为我们通过URL来传递查询的关键字:
curl -XGET localhost:9200/company/employee/_search?q=last_name:tian
- 1
2.3.3 Query DSL
查询字符串是通过命令语句完成 点对点(ad hoc) 的搜索,但是这也有它的局限性。Elasticsearch 提供了更加丰富灵活的查询语言,它被称作 Query DSL,通过它你可以完成更加复杂、强大的搜索任务。
DSL (Domain Specific Language 领域特定语言) 需要使用 JSON 作为主体,我们还可以这样查询姓 Smith 的员工:
curl -XGET 'localhost:9200/company/employee/_search' -d '
{
"query" : {
"match" : {
"last_name":"tian"
}
}
}'
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
我们依旧要寻找出姓 Smith 的员工,但是我们还将添加一个年龄大于30岁的限定条件。我们的查询语句将会有一些细微的调整来以识别结构化搜索的限定条件 filter(过滤器):
curl -XGET 'localhost:9200/company/employee/_search' -d '
{
"query" : {
"filtered" :{
"filter":{
"range":{
"age":{"gt":28}
}
},
"query" : {
"match" : {
"last_name":"tian"
}
}
}
}
}'
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
尽管统一称之为query DSL,事实上Elasticsearch中存在两种DSL:查询DSL(query DSL)和过滤DSL(filter DSL)。查询子句和过滤子句的自然属性非常相近,但在使用目的上略有区别。简单来讲,当执行full-text查询或查询结果依赖于相关度分值时应该使用查询DSL,当执行精确值(extac-value)查询或查询结果仅有“yes”或“no”两种结果时应该使用过滤DSL,也就是说查询DSL偏向于分词查询,过滤DSL偏向于精确查询。
Filter DSL计算及过滤速度较快,且适于缓存,因此可有效提升后续查询请求的执行速度。而query DSL不仅要查找匹配的文档,还需要计算每个文件的相关度分值,因此为更重量级的查询,其查询结果不会被缓存。不过,得益于倒排索引,一个仅返回少量文档的简单query或许比一个跨数百万文档的filter执行起来并得显得更慢。
Filter DSL中常见的有term Filter、terms Filter、range Filter、exists and missing Filters和bool Filter。而Query DSL中常见的有match_all、match 、multi_match及bool Query。