为了更好的操作es,这里安装了kibana进行辅助操作,并且实际使用的过程也是使用kibana进行操作的
安装 Sense
Sense 是一个 Kibana 程序,它的交互式控制台可以帮助你直接通过浏览器向 Elasticsearch 提交请求。 在书籍的在线版中,众多的代码示例都包含了 View in Sense 链接。当你点击之 后,它将自动在 Sense 控制台中运行这段代码。你并不是一定要安装 Sense,但那将失去很 多与本书的互动以及直接在你本地的集群中的实验代码的乐趣。
在 Kibana 的目录中运行以下命令以下载并安装 Sense 程序:(5.0之后使用devtool进行支持)
使用命令进行写入
GET方式
curl -XGET 'http://localhost:9200/_count?pretty' -d ' { "query": { "match_all": {} } } '
- 相应的 HTTP 请求方法 或者 变量 : GET , POST , PUT , HEAD 或者 DELETE 。
- 集群中任意一个节点的访问协议、主机名以及端口。
- 请求的路径。
- 任意一个查询后再加上 ?pretty 就可以生成 更加美观 的JSON反馈,以增强可读性。
- 一个 JSON 编码的请求主体(如果需要的话)。
响应内容
{ "count" : 0, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 } }
建立一个员工名单
想象我们正在为一个名叫 megacorp 的公司的 HR 部门制作一个新的员工名单系统,这些名 单应该可以满足实时协同工作,所以它应该可以满足以下要求:
- 数据可以包含多个值的标签、数字以及纯文本内容,
- 可以检索任何职员的所有数据。
- 允许结构化搜索。例如,查找30岁以上的员工。
- 允许简单的全文搜索以及相对复杂的短语搜索。
- 在返回的匹配文档中高亮关键字。
- 拥有数据统计与管理的后台。
关系数据库 ⇒ 数据库 ⇒ 表 ⇒ 行 ⇒ 列(Columns) Elasticsearch ⇒ 索引 ⇒ 类型 ⇒ 文档 ⇒ 字段(Fields)
所以为了创建员工名单,我们需要进行如下操作:
- 为每一个员工的 文档 创建索引,每个 文档 都包含了一个员工的所有信息
- 每个文档都会被标记为 employee 类型。
- 这种类型将存活在 megacorp 这个 索引 中。
- 这个索引将会存储在 Elasticsearch 的集群中
添加一个索引库
curl -XPUT 'http://localhost:9200/megacorp/employee/1?pretty' -d ' { "first_name" : "John", "last_name" : "Smith", "age" : 25, "about" : "I love to go rock climbing", "interests": [ "sports", "music" ] }' curl -XPUT 'http://localhost:9200/megacorp/employee/2?pretty' -d ' { "first_name" : "Jane", "last_name" : "Smith", "age" : 32, "about" : "I like to collect rock albums", "interests": [ "music" ] } ' curl -XPUT 'http://localhost:9200/megacorp/employee/3?pretty' -d ' { "first_name" : "Douglas", "last_name" : "Fir", "age" : 35, "about": "I like to build cabinets", "interests": [ "forestry" ] } '
{ "_index" : "megacorp", "_type" : "employee", "_id" : "1", "_version" : 1, "result" : "created", "_shards" : { "total" : 2, "successful" : 1, "failed" : 0 }, "created" : true } megacorp 索引的名字 employee 类型的名字 1 当前员工的ID
检索文档
curl -XGET 'localhost:9200/megacorp/employee/1?pretty'
返回的内容包含了这个文档的元数据信息,而 John Smith 的原始 JSON 文档也在 _source 字段中出现了:
{ "_index" : "megacorp", "_type" : "employee", "_id" : "1", "_version" : 1, "found" : true, "_source" : { "first_name" : "John", "last_name" : "Smith", "age" : 25, "about" : "I love to go rock climbing", "interests": [ "sports", "music" ] } }
我们通过将HTTP后的请求方式由 PUT 改变为 GET 来获取文档,同理,我们也可以将其更 换为 DELETE 来删除这个文档, HEAD 是用来查询这个文档是否存在的。如果你想替换一个 已经存在的文档,你只需要使用 PUT 再次发出请求即可。
简易搜索
搜索全部员工:
curl -XGET 'localhost:9200/megacorp/employee/_search?pretty'
响应数据
{ "took" : 9, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 3, "max_score" : 1.0, "hits" : [ { "_index" : "megacorp", "_type" : "employee", "_id" : "2", "_score" : 1.0, "_source" : { "first_name" : "Jane", "last_name" : "Smith", "age" : 32, "about" : "I like to collect rock albums", "interests" : [ "music" ] } }, { "_index" : "megacorp", "_type" : "employee", "_id" : "1", "_score" : 1.0, "_source" : { "first_name" : "John", "last_name" : "Smith", "age" : 25, "about" : "I love to go rock climbing", "interests" : [ "sports", "music" ] } }, { "_index" : "megacorp", "_type" : "employee", "_id" : "3", "_score" : 1.0, "_source" : { "first_name" : "Douglas", "last_name" : "Fir", "age" : 35, "about" : "I like to build cabinets", "interests" : [ "forestry" ] } } ] } }
查询字符串(query string) 搜索
简写:
GET /megacorp/employee/_search?q=last_name:Smith
非简写:
curl -XGET 'localhost:9200/megacorp/employee/_search?q=last_name:Fir&pretty' (查找last_name=Far的员工)
使用Query DSL搜索
查询字符串是通过命令语句完成 点对点(ad hoc) 的搜索,但是这也有它的局限性(可参阅
《搜索局限性》章节)。Elasticsearch 提供了更加丰富灵活的查询语言,它被称作 Query
DSL,通过它你可以完成更加复杂、强大的搜索任务。
查询语句
curl -XGET '172.18.118.222:9200/megacorp/employee/_search?pretty' -d ' { "query" : { "match" : { "last_name" : "Smith" } } } '
查询结果
{ "took" : 2, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 2, "max_score" : 0.2876821, "hits" : [ { "_index" : "megacorp", "_type" : "employee", "_id" : "2", "_score" : 0.2876821, "_source" : { "first_name" : "Jane", "last_name" : "Smith", "age" : 32, "about" : "I like to collect rock albums", "interests" : [ "music" ] } }, { "_index" : "megacorp", "_type" : "employee", "_id" : "1", "_score" : 0.2876821, "_source" : { "first_name" : "John", "last_name" : "Smith", "age" : 25, "about" : "I love to go rock climbing", "interests" : [ "sports", "music" ] } } ] } }
更加复杂的搜索
接下来,我们再提高一点儿搜索的难度。我们依旧要寻找出姓 Smith 的员工,但是我们还将 添加一个年龄大于30岁的限定条件。我们的查询语句将会有一些细微的调整来以识别结构化 搜索的限定条件 filter(过滤器):
curl -XGET 'localhost:9200/megacorp/employee/_search?pretty' -d ' { "query" : { "filtered":{ "filter":{ "range":{ "age":{"gt": "30"} } }, "query":{ "match":{ "last_name":"Smith" } } } } } '
这一部分的语句是 range filter ,它可以查询所有超过30岁的数据 -- gt 代表 greater than (大于)
no [query] registered for [filtered]**
解决办法: 过滤查询已被弃用,并在ES 5.0中删除。现在应该使用bool / must / filter查询。
curl -XPOST '172.18.118.222:9200/megacorp/employee/_search?pretty' -d ' { "query": { "bool": { "filter": { "range": { "age": { "gt": 20 } } }, "must": { "match": { "last_name": "Smith" } } } } } '
结果
{ "took" : 9, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 2, "max_score" : 0.2876821, "hits" : [ { "_index" : "megacorp", "_type" : "employee", "_id" : "2", "_score" : 0.2876821, "_source" : { "first_name" : "Jane", "last_name" : "Smith", "age" : 32, "about" : "I like to collect rock albums", "interests" : [ "music" ] } }, { "_index" : "megacorp", "_type" : "employee", "_id" : "1", "_score" : 0.2876821, "_source" : { "first_name" : "John", "last_name" : "Smith", "age" : 25, "about" : "I love to go rock climbing", "interests" : [ "sports", "music" ] } } ] } }
全文搜索
curl -XPOST '172.18.118.222:9200/megacorp/employee/_search?pretty' -d ' { "query" : { "match" : { "about" : "rock climbing" } } } '
结果
{ "took" : 25, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 2, "max_score" : 0.53484553, "hits" : [ { "_index" : "megacorp", "_type" : "employee", "_id" : "1", "_score" : 0.53484553, "_source" : { "first_name" : "John", "last_name" : "Smith", "age" : 25, "about" : "I love to go rock climbing", "interests" : [ "sports", "music" ] } }, { "_index" : "megacorp", "_type" : "employee", "_id" : "2", "_score" : 0.26742277, "_source" : { "first_name" : "Jane", "last_name" : "Smith", "age" : 32, "about" : "I like to collect rock albums", "interests" : [ "music" ] } } ] } }
你会发现我们同样使用了 match 查询来搜索 about 字段中的 rock climbing。我们会得到 两个匹配的文档:
通常情况下,Elasticsearch 会通过相关性来排列顺序,第一个结果中,John Smith 的 about 字段中明确地写到 rock climbing。而在 Jane Smith 的 about 字段中,提及到了 rock,但 是并没有提及到 climbing,所以后者的 _score 就要比前者的低。