Elasticsearch客户端API使用Demo,

转载自官方文档,

以索引雇员文档为示例,

在命令行使用curl演示了一系列的Restful API操作。

1.索引雇员文档

第一个业务需求就是存储雇员数据。这将会以雇员文档的形式存储:

一个文档代表一个雇员。存储数据到Elasticsearch的行为叫做索引,但在索引一个文档之前,需要确定将文档存储在哪里。

一个Elasticsearch集群可以包含多个索引,相应的每个索引可以包含多个类型。这些不同的类型存储着多个文档,每个文档又有多个属性。

2.概念说明

你也许已经注意到索引这个词在Elasticsearch语境中包含多重意思,所以有必要做一点儿说明:

索引(名词):

如前所述,一个索引类似于传统关系数据库中的一个数据库,是一个存储关系型文档的地方。索引(index)的复数词为indices或indexes。

索引(动词):

索引一个文档就是存储一个文档到一个索引(名词)中以便它可以被检索和查询到。这非常类似于SQL语句中的INSERT关键词,除了文档已存在时新文档会替换旧文档情况之外。

倒排索引:

关系型数据库通过增加一个索引比如一个B树(B-tree)索引到指定的列上,以便提升数据检索速度。Elasticsearch和Lucene使用了一个叫做倒排索引的结构来达到相同的目的。

默认的,一个文档中的每一个属性都是被索引的(有一个倒排索引)和可搜索的。一个没有倒排索引的属性是不能被搜索到的。我们将在倒排索引讨论倒排索引的更多细节。

3.对于雇员目录,我们将做如下操作

每个雇员索引一个文档,包含该雇员的所有信息。

每个文档都将是employee类型。

该类型位于索引megacorp内。

该索引保存在我们的Elasticsearch集群中。

实践中这非常简单(尽管看起来有很多步骤),我们可以通过一条命令完成所有这些动作:

curl -XPUT 'localhost:9200/megacorp/employee/1?pretty' -H 'Content-Type: application/json' -d'

{

"first_name" : "John",

"last_name" : "Smith",

"age" : 25,

"about" : "I love to go rock climbing",

"interests": [ "sports", "music" ]

}

'

注意,路径/megacorp/employee/1包含了三部分的信息:

megacorp 索引名称

employee 类型名称

1 特定雇员的ID

请求体——JSON文档——包含了这位员工的所有详细信息,他的名字叫JohnSmith,今年25岁,喜欢攀岩。

很简单!无需进行执行管理任务,如创建一个索引或指定每个属性的数据类型之类的,可以直接只索引一个文档。Elasticsearch默认地完成其他一切,因此所有必需的管理任务都在后台使用默认设置完成。

4.进行下一步前,让我们增加更多的员工信息到目录中

curl -XPUT 'localhost:9200/megacorp/employee/2?pretty' -H 'Content-Type: application/json' -d'

{

"first_name" : "Jane",

"last_name" : "Smith",

"age" : 32,

"about" : "I like to collect rock albums",

"interests": [ "music" ]

}

'

curl -XPUT 'localhost:9200/megacorp/employee/3?pretty' -H 'Content-Type: application/json' -d'

{

"first_name" : "Douglas",

"last_name" : "Fir",

"age" : 35,

"about": "I like to build cabinets",

"interests": [ "forestry" ]

}

'

5.检索文档

目前我们已经在Elasticsearch中存储了一些数据,接下来就能专注于实现应用的业务需求了。第一个需求是可以检索到单个雇员的数据。

这在Elasticsearch中很简单。简单地执行一个HTTPGET请求并指定文档的地址——索引库、类型和ID。使用这三个信息可以返回原始的JSON文档:

curl -XGET 'localhost:9200/megacorp/employee/1?pretty'

返回结果包含了文档的一些元数据,以及_source属性,内容是JohnSmith雇员的原始JSON文档:

{

"_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。

6.轻量搜索

一个GET是相当简单的,可以直接得到指定的文档。现在尝试点儿稍微高级的功能,比如一个简单的搜索!

第一个尝试的几乎是最简单的搜索了。我们使用下列请求来搜索所有雇员:

curl -XGET 'localhost:9200/megacorp/employee/_search?pretty'

可以看到,我们仍然使用索引库megacorp以及类型employee,但与指定一个文档ID不同,这次使用_search。返回结果包括了所有三个文档,放在数组hits中。一个搜索默认返回十条结果。

{

"took": 6,

"timed_out": false,

"_shards": { ... },

"hits": {

"total": 3,

"max_score": 1,

"hits": [

{

"_index": "megacorp",

"_type": "employee",

"_id": "3",

"_score": 1,

"_source": {

"first_name": "Douglas",

"last_name": "Fir",

"age": 35,

"about": "I like to build cabinets",

"interests": [ "forestry" ]

}

},

{

"_index": "megacorp",

"_type": "employee",

"_id": "1",

"_score": 1,

"_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": 1,

"_source": {

"first_name": "Jane",

"last_name": "Smith",

"age": 32,

"about": "I like to collect rock albums",

"interests": [ "music" ]

}

}

]

}

}

注意:返回结果不仅告知匹配了哪些文档,还包含了整个文档本身:显示搜索结果给最终用户所需的全部信息。

接下来,尝试下搜索姓氏为Smith的雇员。为此,我们将使用一个高亮搜索,很容易通过命令行完成。这个方法一般涉及到一个查询字符串(query-string)搜索,因为我们通过一个URL参数来传递查询信息给搜索接口:

curl -XGET 'localhost:9200/megacorp/employee/_search?q=last_name:Smith&pretty'

我们仍然在请求路径中使用_search端点,并将查询本身赋值给参数q=。返回结果给出了所有的Smith:

{

...

"hits": {

"total": 2,

"max_score": 0.30685282,

"hits": [

{

...

"_source": {

"first_name": "John",

"last_name": "Smith",

"age": 25,

"about": "I love to go rock climbing",

"interests": [ "sports", "music" ]

}

},

{

...

"_source": {

"first_name": "Jane",

"last_name": "Smith",

"age": 32,

"about": "I like to collect rock albums",

"interests": [ "music" ]

}

}

]

}

}

7.使用查询表达式搜索

Query-string搜索通过命令非常方便地进行临时性的即席搜索,但它有自身的局限性(参见轻量搜索)。Elasticsearch提供一个丰富灵活的查询语言叫做查询表达式,它支持构建更加复杂和健壮的查询。

领域特定语言(DSL),指定了使用一个JSON请求。我们可以像这样重写之前的查询所有Smith的搜索:

curl -XGET 'localhost:9200/megacorp/employee/_search?pretty' -H 'Content-Type: application/json' -d'

{

"query" : {

"match" : {

"last_name" : "Smith"

}

}

}

'

返回结果与之前的查询一样,但还是可以看到有一些变化。其中之一是,不再使用query-string参数,而是一个请求体替代。这个请求使用JSON构造,并使用了一个match查询(属于查询类型之一,后续将会了解)。

8.更复杂的搜索

现在尝试下更复杂的搜索。同样搜索姓氏为Smith的雇员,但这次我们只需要年龄大于30的。查询需要稍作调整,使用过滤器filter,它支持高效地执行一个结构化查询。

curl -XGET 'localhost:9200/megacorp/employee/_search?pretty' -H 'Content-Type: application/json' -d'

{

"query" : {

"bool": {

"must": {

"match" : {

"last_name" : "smith" #1#

}

},

"filter": {

"range" : {

"age" : { "gt" : 30 } #2#

}

}

}

}

}

'

#1# 这部分与我们之前使用的match查询一样。
#2# 这部分是一个range过滤器,它能找到年龄大于30的文档,其中gt表示_大于(_greatthan)。

目前无需太多担心语法问题,后续会更详细地介绍。只需明确我们添加了一个过滤器用于执行一个范围查询,并复用之前的match查询。现在结果只返回了一个雇员,叫JaneSmith,32岁。

{

...

"hits": {

"total": 1,

"max_score": 0.30685282,

"hits": [

{

...

"_source": {

"first_name": "Jane",

"last_name": "Smith",

"age": 32,

"about": "I like to collect rock albums",

"interests": [ "music" ]

}

}

]

}

}

9.全文搜索

截止目前的搜索相对都很简单:单个姓名,通过年龄过滤。现在尝试下稍微高级点儿的全文搜索——一项传统数据库确实很难搞定的任务。

搜索下所有喜欢攀岩(rockclimbing)的雇员:

curl -XGET 'localhost:9200/megacorp/employee/_search?pretty' -H 'Content-Type: application/json' -d'

{

"query" : {

"match" : {

"about" : "rock climbing"

}

}

}

'

显然我们依旧使用之前的match查询在about属性上搜索"rockclimbing"。得到两个匹配的文档:

{

...

"hits": {

"total": 2,

"max_score": 0.16273327,

"hits": [

{

...

"_score": 0.16273327, #3#

"_source": {

"first_name": "John",

"last_name": "Smith",

"age": 25,

"about": "I love to go rock climbing",

"interests": [ "sports", "music" ]

}

},

{

...

"_score": 0.016878016, #4#

"_source": {

"first_name": "Jane",

"last_name": "Smith",

"age": 32,

"about": "I like to collect rock albums",

"interests": [ "music" ]

}

}

]

}

}

#3#,#4# 相关性得分

Elasticsearch默认按照相关性得分排序,即每个文档跟查询的匹配程度。第一个最高得分的结果很明显:JohnSmith的about属性清楚地写着"rockclimbing"。

但为什么JaneSmith也作为结果返回了呢?原因是她的about属性里提到了"rock"。因为只有"rock"而没有"climbing",所以她的相关性得分低于John的。

这是一个很好的案例,阐明了Elasticsearch如何在全文属性上搜索并返回相关性最强的结果。Elasticsearch中的相关性概念非常重要,也是完全区别于传统关系型数据库的一个概念,数据库中的一条记录要么匹配要么不匹配。

10.短语搜索

找出一个属性中的独立单词是没有问题的,但有时候想要精确匹配一系列单词或者短语。比如,我们想执行这样一个查询,仅匹配同时包含"rock"和"climbing",并且二者以短语"rockclimbing"的形式紧挨着的雇员记录。

为此对match查询稍作调整,使用一个叫做match_phrase的查询:

curl -XGET 'localhost:9200/megacorp/employee/_search?pretty' -H 'Content-Type: application/json' -d'

{

"query" : {

"match_phrase" : {

"about" : "rock climbing"

}

}

}

'

毫无悬念,返回结果仅有JohnSmith的文档。

{

...

"hits": {

"total": 1,

"max_score": 0.23013961,

"hits": [

{

...

"_score": 0.23013961,

"_source": {

"first_name": "John",

"last_name": "Smith",

"age": 25,

"about": "I love to go rock climbing",

"interests": [ "sports", "music" ]

}

}

]

}

}

11.高亮搜索

许多应用都倾向于在每个搜索结果中高亮部分文本片段,以便让用户知道为何该文档符合查询条件。在Elasticsearch中检索出高亮片段也很容易。

再次执行前面的查询,并增加一个新的highlight参数:

curl -XGET 'localhost:9200/megacorp/employee/_search?pretty' -H 'Content-Type: application/json' -d'

{

"query" : {

"match_phrase" : {

"about" : "rock climbing"

}

},

"highlight": {

"fields" : {

"about" : {}

}

}

}

'

当执行该查询时,返回结果与之前一样,与此同时结果中还多了一个叫做highlight的部分。这个部分包含了about属性匹配的文本片段,并以HTML标签<em></em>封装:

{

...

"hits": {

"total": 1,

"max_score": 0.23013961,

"hits": [

{

...

"_score": 0.23013961,

"_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>" #5#

]

}

}

]

}

}

#5# 原始文本中的高亮片段
关于高亮搜索片段,可以在highlightingreferencedocumentation了解更多信息。

12.分析

终于到了最后一个业务需求:支持管理者对雇员目录做分析。Elasticsearch有一个功能叫聚合(aggregations),允许我们基于数据生成一些精细的分析结果。聚合与SQL中的GROUPBY类似但更强大。

举个例子,挖掘出雇员中最受欢迎的兴趣爱好:

curl -XGET 'localhost:9200/megacorp/employee/_search?pretty' -H 'Content-Type: application/json' -d'

{

"aggs": {

"all_interests": {

"terms": { "field": "interests" }

}

}

}

'

暂时忽略掉语法,直接看看结果:

{

...

"hits": { ... },

"aggregations": {

"all_interests": {

"buckets": [

{

"key": "music",

"doc_count": 2

},

{

"key": "forestry",

"doc_count": 1

},

{

"key": "sports",

"doc_count": 1

}

]

}

}

}

可以看到,两位员工对音乐感兴趣,一位对林地感兴趣,一位对运动感兴趣。这些聚合并非预先统计,而是从匹配当前查询的文档中即时生成。如果想知道叫Smith的雇员中最受欢迎的兴趣爱好,可以直接添加适当的查询来组合查询:

curl -XGET 'localhost:9200/megacorp/employee/_search?pretty' -H 'Content-Type: application/json' -d'

{

"query": {

"match": {

"last_name": "smith"

}

},

"aggs": {

"all_interests": {

"terms": {

"field": "interests"

}

}

}

}

'

all_interests聚合已经变为只包含匹配查询的文档:

...

"all_interests": {

"buckets": [

{

"key": "music",

"doc_count": 2

},

{

"key": "sports",

"doc_count": 1

}

]

}

聚合还支持分级汇总。比如,查询特定兴趣爱好员工的平均年龄:

curl -XGET 'localhost:9200/megacorp/employee/_search?pretty' -H 'Content-Type: application/json' -d'

{

"aggs" : {

"all_interests" : {

"terms" : { "field" : "interests" },

"aggs" : {

"avg_age" : {

"avg" : { "field" : "age" }

}

}

}

}

}

'

得到的聚合结果有点儿复杂,但理解起来还是很简单的:

...

"all_interests": {

"buckets": [

{

"key": "music",

"doc_count": 2,

"avg_age": {

"value": 28.5

}

},

{

"key": "forestry",

"doc_count": 1,

"avg_age": {

"value": 35

}

},

{

"key": "sports",

"doc_count": 1,

"avg_age": {

"value": 25

}

}

]

}

输出基本是第一次聚合的加强版。依然有一个兴趣及数量的列表,只不过每个兴趣都有了一个附加的avg_age属性,代表有这个兴趣爱好的所有员工的平均年龄。

即使现在不太理解这些语法也没有关系,依然很容易了解到复杂聚合及分组通过Elasticsearch特性实现得很完美。可提取的数据类型毫无限制。

13.教程结语

欣喜的是,这是一个关于 Elasticsearch 基础描述的教程,且仅仅是浅尝辄止,更多诸如 suggestions、geolocation、percolation、fuzzy 与 partial matching 等特性均被省略,以便保持教程的简洁。但它确实突显了开始构建高级搜索功能多么容易。不需要配置——只需要添加数据并开始搜索!

很可能语法会让你在某些地方有所困惑,并且对各个方面如何微调也有一些问题。没关系!本书后续内容将针对每个问题详细解释,让你全方位地理解 Elasticsearch 的工作原理。

14.转载原文链接

https://www.elastic.co/guide/cn/elasticsearch/guide/current/_indexing_employee_documents.html

【】Elasticsearch客户端API使用Demo的更多相关文章

  1. jQuery EasyUI 1.3.4 离线API、Demo

    [原]jQuery EasyUI 1.3.4 离线API.Demo (最新)   说明 本文下载包为 jQuery EasyUI 1.3.4 离线API.Demo. API 按照分类整理做成了离线版本 ...

  2. [搜索]ElasticSearch Java Api(一) -添加数据创建索引

    转载:http://blog.csdn.net/napoay/article/details/51707023 ElasticSearch JAVA API官网文档:https://www.elast ...

  3. Elasticsearch java api 基本搜索部分详解

    文档是结合几个博客整理出来的,内容大部分为转载内容.在使用过程中,对一些疑问点进行了整理与解析. Elasticsearch java api 基本搜索部分详解 ElasticSearch 常用的查询 ...

  4. 第08章 ElasticSearch Java API

    本章内容 使用客户端对象(client object)连接到本地或远程ElasticSearch集群. 逐条或批量索引文档. 更新文档内容. 使用各种ElasticSearch支持的查询方式. 处理E ...

  5. Elasticsearch Java API深入详解

    0.题记 之前Elasticsearch的应用比较多,但大多集中在关系型.非关系型数据库与Elasticsearch之间的同步.以上内容完成了Elasticsearch所需要的基础数据量的供给.但想要 ...

  6. Elasticsearch Java API 很全的整理

    Elasticsearch 的API 分为 REST Client API(http请求形式)以及 transportClient API两种.相比来说transportClient API效率更高, ...

  7. Elasticsearch客户端源码剖析

    注:本文出自博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 注:本文源链接:https://www.cnblogs.com/chloneda/p/es-cli ...

  8. SignalR的Javascript客户端API使用方式整理

    SignalR的服务端提供了两种实现方式,分别是PersistentConnection和Hub,这两种方式的侧重点不同: PersistentConnection更接近于底层,编程接口比较简单,传输 ...

  9. Hbase1.0 客户端api

    最近在试用Hbase1.0的客户端API,发觉变化还是挺大(以前版本也不熟).到处都是deprecated. 现在应该是这样子: Configuration  conf = HBaseConfigur ...

随机推荐

  1. minSdkVersion、targetSdkVersion、targetApiLevel的区别

    在AndroidMenifest.xml中,常常会有下面的语句:  <uses-sdk android:minSdkVersion="4" android:targetSdk ...

  2. 技术预演blog

    canal整合springboot实现mysql数据实时同步到redis spring+mysql集成canal springboot整合canal监控mysql数据库 SpringBoot cana ...

  3. Can references refer to invalid location in C++?

    在C++中,引用比指针更加的安全,一方面是因为引用咋定义时必须进行初始化,另一方面是引用一旦被初始化就无法使其与其他对象相关联. 但是,在使用引用的地方仍然会有一些例外. (1)Reference t ...

  4. jQuery - 按回车键触发跳转

    键盘事件有三种: keyup:按键按下去,抬上来后,事件才生效 (推荐) keydown:按键按下去就生效 keypress:与 keydown 事件类似,当按钮被按下时,会发生该事件,与 keydo ...

  5. 【划重点】Python matplotlib绘图建立画布和坐标系

    一.建立画布 import matplotlib.pyplot as plt import numpy as np x=np.arange(8) y=np.arange(8) print(x,y) # ...

  6. Docker从入门到精通(四)——常用命令

    话不多说,本篇文章给大家介绍 docker 的常用命令,基本上会覆盖我们日常使用的命令. 1.万能帮助命令 docker 命令 --help 假设你想用某个命令,但是又不知道该命令的一些参数怎么用,这 ...

  7. Windows下mongodb的安装和配置

    1----->下载地址:https://www.mongodb.com/dr/fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-ssl ...

  8. [OpenGL ES 02]OpenGL ES渲染管线与着色器

    [OpenGL ES 02]OpenGL ES渲染管线与着色器 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循"署名-非商业用途-保持一致"创 ...

  9. Python写业务逻辑的几个编码原则

    作为一个写业务逻辑的boy,我需要专注的就是把业务逻辑写好.写业务逻辑并不复杂,就是把编程最基础的东西使用好,有变量.循环.流程控制.函数.数据库等. 但是写出的逻辑要通俗易懂.易于理解,避免炫技.晦 ...

  10. nodejs+koa+uniapp实现微信小程序登陆获取用户手机号及openId

    nodejs+koa+uniapp实现微信小程序登陆获取用户手机号及openId 前言: 我准备用nodejs+koa+uniapp实现一款餐饮点单小程序,以及nodejs+koa+vue实现后端管理 ...