段落搜索
curl -XPOST '172.18.118.222:9200/megacorp/employee/_search?pretty' -d ' { "query" : { "match_phrase" : { "about" : "rock climbing" } } } '
结果
{ "took" : 23, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1, "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" ] } } ] } }
高亮我们的搜索
curl -XPOST '172.18.118.222:9200/megacorp/employee/_search?pretty' -d ' { "query" : { "match_phrase" : { "about" : "rock climbing" } }, "highlight": { "fields" : { "about" : {} } } } '
结果
{ "took" : 7, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1, "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" ] }, "highlight" : { "about" : [ "I love to go <em>rock</em> <em>climbing</em>" ] } } ] } }
统计
最后,我们还有一个需求需要完成:可以让老板在职工目录中进行统计。Elasticsearch 把这 项功能称作 汇总 (aggregations),通过这个功能,我们可以针对你的数据进行复杂的统计。 这个功能有些类似于 SQL 中的 GROUP BY ,但是要比它更加强大。
例如,让我们找一下员工中最受欢迎的兴趣是什么:
curl -XPOST '172.18.118.222:9200/megacorp/employee/_search?pretty' -d ' { "aggs": { "all_interests": { "terms": { "field": "interests" } } } } '
Fielddata is disabled on text fields by default. Set fielddata=true on [interests] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead
默认情况下,在文本字段上禁用Fielddata。 在[的兴趣]上设置fielddata = true,以便通过反转索引来加载内存中的fielddata。 请注意,这可能会占用大量内存。 或者,也可以使用关键字字段
(fielddata会消耗大量的栈内存,尤其在进行加载文本的时候,所以一单fielddata完成了加载,就会一直存在。)
curl -XPOST '172.18.118.222:9200/megacorp/employee/_search?pretty' -d ' { "aggs": { "all_interests": { "terms": { "field": "interests.keyword" } } } } '
结果(截取部分)
"aggregations" : { "all_interests" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : "music", "doc_count" : 2 }, { "key" : "forestry", "doc_count" : 1 }, { "key" : "sports", "doc_count" : 1 } ] } }
查询汇总
curl -XGET '172.18.118.222:9200/megacorp/employee/_search?pretty' -d ' { "query": { "match": { "last_name": "Smith" } }, "aggs": { "all_interests": { "terms": { "field": "interests.keyword" } } } } '
结果
{ "took" : 11, "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" ] } } ] }, "aggregations" : { "all_interests" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : "music", "doc_count" : 2 }, { "key" : "sports", "doc_count" : 1 } ] } } }
汇总还允许多个层面的统计。比如我们还可以统计每一个兴趣下的平均年龄:
curl -XGET '172.18.118.222:9200/megacorp/employee/_search?pretty' -d ' { "aggs" : { "all_interests" : { "terms" : { "field" : "interests.keyword" }, "aggs" : { "avg_age" : { "avg" : { "field" : "age" } } } } } } '
结果
"aggregations" : { "all_interests" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 0, "buckets" : [ { "key" : "music", "doc_count" : 2, "avg_age" : { "value" : 28.5 } }, { "key" : "forestry", "doc_count" : 1, "avg_age" : { "value" : 35.0 } }, { "key" : "sports", "doc_count" : 1, "avg_age" : { "value" : 25.0 } } ] } }
ElasticSearch 分布式特性
Elasticsearch 很努力地在避免复杂的分布式系统,很多操作都是自动完成的:
- 可以将你的文档分区到不同容器或者 分片 中,这些文档可能被存在一个节点或者多个节 点。
- 跨节点平衡集群中节点间的索引与搜索负载。
- 自动复制你的数据以提供冗余副本,防止硬件错误导致数据丢失。
- 自动在节点之间路由,以帮助你找到你想要的数据。 无缝扩展或者恢复你的集群
空集群
- 节点 是 Elasticsearch 运行中的实例,而 集群 则包含一个或多个具有相同 cluster.name 的 节点,它们协同工作,共享数据,并共同分担工作负荷。由于节点是从属集群的,集群会自 我重组来均匀地分发数据。
- 集群中的一个节点会被选为 master 节点,它将负责管理集群范畴的变更,例如创建或删除索 引,添加节点到集群或从集群删除节点。master 节点无需参与文档层面的变更和搜索,这意 味着仅有一个 master 节点并不会因流量增长而成为瓶颈。任意一个节点都可以成为 master 节点。我们例举的集群只有一个节点,因此它会扮演 master 节点的角色。
- 作为用户,我们可以访问包括 master 节点在内的集群中的任一节点。每个节点都知道各个文 档的位置,并能够将我们的请求直接转发到拥有我们想要的数据的节点。无论我们访问的是 哪个节点,它都会控制从拥有数据的节点收集响应的过程,并返回给客户端最终的结果。这 一切都是由 Elasticsearch 透明管理的。
集群健康
在 Elasticsearch 集群中可以监控统计很多信息,其中最重要的就是:集群健康(cluster health)。它的 status 有 green 、 yellow 、 red 三种;
GET /_cluster/health
{ "cluster_name": "elasticsearch", "status": "green", <1> "timed_out": false, "number_of_nodes": 1, "number_of_data_nodes": 1, "active_primary_shards": 0, "active_shards": 0, "relocating_shards": 0, "initializing_shards": 0, "unassigned_shards": 0 }
status 是我们最应该关注的字段。
状态 | 意义 |
green | 所有主分片和从分片都可用 |
yellow | 所有主分片可用,但存在不可用的从分片 |
red | 存在不可用的主要分片 |
添加索引
PUT /blogs { "settings" : { "number_of_shards" : 3, "number_of_replicas" : 1 } }