介绍ElasticSearch
Elasticsearch 是一个实时的分布式搜索分析引擎,它能让你以前所未有的速度和规模,去探索你的数据。 它被用作全文检索、结构化搜索、分析以及这三个功能的组合:
- Wikipedia 使用 Elasticsearch 提供带有高亮片段的全文搜索,还有 search-as-you-type 和 did-you-mean 的建议。
- 卫报 使用 Elasticsearch 将网络社交数据结合到访客日志中,为它的编辑们提供公众对于新文章的实时反馈。
- Stack Overflow 将地理位置查询融入全文检索中去,并且使用 more-like-this 接口去查找相关的问题和回答。
- GitHub 使用 Elasticsearch 对1300亿行代码进行查询。
Elasticsearch 不仅仅为巨头公司服务。它也帮助了很多初创公司,比如 Datadog 和 Klout, Elasticsearch 帮助他们将想法用原型实现,并转化为可扩展的解决方案。Elasticsearch 能运行在你的笔记本电脑上,或者扩展到数百台服务器上来处理PB级数据。
Elasticsearch 中没有一个单独的组件是全新的或者是革命性的。全文搜索很久之前就已经可以做到了, 就像很早之前出现的分析系统和分布式数据库。 革命性的成果在于将这些单独的,有用的组件融合到一个单一的、一致的、实时的应用中。对于初学者而言它的门槛相对较低, 而当你的技能提升或需求增加时,它也始终能满足你的需求。
如果你现在打开这本书,是因为你拥有数据。除非你准备使用它 做些什么 ,否则拥有这些数据将没有意义。
不幸的是,大部分数据库在从你的数据中提取可用知识时出乎意料的低效。 当然,你可以通过时间戳或精确值进行过滤,但是它们能够全文检索、处理同义词、通过相关性给文档评分么? 它们能从同样的数据中生成分析与聚合数据吗?最重要的是,它们能实时地做到上述操作,而不经过大型批处理的任务么?
这就是 Elasticsearch 脱颖而出的地方:Elasticsearch 鼓励你去探索与利用数据,而不是因为查询数据太困难,就让它们烂在数据仓库里面。
Elasticsearch 将成为你最好的朋友。
Elasticsearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库 Apache Lucene™ 基础之上。 Lucene 可以说是当下最先进、高性能、全功能的搜索引擎库—无论是开源还是私有。
但是 Lucene 仅仅只是一个库。为了充分发挥其功能,你需要使用 Java 并将 Lucene 直接集成到应用程序中。 更糟糕的是,您可能需要获得信息检索学位才能了解其工作原理。Lucene 非常 复杂。
Elasticsearch 也是使用 Java 编写的,它的内部使用 Lucene 做索引与搜索,但是它的目的是使全文检索变得简单, 通过隐藏 Lucene 的复杂性,取而代之的提供一套简单一致的 RESTful API。
然而,Elasticsearch 不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎。 它可以被下面这样准确的形容:
- 一个分布式的实时文档存储,每个字段 可以被索引与搜索
- 一个分布式实时分析搜索引擎
- 能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据
Elasticsearch 将所有的功能打包成一个单独的服务,这样你可以通过程序与它提供的简单的 RESTful API 进行通信, 可以使用自己喜欢的编程语言充当 web 客户端,甚至可以使用命令行(去充当这个客户端)。
就 Elasticsearch 而言,起步很简单。对于初学者来说,它预设了一些适当的默认值,并隐藏了复杂的搜索理论知识。 它 开箱即用 。只需最少的理解,你很快就能具有生产力。
随着你知识的积累,你可以利用 Elasticsearch 更多的高级特性,它的整个引擎是可配置并且灵活的。 从众多高级特性中,挑选恰当去修饰的 Elasticsearch,使它能解决你本地遇到的问题。
你可以免费下载,使用,修改 Elasticsearch。它在 Apache 2 license 协议下发布的, 这是众多灵活的开源协议之一。Elasticsearch 的源码被托管在 Github 上 github.com/elastic/elasticsearch。
和ElasticSearch交互
和 Elasticsearch 的交互方式取决于你是否使用 Java
Java API
如果你正在使用 Java,在代码中你可以使用 Elasticsearch 内置的两个客户端:
节点客户端(Node client)
节点客户端作为一个非数据节点加入到本地集群中。换句话说,它本身不保存任何数据,但是它知道数据在集群中的哪个节点中,并且可以把请求转发到正确的节点。
传输客户端(Transport client)
轻量级的传输客户端可以将请求发送到远程集群。它本身不加入集群,但是它可以将请求转发到集群中的一个节点上。
两个 Java 客户端都是通过 9300 端口并使用 Elasticsearch 的原生 传输 协议和集群交互。集群中的节点通过端口 9300 彼此通信。如果这个端口没有打开,节点将无法形成一个集群。
Java 客户端作为节点必须和 Elasticsearch 有相同的 主要 版本;否则,它们之间将无法互相理解。
RESTful API with JSON over HTTP
所有其他语言可以使用 RESTful API 通过端口 9200 和 Elasticsearch 进行通信,你可以用你最喜爱的 web 客户端访问 Elasticsearch 。事实上,正如你所看到的,你甚至可以使用 curl 命令来和 Elasticsearch 交互。
Elasticsearch 为以下语言提供了官方客户端--Groovy、JavaScript、.NET、 PHP、 Perl、 Python 和 Ruby—还有很多社区提供的客户端和插件,所有这些都可以在 Elasticsearch Clients 中找到。
一个 Elasticsearch 请求和任何 HTTP 请求一样由若干相同的部件组成:
curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
被 < >
标记的部件:
VERB
适当的 HTTP 方法 或 谓词 : GET、 POST、 PUT、 HEAD 或者 DELETE。
PROTOCOL
http 或者 https(如果你在 Elasticsearch 前面有一个 https 代理)
HOST
Elasticsearch 集群中任意节点的主机名,或者用 localhost 代表本地机器上的节点。
PORT
运行 Elasticsearch HTTP 服务的端口号,默认是 9200 。
PATH
API 的终端路径(例如 _count 将返回集群中文档数量)。Path 可能包含多个组件,例如:_cluster/stats 和 _nodes/stats/jvm 。
QUERY_STRING
任意可选的查询字符串参数 (例如 ?pretty 将格式化地输出 JSON 返回值,使其更容易阅读)
BODY
一个 JSON 格式的请求体 (如果请求需要的话)
例如,计算集群中文档的数量,可以用这个:
curl -XGET 'http://localhost:9200/_count?pretty' -d ' { "query": { "match_all": {} } } '
Elasticsearch 返回一个 HTTP 状态码(例如:200 OK)和(除`HEAD`请求)一个 JSON 格式的返回值。前面的 curl 请求将返回一个像下面一样的 JSON 体:
{ "count" : 0, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 } }
在返回结果中没有看到 HTTP 头信息是因为没有要求`curl`显示它们。想要看到头信息,需要结合 -i 参数来使用 curl 命令:
curl -i -XGET 'localhost:9200/'
在剩余的部分,用缩写格式来展示这些 curl 示例,所谓的缩写格式就是省略请求中所有相同的部分,例如主机名、端口号以及 curl 命令本身。而不是像下面显示的那样用一个完整的请求:
curl -XGET 'localhost:9200/_count?pretty' -d ' { "query": { "match_all": {} } }'
用缩写格式显示:
curl -X GET "localhost:9200/_count?pretty" -H 'Content-Type: application/json' -d' { "query": { "match_all": {} } } '
面向文档
在应用程序中对象很少只是一个简单的键和值的列表。通常,它们拥有更复杂的数据结构,可能包括日期、地理信息、其他对象或者数组等。
也许有一天你想把这些对象存储在数据库中。使用关系型数据库的行和列存储,这相当于是把一个表现力丰富的对象塞到一个非常大的电子表格中:为了适应表结构,你必须设法将这个对象扁平化—通常一个字段对应一列—而且每次查询时又需要将其重新构造为对象。
Elasticsearch 是 面向文档 的,意味着它存储整个对象或 文档。Elasticsearch 不仅存储文档,而且 索引 每个文档的内容,使之可以被检索。在 Elasticsearch 中,我们对文档进行索引、检索、排序和过滤—而不是对行列数据。这是一种完全不同的思考数据的方式,也是 Elasticsearch 能支持复杂全文检索的原因。
JSON
Elasticsearch 使用 JavaScript Object Notation(或者 JSON)作为文档的序列化格式。JSON 序列化为大多数编程语言所支持,并且已经成为 NoSQL 领域的标准格式。 它简单、简洁、易于阅读。
下面这个 JSON 文档代表了一个 user 对象:
{ "email": "john@smith.com", "first_name": "John", "last_name": "Smith", "info": { "bio": "Eco-warrior and defender of the weak", "age": 25, "interests": [ "dolphins", "whales" ] }, "join_date": "2014/05/01" }
虽然原始的 user 对象很复杂,但这个对象的结构和含义在 JSON 版本中都得到了体现和保留。在 Elasticsearch 中将对象转化为 JSON 后构建索引要比在一个扁平的表结构中要简单的多。
几乎所有的语言都有可以将任意的数据结构或对象转化成 JSON 格式的模块,只是细节各不相同。具体请查看 serialization 或者 marshalling 这两个处理 JSON 的模块。官方 Elasticsearch 客户端 自动为您提供 JSON 转化。