如何使用CRUD操作与ElasticSearch中的数据交互

来自菜鸟教程
跳转至:导航、​搜索

状态: 已弃用

本文介绍了不再受支持的 Ubuntu 版本。 如果您当前正在运行运行 Ubuntu 12.04 的服务器,我们强烈建议您升级或迁移到受支持的 Ubuntu 版本:

原因: Ubuntu 12.04 已于 2017 年 4 月 28 日终止生命周期 (EOL) and no longer receives security patches or updates. This guide is no longer maintained.

请参阅: 本指南可能仍可用作参考,但可能不适用于其他 Ubuntu 版本。 如果可用,我们强烈建议使用为您正在使用的 Ubuntu 版本编写的指南。 您可以使用页面顶部的搜索功能来查找更新的版本。


介绍


Web 应用程序和站点的灵活搜索和索引几乎总是有用的,有时是绝对必要的。 虽然有许多复杂的解决方案可以管理数据并允许您通过 HTTP 方法检索数据并与之交互,但 ElasticSearch 因其易于配置和令人难以置信的延展性而广受欢迎。

在本文中,我们将讨论如何与 ElasticSearch 交互,以便将其用于您的特定需求。 我们将在 Ubuntu 12.04 VPS 上进行演示。

要继续学习,您必须使用本教程 安装 ElasticSearch。 我们将假设您使用项目站点提供的最新 .deb 文件安装了 ElasticSearch。

ElasticSearch 的工作原理


在深入研究 ElasticSearch 使用的具体细节之前,了解软件如何实现其解决方案非常重要。

ElasticSearch 提供了一个 RESTful API,您可以通过多种方式与之交互。 这基本上是一种描述客户端和服务器交互方式的接口。 如果说服务器是“RESTful”的,它提供了一种通过常见 HTTP 方法(GET、POST、PUT、DELETE)进行交互的方式,并且不维护状态信息。 每个请求都是独立的,资源以 JSON 等常见文本格式返回。

ElasticSearch 公开了一个 API,允许您使用 HTTP 动词与数据进行交互,并通过使用 URI 组件传递参数和信息。 这意味着它根据 URI 的格式存储数据。

在典型的 ElasticSearch 交互中,您指定要使用的操作来确定对随后的数据执行哪种操作。 要检索信息,您可以使用 GET 命令。 要创建或更新记录,您可以使用 PUTPOST 命令。

实现 CRUD 方法


CRUD 代表创建、读取、更新和删除。 这些都是有效管理持久数据存储所需的所有操作。 幸运的是,这些在 HTTP 方法中也有逻辑等价物,这使得使用标准方法进行交互变得容易。 CRUD 方法分别由 HTTP 方法 POST、GET、PUT 和 DELETE 实现。

ElasticSearch 提供了可以执行所有这些功能的 API 访问。 我们将根据如何执行这些类型的操作来讨论 ElasticSearch。

为了便于解释,我们将使用 curl 进行演示,因为您可以显式声明 HTTP 方法,并且可以轻松地从终端会话中与 ElasticSearch 进行交互。

默认情况下,通过服务器上的 9200 端口可以访问 ElasticSearch。

创建内容


ElasticSearch 中的对象创建通常称为索引。 这只是将数据添加到商店并确定类别的过程。 我们可以使用 HTTP 方法 PUT 或 POST 在 ElasticSearch 中创建对象。

以最简单的形式,您可以指定要发布数据的 index、要存储的对象的 type 以及要存储的对象的 id . 一般来说,这将如下所示:

 curl -X PUT http://server_name.com:9200/index/type/object_id -d'{  }'

在这种情况下,可以将索引视为数据库。 它是可以将某些信息与其他信息分开的顶级组织单元。 例如,您可能希望使用它来分离应用程序或站点数据。

类型是任意类型分类。 它可以是任何东西,但可用于将某些信息组合在一起。 例如,您的数据类型可能是“用户”或“文档”。

如果您使用 PUT 命令创建它,则可以指定该 id,如果您选择使用 POST 命令,则可以将其保留为自动生成。

-d 标志之后,传入要存储的对象。 这是一个格式灵活的类 JSON 对象。 类别是即时创建的,因此您可以指定任何您想要的内容。

例如,如果我们正在为我们的游乐场设备建立索引,我们可以像这样索引幻灯片:

curl -XPUT "http://localhost:9200/playground/equipment/1" -d ' { "type": "slide", "quantity": 2 }'

您应该收到一个响应,表明操作成功:

{"ok":true,"_index":"playground","_type":"equipment","_id":"1","_version":1}

如您所见,这基本上告诉您它已使用您提供的信息进行了索引。 您可能还会注意到您的信息是版本化的。 这对于以后的查询很有用。

因为 PUT 命令可用于更新信息以及创建信息,所以您可能希望指定要创建记录,而不是更新已存在的记录。 为此,只需将 /_create 添加到 URI 的末尾:

curl -XPUT "http://localhost:9200/playground/equipment/1/_create" -d '{ "type": "slide", "quantity": 2 }'

如果文档已经存在,这将导致 API 调用返回错误:

{"error":"DocumentAlreadyExistsException[[playground][2] [equipment][1]: document already exists]","status":409}

阅读内容


将数据添加到索引的全部目的是获得在稍后时间点检索该数据的能力。 我们使用 HTTP GET 方法访问 API 以读取内容。

检索数据的最基本方法是通过索引、类型和 id 指定确切的对象:

curl -XGET "http://localhost:9200/playground/equipment/1"

这将返回有关我们在创建对象时收到的文档的信息。 附加到此输出的是一个名为 _source 的键,其中包含文档本身作为其值:

{"_index":"playground","_type":"equipment","_id":"1","_version":2,"exists":true, "_source" :  { "type": "slide", "quantity": 1 }}

出于我们的目的,我们可能希望输出更人性化,因此我们可以将 ?pretty 附加到请求的末尾:

curl -XGET "http://localhost:9200/playground/equipment/1?pretty"

{
    "_index" : "playground",
    "_type" : "equipment",
    "_id" : "1",
    "_version" : 2,
    "exists" : true, "_source" : { "type": "slide", "quantity": 1 }
}

通常,我们只希望返回文档本身。 我们可以通过将 /_source 附加到查询字符串来做到这一点:

curl -XGET "http://localhost:9200/playground/equipment/1/_source?pretty"

{ "type": "slide", "quantity": 1 }

如果我们只想返回特定字段,我们可以通过在查询末尾添加 ?fields=<field1>,<field1> 来实现:

curl -XGET "http://localhost:9200/playground/equipment/1?fields=type"

这将添加一个名为 fields 的添加键,其中包含一个带有过滤 _source 的 JSON 对象:

{"_index":"playground","_type":"equipment","_id":"1","_version":2,"exists":true,"fields":{"type":"slide"}}

更新内容


我们可以使用 HTTP POST 命令轻松更新内容。 这将允许我们使用内联脚本和参数修改数据。 另一种选择是仅使用 PUT 命令并基本上使用替换(更新)对象“重新创建”对象。

我们可以使用 POST 命令更新数据对象并将 /_update 附加到 URI。 我们通过键 scriptparams 向它传递一个对象。 它可以通过使用前缀 ctx._source 来引用文档中内部定义的键。

例如,要更新 Playground 上的幻灯片数量,我们可以输入如下内容:

curl -XPOST "http://localhost:9200/playground/equipment/1/_update" -d '{ "script": "ctx._source.quantity += step", "params": { "step": 1 } }'

如果我们在完成这个操作后读取数据,我们可以看到“数量”已经增加:

curl -XGET "http://localhost:9200/playground/equipment/1/_source"

{"type":"slide","quantity":3}

我们可以通过简单地更新对象并将值分配给新键来添加任意新字段:

curl -XPOST "http://localhost:9200/playground/equipment/1/_update" -d '{ "script": "ctx._source.name_of_new_key = \"value of new field\"" }'

请注意,您可能必须转义一些引号以避免混淆引擎。

我们还可以通过调用源的 .remove 方法并传递字段名称来删除字段:

curl -XPOST "http://localhost:9200/playground/equipment/1/_update" -d '{ "script": "ctx._source.remove(\"name_of_new_key\")" }'

如果传递脚本对于您尝试执行的操作来说过于复杂,您也可以简单地引用您想要更新的字段并使用“doc”键而不是之前的“脚本”来传递新值例子:

curl -XPOST "http://localhost:9200/playground/equipment/1/_update" -d '{ "doc" : { "type": "swing" } }'

现在,我们可以再次找到该文档,并且它的“type”已被“swing”替换:

curl -XGET "http://localhost:9200/playground/equipment/1/_source"

{"type":"swing","quantity":3}

删除内容


ElasticSearch 中的删除操作相当简单。 它只是删除具有匹配 ID 的文档。 我们可以通过 HTTP 使用 DELETE 命令来达到此目的。

例如,要删除我们 Playground 索引中 ID 为 36 的文档,我们可以使用以下命令:

curl -XDELETE "http://localhost:9200/playground/equipment/36"

{"ok":true,"found":true,"_index":"playground","_type":"equipment","_id":"36","_version":2}

这表明操作成功。 如果没有与命令匹配的对象,您将获得如下所示的响应:

{"ok":true,"found":false,"_index":"playground","_type":"equipment","_id":"36","_version":1}

“found”键是用来指示是否找到并处理了匹配对象的键。

搜索内容


我们可以通过传递 /_search URI 组件来搜索我们的对象。 这可以在服务器本身之后、索引之后或类型之后使用,具体取决于您要搜索的领域。

例如,要在服务器上搜索数量为“4”的所有内容,我们可以使用如下搜索字符串:

curl -XGET "http://localhost:9200/_search?q=quantity:4'

{"took":5,"timed_out":false,"_shards":{"total":25,"successful":25,"failed":0},"hits":{"total":1,"max_score":1.0,"hits":[{"_index":"playground","_type":"equipment","_id":"1","_score":1.0, "_source" : {"type":"slide","quantity":4}}]}}

这是另一个领域,传递“pretty”参数可能会有所帮助:

curl -XGET "http://localhost:9200/_search?q=quantity:4&pretty"

{
  "took" : 14,
  "timed_out" : false,
  "_shards" : {
    "total" : 25,
    "successful" : 25,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [ {
      "_index" : "playground",
      "_type" : "equipment",
      "_id" : "1",
      "_score" : 1.0, "_source" : {"type":"slide","quantity":4}
    } ]
  }
}

如果您希望仅在游乐场设备中搜索并排除其他区域,您可以通过在 URI 中包含索引和类型来更改搜索域:

curl -XGET "http://localhost:9200/playground/equipment/_search?q=quantity:4&pretty"

如果要指定类型,但排除索引,可以将索引替换为 _all

curl -XGET "http://localhost:9200/_all/equipment/_search?q=quantity:4&pretty"

您还可以使用 ElasticSearch 域特定语言进行搜索,该语言作为看起来很像标准 JSON 的文档传入:

curl -XGET "http://localhost:9200/playground/equipment/_search" -d '{ "query": { "term": { "type": "slide" } } }'

还有更多用于搜索和过滤结果的选项,但这为如何检索已存储的数据提供了良好的基础。

结论


ElasticSearch 是一种灵活的解决方案,可以轻松动态地索引文本对象。 如果您可以以编程方式索引内容,那么这个解决方案在生成您的应用程序或用户可以使用的搜索结果的能力方面几乎是无限的。

虽然本文向您介绍了如何使用 ElasticSearch 的一些基本概念,但您通过程序或网站与搜索交互的方式完全取决于您。 您可以利用它作为工具来快速获得一些基本的搜索功能,或者您可以创建精细的对象索引,使您能够以极其细粒度的方式访问您的数据。 ElasticSearch 只是一个引擎,您可以连接它来满足您的应用程序需求。

贾斯汀·艾林伍德