elasticsearch.

搜索,你懂的

好吧,假如你建了一个web站点或者是一个应用程序,你就可能会需要添加搜索功能(因为这太有必要了),而事实上让搜索跑起来是有难度的,我们不仅想要搜索的速度快,而且还要安装方便(最好是无痛安装),另外模式定义要非常自由(schema free),可以通过HTTP以JSON格式的数据来进行索引,服务器必须是一直可用的(HA高可用,这个不能丢),从一台机器能够扩展到成千上万台,然后搜索必须是实时的(real-time),使用起来一定要简单、支持多租户,我们需要一整套的解决方案,并且是为云构建的。

“让搜索更简单”,这是我们的宣言,“并且要酷,像盆景一样”

elasticsearch 的目标是解决上面的所有问题以及更多。她是开源的(Apache2协议),分布式的,RESTful的,构建在Apache Lucene之上的的搜索引擎.

模式自由(Schema Free) & 面向文档的 (Document Oriented)

搜索引擎的数据模型属于模式自由以及数据库是面向文档的,以目前#nosql的发展趋势来看,使用这种数据模型来构建应用程序已经被证明是非常高效的。

elasticsearch 的模型基于 JSON, 事实上,在近些年,它俨然已经成为数据呈现的一个标准,此外,通过JSON,可以非常简单的表示半结构化的数据,同样的,大多数编程语言都会优先支持JSON数据的解析.

先来看几个简单的例子,都是创建索引的。(ps:curl是一个linux下的处理HTTP请求的一个工具,你可以使用fiddler或者其他类似的工具来执行elasticsearch提供的RESTful接口)。
//索引
$ curl -XPUT http://localhost:9200/twitter/user/kimchy -d '{
    "name" : "Shay Banon"
}'

//索引,多个field
$ curl -XPUT http://localhost:9200/twitter/tweet/1 -d '{
    "user": "kimchy",
    "post_date": "2009-11-15T13:12:00",
    "message": "Trying out elasticsearch, so far so good?"
}'

//索引,注意url里面的id是不一样的哦
$ curl -XPUT http://localhost:9200/twitter/tweet/2 -d '{
    "user": "kimchy",
    "post_date": "2009-11-15T14:12:12",
    "message": "You know, for Search"
}'

模式映射(Schema Mapping)

elasticsearch 是无模式的,你随便往里面扔一个JSON格式的文档,然后ES就可以自动的进行索引。 输入的内容如果是数字或者是时间类型,ES也自动的检测出来,并做相应的处理。

但是,总所周知,搜索引擎是非常复杂的,索引文档中的字段是可以设置BOOST值来影响打分的,另外还可以使用不同的分析器(Analyzer)用来控制怎么分词,比如有些字段是需要进行分词的,但是有些则不一定,如此等等。elasticsearch允许你完全控制这些规则,最终将一个JSON文档映射到搜索引擎里面。并且可以按索引(Index)和按类型(Type)2种级别来进行设置.

//创建索引
$ curl -XPUT http://localhost:9200/twitter

//创建Mapping
$ curl -XPUT http://localhost:9200/twitter/user/_mapping -d '{
    "properties" : {
        "name" : { "type" : "string" }
    }
}'

获取数据(GETting Some Data)

每个索引的文档都必须要有一个唯一标识(在类型级别),在很多时候这是非常有用的,比如你想更新或者删除某一个索引文档,或者只是想拿一条索引数据看看。 获取数据真是简单的不能再简单了,你只需用告诉es指定文档的索引、类型、和id就可以拿回实际的索引文档了(就是你建索引的时候的JSON文档),嘘,你知道就可以了,不要告诉其他的还在使用key/value来做分布式存储的人。。。

//索引
$ curl -XPUT http://localhost:9200/twitter/tweet/2 -d '{
    "user": "kimchy",
    "post_date": "2009-11-15T14:12:12",
    "message": "You know, for Search"
}'

//获取
$ curl -XGET http://localhost:9200/twitter/tweet/2

搜索(Search)

这才是最终我们想要的:能够被搜索,并且搜索从来没有这么简单过,处理查询只需要一个简单的请求,里面隐藏了很多复杂的es提供的基于分布式的操作。 可以简单的使用 Lucene通用的语法,或者使用基于JSON格式QueryDSL(DSL:领域特定语言)来构造搜索各种请求(更加灵活,方便构造复杂查询)。

搜索可不仅仅就是查询就结束了,方面/层面(facets),高亮,自定义脚本等等都是支持的。

//索引
$ curl -XPUT http://localhost:9200/twitter/tweet/2 -d '{
    "user": "kimchy",
    "post_date": "2009-11-15T14:12:12",
    "message": "You know, for Search"
}'

//lucene语法方式的查询
$ curl -XGET http://localhost:9200/twitter/tweet/_search?q=user:kimchy

//query DSL方式查询
$ curl -XGET http://localhost:9200/twitter/tweet/_search -d '{
    "query" : {
        "term" : { "user": "kimchy" }
    }
}'

//query DSL方式查询
$ curl -XGET http://localhost:9200/twitter/_search?pretty=true -d '{
    "query" : {
        "range" : {
            "post_date" : {
                "from" : "2009-11-15T13:00:00",
                "to" : "2009-11-15T14:30:00"
            }
        }
    }
}'

多租户(Multi Tenancy)

单个索引既然已经有了,那为什么还会需要不止一个索引呢,其实,有很多原因需要支持多索引,比如,对日志索引可以按周来分别存放,或者是对不同的索引进行不同的设置(比如,一个使用内存作为存储,一个使用文件系统来存储).

当有了多个索引之后,我们就想要能够跨索引来进行搜索(或者其他操作)。

//创建索引
$ curl -XPUT http://localhost:9200/kimchy

//创建索引
$ curl -XPUT http://localhost:9200/elasticsearch

//索引数据
$ curl -XPUT http://localhost:9200/elasticsearch/tweet/1 -d '{
    "post_date": "2009-11-15T14:12:12",
    "message": "Zug Zug",
    "tag": "warcraft"
}'

//索引数据
$ curl -XPUT http://localhost:9200/kimchy/tweet/1 -d '{
    "post_date": "2009-11-15T14:12:12",
    "message": "Whatyouwant?",
    "tag": "warcraft"
}'

//跨多个索引来进行查询
$ curl -XGET http://localhost:9200/kimchy,elasticsearch/tweet/_search?q=tag:warcraft

//查询所有索引下:_all是一个关键字
$ curl -XGET http://localhost:9200/_all/tweet/_search?q=tag:warcraft

设置(Settings)

能够进行配置本身就是一把双刃剑,我们想要的是能够打开就能尽快运行,中间无需任何配置,并且当有需要的时候能够控制应用程序的几乎所有方面。

elasticsearch 从构建之初就这种理念,所以几乎所有事情都是可配和可插拔的,此外,每个索引(index)都有其独立的配置,用来覆盖主配置(master settings) 。举例来说,一个索引可以配置为使用内存存储,10个分片和1个副本,而另外一个索引可以是使用文件系统存储,1个分片和10个副本。所有的索引级别(index)的设置都是可以在创建索引的时候通过YAML或者JSON格式来进行指定的。

//创建索引,并设置分片和副本参数
$ curl -XPUT http://localhost:9200/elasticsearch/ -d '{
    "settings" : {
        "number_of_shards" : 2,
        "number_of_replicas" : 3
    }
}'

分布式(Distributed)

elasticsearch的一个最主要的功能就是对分布式的支持,索引能够分拆为多个分片,每个分片可以有0个或者多个副本,集群中的每个数据节点,都可以承载一个或者多个分片,并且充当协调和处理各种操作分发到合适的分片上去。再平衡(Rebalancing)和路由(routing)这一切都是自动进行的。

时间之门(Gateway)

也许有一天,整个集群会崩溃(谁也无法保证因为什么原因),或者是因为特殊需要而进行关停,大多数情况,我们是需要让集群恢复到最后的一个状态的,并且让服务重新run起来 ,elasticsearch提供了一个叫做gateway的模块,允许你来做这件事情,你可以想想时间机器和搜索的结合(博客里面有一篇文章介绍)

集群的状态信息(包括事务日志)可以通过每个本地存储(默认模式)来重建,或共享存储(如NFS或者Amazon S3),当使用共享存储,集群状态信息会异步的复制过去。

此外,当使用共享存储来做持久化,索引信息可以完全的存放在内存里面,就算做整个集群的关闭再恢复也不会有问题。

Apache Lucene and the logo is a trademark of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners."

由于译者水平有限,难免会有不少问题,欢迎大家及时指出更正,文中有些地方不太好翻译的地方,会直接给出英文原文,方便对照,最后热烈欢迎大家加入到我们的译者团队,一起为es的中文社区出一把力
 
Fork me on GitHub