ElasticSearch是一个高度可扩展的开源搜索引擎并使用REST API,所以您值得拥有。 在本教程中,将介绍开始使用ElasticSearch的一些主要概念。
ElasticSearch可以从elasticsearch 下载对应的文件格式,如ZIP
和TAR.GZ
。下载并提取一个运行它的软件包之后不会容易得多,需要提前安装Java运行时环境。
在本文章中,所使用的环境是Windows,所以这里只介绍在Windows上运行ElasticSearch,可从命令窗口运行位于bin
文件夹中的elasticsearch.bat
。这将会启动ElasticSearch在控制台的前台运行,这意味着我们可在控制台中看到运行信息或一些错误信息,并可以使用CTRL + C停止或关闭它。
当前版本是: elasticsearch-5.2.0 下载链接: http://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.2.0.zip
把下载好的文件 elasticsearch-5.2.0.zip
解压到 D:\software\elasticsearch-5.2.0
,其目录结构如下所示 -
在启动过程中,ElasticSearch的实例运行会占用大量的内存,所以在这一过程中,电脑会变得比较慢,需要耐心等待,启动加载完成后电脑就可以正常使用了。
如果您没有安装Java运行时或没有正确配置,应该不会看到像上面的输出,而是一个消息说“JAVA_HOME环境变量必须设置!" 要解决这个问题,首先下载并安装Java,其次,确保已正确配置JAVA_HOME
环境变量(或参考 - Java JDK安装和配置)。
当ElasticSearch的实例并运行,您可以使用localhost:9200
,基于JSON的REST API与ElasticSearch进行通信。使用任何HTTP客户端来通信。在ElasticSearch自己的文档中,所有示例都使用curl。 但是,当使用API时也可使用图形客户端(如Fiddler或RESTClient),这样操作起更方便直观一些。
更方便的是Chrome插件Sense。 Sense提供了一个专门用于使用ElasticSearch的REST API的简单用户界面。 它还具有许多方便的功能,例如:ElasticSearch的查询语法的自动完成功能以及curl格式的复制和粘贴请求,从而可以方便地在文档中运行示例。
我们将在本教程中使用sense来执行curl请求,建议安装Sense并使用它学习后续文章内容。
安装完成后,在Chrome的右上角找到Sense的图标。 第一次单击它运行Sense时,会为您准备一个非常简单的示例请求。如下图所示 -
执行请求后,可以看到接收到来自ElasticSearch响应的JSON对象。如下所示 -
{
"_index": "movies",
"_type": "movie",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": true
}
响应对象包含有关索引操作的信息,例如它是否成功(“ok”)和文档ID,如果不指定则ElasticSearch会自己生成一个。
如果运行Sense提供的默认搜索请求(可以使用Sense中的“历史记录”按钮访问,因为确实已执行它)过了,就会看到返回有数据的结果。
{
"took": 146,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "movies",
"_type": "movie",
"_id": "1",
"_score": 1,
"_source": {
"title": "The Godfather",
"director": "Francis Ford Coppola",
"year": 1972
}
}
]
}
}
在上面返回结果中,看到的是搜索结果而不是错误或是空的结果。
现在,在索引中有了一部电影信息,接下来来了解如何更新它,添加一个类型列表。要做到这一点,只需使用相同的ID索引它。使用与之前完全相同的索引请求,但类型扩展了JSON对象。
curl -XPUT "http://localhost:9200/movies/movie/1" -d'
{
"title": "The Godfather",
"director": "Francis Ford Coppola",
"year": 1972,
"genres": ["Crime", "Drama"]
}'
ElasticSearch的响应结果与前面的大体上一样,但有一点区别,结果对象中的_version
属性的值为2
,而不是1
。响应结果如下 -
{
"_index": "movies",
"_type": "movie",
"_id": "1",
"_version": 2,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": false
}
版本号(_version
)可用于跟踪文档已编入索引的次数。它的主要目的是允许乐观的并发控制,因为可以在索引请求中提供一个版本,如果提供的版本高于索引中的版本,ElasticSearch将只覆盖文档内容,ID值不变,版本号自动添加。
上面已经学习了索引新文档以及更新存在的文档。还看到了一个简单搜索请求的示例。如果只是想检索一个具有已知ID的索引,一个方法是搜索索引中的文档。另一个简单而快速的方法是通过ID
,使用GET
来检索它。
简单的做法是向同一个URL发出一个GET请求,URL的ID部分是强制性的。通过ID从ElasticSearch中检索文档可发出URL的GET请求:http://localhost:9200///
。
使用以下请求尝试获取电影信息:
curl -XGET "http://localhost:9200/movies/movie/1" -d''
执行结果如下所示 -
在执行DELETE
调用后切换回GET
,可以验证文档是否确实已删除。
在前面,已经介绍了在ElasticSearch索引中处理数据的基础知识,现在是时候进行核心功能的学习了。考虑到之前我们删除索引中的所有文档,所以,在进行搜索学习之前,需要一些添加一些示例数据。使用以下这些请求和数据对象来创建索引。
curl -XPUT "http://localhost:9200/movies/movie/1" -d'
{
"title": "The Godfather",
"director": "Francis Ford Coppola",
"year": 1972,
"genres": ["Crime", "Drama"]
}'
curl -XPUT "http://localhost:9200/movies/movie/2" -d'
{
"title": "Lawrence of Arabia",
"director": "David Lean",
"year": 1962,
"genres": ["Adventure", "Biography", "Drama"]
}'
curl -XPUT "http://localhost:9200/movies/movie/3" -d'
{
"title": "To Kill a Mockingbird",
"director": "Robert Mulligan",
"year": 1962,
"genres": ["Crime", "Drama", "Mystery"]
}'
curl -XPUT "http://localhost:9200/movies/movie/4" -d'
{
"title": "Apocalypse Now",
"director": "Francis Ford Coppola",
"year": 1979,
"genres": ["Drama", "War"]
}'
curl -XPUT "http://localhost:9200/movies/movie/5" -d'
{
"title": "Kill Bill: Vol. 1",
"director": "Quentin Tarantino",
"year": 2003,
"genres": ["Action", "Crime", "Thriller"]
}'
curl -XPUT "http://localhost:9200/movies/movie/6" -d'
{
"title": "The Assassination of Jesse James by the Coward Robert Ford",
"director": "Andrew Dominik",
"year": 2007,
"genres": ["Biography", "Crime", "Drama"]
}'
值得指出的是,ElasticSearch具有和端点(_bulk
)用于用单个请求索引多个文档,但是这超出了本教程的范围,这里只保持简单,使用六个单独的请求学习。
现在已经把一些电影信息放入了索引,可以通过搜索看看是否可找到它们。 为了使用ElasticSearch进行搜索,我们使用_search
端点,可选择使用索引和类型。也就是说,按照以下模式向URL发出请求://_search
。其中,index
和type
都是可选的。
换句话说,为了搜索电影,可以对以下任一URL进行POST请求:
因为我们只有一个单一的索引和单一的类型,所以怎么使用都不会有什么问题。为了简洁起见使用第一个URL。
如果只是发送一个请求到上面的URL,我们会得到所有的电影信息。为了创建更有用的搜索请求,还需要向请求正文中提供查询。 请求正文是一个JSON对象,除了其它属性以外,它还要包含一个名称为“query
”的属性,这就可使用ElasticSearch的查询DSL。
{
"query": {
//Query DSL here
}
}
你可能想知道查询DSL是什么。它是ElasticSearch自己基于JSON的域特定语言,可以在其中表达查询和过滤器。想象ElasticSearch它像关系数据库的SQL。这里是ElasticSearch自己的文档解释它的一部分(英文好自己撸吧):
Think of the Query DSL as an AST of queries. Certain queries can contain other queries (like the bool query), other can contain filters (like the constant_score), and some can contain both a query and a filter (like the filtered). Each of those can contain any query of the list of queries or any filter from the list of filters, resulting in the ability to build quite complex (and interesting) queries. see more: http://www.elasticsearch /guide/reference/query-dsl/
查询DSL具有一长列不同类型的查询可以使用。 对于“普通”自由文本搜索,最有可能想使用一个名称为“查询字符串查询”。
查询字符串查询是一个高级查询,有很多不同的选项,ElasticSearch将解析和转换为更简单的查询树。如果忽略了所有的可选参数,并且只需要给它一个字符串用于搜索,它可以很容易使用。
现在尝试在两部电影的标题中搜索有“kill”这个词的电影信息:
curl -XPOST "http://localhost:9200/_search" -d'
{
"query": {
"query_string": {
"query": "kill"
}
}
}'
执行上面的请求并查看结果,如下所示 -
正如预期的得到一个命中,电影的标题中的单词“ford
”。现在,从查询中移除fields
属性,应该能匹配到 3
行数据:
在上面的示例中,使用过滤器限制查询字符串查询的结果。如果想要做的是应用一个过滤器呢? 也就是说,我们希望所有电影符合一定的标准。
在这种情况下,我们仍然在搜索请求正文中使用“query
”属性。但是,我们不能只是添加一个过滤器,需要将它包装在某种查询中。
一个解决方案是修改当前的搜索请求,替换查询字符串 query
过滤查询中的match_all
查询,这是一个查询,只是匹配一切。类似下面这个:
curl -XPOST "http://localhost:9200/_search" -d'
{
"query": {
"filtered": {
"query": {
"match_all": {
}
},
"filter": {
"term": { "year": 1962 }
}
}
}
}'
另一个更简单的方法是使用常数分数查询:
curl -XPOST "http://localhost:9200/_search" -d'
{
"query": {
"constant_score": {
"filter": {
"term": { "year": 1962 }
}
}
}
}'
参考:http://www.yiibai /elasticsearch/elasticsearch-getting-start.html
Linux版参考:http://www.ruanyifeng /blog/2017/08/elasticsearch.html