【腾讯云 Elasticsearch Service】高可用,可伸缩,云端全托管。集成X-Pack高级特性,适用日志分析/企业搜索/BI分析等场景
在今天的这篇文章中,我们来主要介绍一下如何使用 REST 接口来对 Elasticsearch 进行操作。为了完成这项工作,我们必须完成如下的步骤:
安装 Elasticsearch。请参阅文章 “ 如何在 Linux,MacOS 及 Windows 上进行安装 Elasticsearch ”。把 Elasticsearch 运行起来。
安装 Kiban。请参阅文章 “ 如何在 Linux,MacOS 及 Windows 上安装Elastic栈中的 Kibana ”。把Kibana运行起来。
熟悉有关于 Elastic 栈的一些最基本的概念。请参阅文章 “ Elasticsarch 中的一些重要概念 : cluster, node, shards 及 replica ”。这些概念对我们如下的练习有非常多的帮助。
有了上面最基本的一些安装及概念,我们就很容进行下面的讲解了。在如下所展示的所有的scripts可在地址 https://github.com/liu-xiao-guo/es-scripts-7.3 找到。
什么是 JSON ?
JSON ( JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999 的一个子集。在 Elasticsearch 中,所以的数据都是以 JSON 的格式来进行表述的。这个和其它的有些数据库,比如 Solr,它支持更多格式的数据,比如 xml, csv 等。
我们来看一下一个简单的 JSON 格式的数据表达:
代码语言:javascript复制{
"name" : "Elastic",
"location" : {
"state" : "CA",
"zipcode" : 94123
}
}
这个看起来非常简单直接。如果大家熟悉 Javascript 的话,你会发现它和 Javascript 里的 Object 非常地相似。
什么是 REST 接口?
相信很多做过微服务架构的开发者来说,你们可能对 REST 接口再熟悉不过了。REST 即表述性状态传递(英文:Representational State Transfer,简称 REST )是 Roy Fielding 博士在 2000 年他的博士论文中提出来的一种软件架构风格。REST 是一种规范。即参数通过封装后进行传递,响应也是返回的一个封装对象。一个 REST 的接口就像如下的接口:
http://example.com/customers/1234
我们可以通过:
代码语言:javascript复制HTTP GET
HTTP POST
HTTP PUT
HTTP DELETE
HTTP PATCH
来对数据进行增加(Create),查询(Read),更新(Update)及删除(Delete)。也就是我们通常说是的 CRUD。
Elasticsearch 里的接口都是通过 REST 接口来实现的。我们在一下的章节里来重点介绍一下是如果使用 REST 接口来实现对数据的操作及查询的。
检查 Elasticsearch 及 Kibana 是否运行正常
我们首先在我们的浏览器中输入如下地址:http://localhost:9200。查看一下我们的输出:
如果你能看到如上的信息输出,表明我们的 Elasticsearch 是处于一个正常运行的状态。
同时,我们在浏览器中输入地址:http://localhost:5601。在浏览器中,我们查看输出的信息:
上面显示了 Kibana 的界面。由于 Kibana 的功能有很多。我们在今天的培训中就不一一介绍了。我们着重使用在上面显示的 “ Dev Tools ” 菜单里的功能。当我们点击它的时候,我们可以看到如下的界面。
当我们执行命令时,我们必须点击左边窗口里的那个绿色的播放按钮。命令所执行显示的结果将在右边展示。在接下的所有练习中,我们都将使用这样的操作来进行。
查看 Elasticsearch 信息
就像我们之前在浏览器其中打入地址 http://localhost:9200 看到的效果一样,我们直接打入
代码语言:javascript复制GET /
我们就可以看到如下的信息:
在这里我们可以看到 Elasticsearch 的版本信息及我们正在使用的 Elasticsearch 的 Cluster 名称等信息。
我们发现当我们打入一个命令时,Kibana 会帮我们自动地显示可以输入的选择项,它具有 autocomplete 的功能。这个对我们打入我们所需要的命令非常用用。我们有时候不需要记那么多。
创建一个索引及文档
我们接下来创建一个叫做 twitter 的索引(index),并插入一个文档(document)。我们知道在 RDMS 中,我们通常需要有专用的语句来生产相应的数据库,表格,让后才可以让我们输入相应的记录,但是针对 Elasticsearch 来说,这个是不必须的。我们在左边的窗口中输入:
代码语言:javascript复制PUT twitter/_doc/1
{
"user": "GB",
"uid": 1,
"city": "Beijing",
"province": "Beijing",
"country": "China"
}
我们可以看到在 Kibana 右边的窗口中有下面的输出:
在上面,我们可以看出来我们已经成功地创建了一个叫做 twitter 的 index 。通过这样的方法,我们可以自动创建一个 index 。如果大家不喜欢自动创建一个 index ,我们可以修改如下的一个设置:
代码语言:javascript复制PUT _cluster/settings
{
"persistent": {
"action.auto_create_index": "false"
}
}
详细设置请参阅链接。如果你你想禁止自动创建索引,您必须配置 action.auto_create_index 以允许这些创建以下索引的组件:
代码语言:javascript复制PUT _cluster/settings
{
"persistent": {
"action.auto_create_index": ".monitoring*,.watches,.triggered_watches,.watcher-history*,.ml*"
}
}
如果使用 Logstash 或 Beats ,则应在上面的列表中添加其他索引名称。我们也可以在 elasticsearch.yml 里进行配置。
通常对一个通过上面方法写入到 Elasticsearch 的文档,在默认的情况下并不马上可以进行搜索。这是因为在 Elasticsearch 的设计中,有一个叫做 refresh 的操作。它可以使更改可见以进行搜索的操作。通常会有一个 refresh timer 来定时完成这个操作。这个周期为 1 秒。这也是我们通常所说的 Elasticsearch 可以实现秒级的搜索。当然这个 timer 的周期也可以在索引的设置中进行配置。如果我们想让我们的结果马上可以对搜索可见,我们可以用如下的方法:
代码语言:javascript复制PUT twitter/_doc/1?refresh=true
{
"user": "GB",
"uid": 1,
"city": "Beijing",
"province": "Beijing",
"country": "China"
}
上面的方式可以强制使 Elasticsearch 进行 refresh 的操作,当然这个是有代价的。频繁的进行这种操作,可以使我们的 Elasticsearch 变得非常慢。另外一种方式是通过设置 refresh=wait_for 。这样相当于一个同步的操作,它等待下一个 refresh 周期发生完后,才返回。这样可以确保我们在调用上面的接口后,马上可以搜索到我们刚才录入的文档:
代码语言:javascript复制PUT twitter/_doc/1?refresh=wait_fo
{
"user": "GB",
"uid": 1,
"city": "Beijing",
"province": "Beijing",
"country": "China"
}
如果你想对 refresh 有更多的了解,请参阅我的文章 “ Elasticsearch 中的 refresh 和 flush 操作指南 ” 。
它也创建了一个被叫做 _doc 的 type 。自从 Elasticsearch 6.0 以后,一个 index 只能有一个 type 。如果我们创建另外一个 type 的话,系统会告诉我们是错误的。这里我们也会发现有一个版本信息,它显示的是 4 。如果这个 _id 为 1 的 document 之前没有被创建过的话,它会显示为 1 。之后如果我们更改这个 document ,它的版本会每次自动增加 1 。比如,我们输入:
代码语言:javascript复制POST twitter/_doc/1
{
"user": "GB",
"uid": 1,
"city": "Shenzhen",
"province": "Guangdong",
"country": "China"
}
我们在左边修改了我们的数据,在右边,我们可以看到版本信息增加到 6 。这是因为我们把左边的命令执行了两次。同时,我们也可以看出来,我们也把左边的数据进行了修改,我们也看到了成功被修改的返回信息。在上面我们可以看出来,我们每次执行那个POST 或者 PUT 接口时,如果文档已经存在,那么相应的版本就会自动加 1 ,之前的版本抛弃。如果这个不是我们想要的,那么我们可以使用 _create 端点接口来实现:
代码语言:javascript复制PUT twitter/_create/1
{
"user": "GB",
"uid": 1,
"city": "Shenzhen",
"province": "Guangdong",
"country": "China"
}
如果文档已经存在的话,我们会收到一个错误的信息:
上面的命令和如下的命令也是一样的效果:
代码语言:javascript复制PUT twitter/_doc/1?op_type=create
{
"user": "双榆树-张三",
"message": "今儿天气不错啊,出去转转去",
"uid": 2,
"age": 20,
"city": "北京",
"province": "北京",
"country": "中国",
"address": "中国北京市海淀区",
"location": {
"lat": "39.970718",
"lon": "116.325747"
}
}
在上面,我们在请求时带上 op_type 。它可以有两种值:index 及 create 。
我们必须指出的是,如果你是在 Linux 或 MacOS 机器上,我们也可以使用如下的命令行指令来达到同样的效果:
代码语言:javascript复制curl -XPUT 'http://localhost:9200/twitter/_doc/1?pretty' -H 'Content-Type: application/json' -d '
{
"user": "GB",
"uid": 1,
"city": "Shenzhen",
"province": "Guangdong",
"country": "China"
}'
本方法适用于一下所有的命令,如法炮制!
我们可以通过如下的命令来查看被修改的文档:
代码语言:javascript复制GET twitter/_doc/1
我们可以看到在右边显示了我们被修改的文档的结果。
如果我们只想得到这个文档的 _source 部分,我们可以使用如下的命令格式:
代码语言:javascript复制GET twitter/_doc/1/_source
自动 ID 生成
在上面,我特意为我们的文档分配了一个 ID 。其实在实际的应用中,这个并不必要。相反,当我们分配一个 ID 时,在数据导入的时候会检查这个 ID 的文档是否存在,如果是已经存在,那么就更新器版本。如果不存在,就创建一个新的文档。如果我们不指定文档的 ID ,转而让 Elasticsearch 自动帮我们生成一个 ID ,这样的速度更快。在这种情况下,我们必须使用 POST ,而不是 PUT 。比如:
代码语言:javascript复制POST my_index/_doc
{
"content": "this is really cool"
}
返回的结果:
代码语言:javascript复制{
"_index" : "my_index",
"_type" : "_doc",
"_id" : "egiY4nEBQTokU_uEEGZz",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
从上面我们可以看出来,系统会为我们自动分配一个 ID 啊。
如果我们只对 source 的内容感兴趣的话,我们可以使用:
代码语言:javascript复制GET twitter/_doc/1/_source
这样我们可以直接得到 source 的信息:
代码语言:javascript复制{
"user" : "双榆树-张三",
"message" : "今儿天气不错啊,出去转转去",
"uid" : 2,
"age" : 20,
"city" : "北京",
"province" : "北京",
"country" : "中国",
"address" : "中国北京市海淀区",
"location" : {
"lat" : "39.970718",
"lon" : "116.325747"
}
}
我们也可以只获取 source 的部分字段:
代码语言:javascript复制GET twitter/_doc/1?_source=city,age,province
如果你想一次请求查找多个文档,我们可以使用 _mget 接口:
代码语言:javascript复制GET _mget
{
"docs": [
{
"_index": "twitter",
"_id": 1
},
{
"_index": "twitter",
"_id": 2
}
]
}
我们也可以只获得部分字段:
代码语言:javascript复制GET _mget
{
"docs": [
{
"_index": "twitter",
"_id": 1,
"_source":["age", "city"]
},
{
"_index": "twitter",
"_id": 2,
"_source":["province", "address"]
}
]
}
在这里,我们同时请求 id 为 1 和 2 的两个文档。
我们也可以简单地写为:
代码语言:javascript复制GET twitter/_doc/_mget
{
"ids": ["1", "2"]
}
它和上面的做一个是一样的。使用一个命令同时获取 id 为 1 及 2 的文档。
在上面当我们写入数据时,我们有意识地把文档的 id 在命令中写了出来。如果我们不写这个 id 的话,ES 会帮我们自动生产一个id:
代码语言:javascript复制POST twitter/_doc/
我可以看到右边的一个 id 像是一个随机的数值,同时我们可以看到它的一个版本信息为 1 。
我们也可以看出来系统所给出来的字段都是以下划线的形式给出来的,比如:_id, _shards, _index, _typed 等
修改一个文档
我们接下来看一下如何修改一个文档。在上面我们看到了可以使用 POST 的命令来修改改一个文档。通常我们使用 POST 来创建一个新的文档。在使用 POST 的时候,我们甚至不用去指定特定的 id ,系统会帮我们自动生成。但是我们修改一个文档时,我们通常会使用 PUT 来进行操作,并且,我们需要指定一个特定的 id 来进行修改:
代码语言:javascript复制PUT twitter/_doc/1
{
"user": "GB",
"uid": 1,
"city": "北京",
"province": "北京",
"country": "中国",
"location":{
"lat":"29.084661",
"lon":"111.335210"
}
}
如上面所示,我们使用 PUT 命令来对我们的 id 为 1 的文档进行修改。我们也可以使用我们上面学过的 GET 来进行查询:
代码语言:javascript复制GET twitter/_doc/1
代码语言:javascript复制
{
"_index" : "twitter",
"_type" : "_doc",
"_id" : "1",
"_version" : 8,
"_seq_no" : 13,
"_primary_term" : 1,
"found" : true,
"_source" : {
"user" : "GB",
"uid" : 1,
"city" : "北京",
"province" : "北京",
"country" : "中国",
"location" : {
"lat" : "29.084661",
"lon" : "111.335210"
}
}
}
显然,我们的这个文档已经被成功修改了。
我们使用 PUT 的这个方法,每次修改一个文档时,我们需要把文档的每一项都要写出来。这对于有些情况来说,并不方便,我们可以使用如下的方法来进行修改:
代码语言:javascript复制POST twitter/_update/1
{
"doc": {
"city": "成都",
"province": "四川"
}
}
我们可以使用如上的命令来修改我们的部分数据。同样我们可以使用 GET 来查询我们的修改是否成功:
从上面的显示中,我们可以看出来,我们的修改是成功的,虽然在我们修改时,我们只提供了部分的数据。
在关系数据库中,我们通常是对数据库进行搜索,让后才进行修改。在这种情况下,我们事先通常并不知道文档的 id 。我们需要通过查询的方式来进行查询,让后进行修改。ES 也提供了相应的 REST 接口。
代码语言:javascript复制POST twitter/_update_by_query
{
"query": {
"match": {
"user": "GB"
}
},
"script": {
"source": "ctx._source.city = params.city;ctx._source.province = params.province;ctx._source.country = params.country",
"lang": "painless",
"params": {
"city": "上海",
"province": "上海",
"country": "中国"
}
}
}
对于那些名字是中文字段的文档来说,在 painless 语言中,直接打入中文字段名字,并不能被认可。我们可以使用如下的方式来操作:
代码语言:javascript复制POST edd/_update_by_query
{
"query": {
"match": {
"姓名": "张彬"
}
},
"script": {
"source": "ctx._source["签到状态"] = params["签到状态"]",
"lang": "painless",
"params" : {
"签到状态":"已签到"
}
}
}
在上面我们使用一个中括号并 escape 引号的方式来操作。
我们可以通过上面的方法搜寻 user 为 GB 的用户,并且把它的数据项修改为:
代码语言:javascript复制 "city" : "上海",
"province": "上海",
"country": "中国"
我们也可以通过 update 接口,使用 script 的方法来进行修改。这个方法也是需要知道文档的 id :
代码语言:javascript复制POST twitter/_update/1
{
"script" : {
"source": "ctx._source.city=params.city",
"lang": "painless",
"params": {
"city": "长沙"
}
}
}
和前面的方法一下,我们可以使用 GET 来查询,我们的结果是否已经改变:
代码语言:javascript复制{
"_index" : "twitter",
"_type" : "_doc",
"_id" : "1",
"_version" : 18,
"_seq_no" : 39,
"_primary_term" : 1,
"found" : true,
"_source" : {
"uid" : 1,
"country" : "中国",
"province" : "上海",
"city" : "长沙",
"location" : {
"lon" : "111.335210",
"lat" : "29.084661"
},
"user" : "GB"
}
}
UPSERT 一个文档
仅在文档事先存在的情况下,我们在前面的代码中看到的部分更新才有效。 如果具有给定 ID 的文档不存在,Elasticsearch 将返回一个错误,指出该文档丢失。 让我们了解如何使用更新 API 进行 upsert 操作。 术语 “ upsert ” 宽松地表示更新或插入,即更新文档(如果存在),否则,插入新文档。
doc_as_upsert 参数检查具有给定 ID 的文档是否已经存在,并将提供的 doc 与现有文档合并。 如果不存在具有给定 ID 的文档,则会插入具有给定文档内容的新文档。
下面的示例使用 doc_as_upsert 合并到 ID 为 3 的文档中,或者如果不存在则插入一个新文档:
代码语言:javascript复制POST /catalog/_update/3
{
"doc": {
"author": "Albert Paro",
"title": "Elasticsearch 5.0 Cookbook",
"description": "Elasticsearch 5.0 Cookbook Third Edition",
"price": "54.99"
},
"doc_as_upsert": true
}
检查一个文档是否存在
有时候我们想知道一个文档是否存在,我们可以使用如下的方法:
代码语言:javascript复制HEAD twitter/_doc/1
这个 HEAD 接口可以很方便地告诉我们在 twitter 的索引里是否有一 id 为 1 的文档:
上面的返回值表面 id 为 1 的文档时存在的。
删除一个文档
如果我们想删除一个文档的话,我们可以使用如下的命令:
代码语言:javascript复制DELETE twitter/_doc/1
在上面的命令中,我们删除了 id 为 1 的文档。
在关系数据库中,我们通常是对数据库进行搜索,让后才进行删除。在这种情况下,我们事先通常并不知道文档的 id 。我们需要通过查询的方式来进行查询,让后进行删除。ES 也提供了相应的 REST 接口。
代码语言:javascript复制POST twitter/_delete_by_query
{
"query": {
"match": {
"city": "上海"
}
}
}
这样我们就把所有的 city是上海的文档都删除了。
删除一个 index
删除一个 index 是非常直接的。我们可以直接使用如下的命令来进行删除:
代码语言:javascript复制DELETE twitte
当我们执行完这一条语句后,所有的在 twitter 中的所有的文档都将被删除。
批处理命令
上面我们已经了解了如何使用REST接口来创建一个 index ,并为之创建,读取,修改,删除文档(CRUD)。因为每一次操作都是一个 REST 请求,对于大量的数据进行操作的话,这个显得比较慢。ES 创建一个批量处理的命令给我们使用。这样我们在一次的 REST 请求中,我们就可以完成很多的操作。这无疑是一个非常大的好处。下面,我们来介绍一下这个 bulk 命令。
我们使用如下的命令来进行 bulk操作:
代码语言:javascript复制POST _bulk
{ "index" : { "_index" : "twitter", "_id": 1} }
{"user":"双榆树-张三","message":"今儿天气不错啊,出去转转去","uid":2,"age":20,"city":"北京","province":"北京","country":"中国","address":"中国北京市海淀区","location":{"lat":"39.970718","lon":"116.325747"}}
{ "index" : { "_index" : "twitter", "_id": 2 }}
{"user":"东城区-老刘","message":"出发,下一站云南!","uid":3,"age":30,"city":"北京","province":"北京","country":"中国","address":"中国北京市东城区台基厂三条3号","location":{"lat":"39.904313","lon":"116.412754"}}
{ "index" : { "_index" : "twitter", "_id": 3} }
{"user":"东城区-李四","message":"happy birthday!","uid":4,"age":30,"city":"北京","province":"北京","country":"中国","address":"中国北京市东城区","location":{"lat":"39.893801","lon":"116.408986"}}
{ "index" : { "_index" : "twitter", "_id": 4} }
{"user":"朝阳区-老贾","message":"123,gogogo","uid":5,"age":35,"city":"北京","province":"北京","country":"中国","address":"中国北京市朝阳区建国门","location":{"lat":"39.718256","lon":"116.367910"}}
{ "index" : { "_index" : "twitter", "_id": 5} }
{"user":"朝阳区-老王","message":"Happy BirthDay My Friend!","uid":6,"age":50,"city":"北京","province":"北京","country":"中国","address":"中国北京市朝阳区国贸","location":{"lat":"39.918256","lon":"116.467910"}}
{ "index" : { "_index" : "twitter", "_id": 6} }
{"user":"虹桥-老吴","message":"好友来了都今天我生日,好友来了,什么 birthday happy 就成!","uid":7,"age":90,"city":"上海","province":"上海","country":"中国","address":"中国上海市闵行区","location":{"lat":"31.175927","lon":"121.383328"}}
在上面的命令中,我们使用了 bulk 指令来完成我们的操作。在输入命令时,我们需要特别的注意:千万不要添加除了换行以外的空格,否则会导致错误。在上面我们使用的 index 用来创建一个文档。为了说明问题的方便,我们在每一个文档里,特别指定了每个文档的 id 。当执行完我们的批处理 bulk 命令后,我们可以看到:
显然,我们的创建时成功的。因为我运行了两遍的原因,所以你看到的是 version 为 2 的返回结果。bulk 指令是高效的,因为一个请求就可以处理很多个操作。在实际的使用中,我们必须注意的是:一个好的起点是批量处理 1000 到 5,000 个文档,总有效负载在 5MB 到 15MB 之间。如果我们的 payload 过大,那么可能会造成请求的失败。如果你想更进一步探讨的话,你可以使用文件accounts.json 来做实验。
如果你想查询到所有的输入的文档,我们可以使用如下的命令来进行查询:
代码语言:javascript复制POST twitter/_search
这是一个查询的命令,在以后的章节中,我们将再详细介绍。通过上面的指令,我们可以看到所有的已经输入的文档。
上面的结果显示,我们已经有 6 条生产的文档记录已经生产了。
我们可以通过使用 _count 命令来查询有多少天数据:
代码语言:javascript复制GET twitter/_count
上面我们已经使用了 index 来创建 6 条文档记录。我也可以尝试其它的命令,比如 create :
代码语言:javascript复制POST _bulk
{ "create" : { "_index" : "twitter", "_id": 1} }
{"user":"双榆树-张三","message":"今儿天气不错啊,出去转转去","uid":2,"age":20,"city":"北京","province":"北京","country":"中国","address":"中国北京市海淀区","location":{"lat":"39.970718","lon":"116.325747"}}
{ "index" : { "_index" : "twitter", "_id": 2 }}
{"user":"东城区-老刘","message":"出发,下一站云南!","uid":3,"age":30,"city":"北京","province":"北京","country":"中国","address":"中国北京市东城区台基厂三条3号","location":{"lat":"39.904313","lon":"116.412754"}}
{ "index" : { "_index" : "twitter", "_id": 3} }
{"user":"东城区-李四","message":"happy birthday!","uid":4,"age":30,"city":"北京","province":"北京","country":"中国","address":"中国北京市东城区","location":{"lat":"39.893801","lon":"116.408986"}}
{ "index" : { "_index" : "twitter", "_id": 4} }
{"user":"朝阳区-老贾","message":"123,gogogo","uid":5,"age":35,"city":"北京","province":"北京","country":"中国","address":"中国北京市朝阳区建国门","location":{"lat":"39.718256","lon":"116.367910"}}
{ "index" : { "_index" : "twitter", "_id": 5} }
{"user":"朝阳区-老王","message":"Happy BirthDay My Friend!","uid":6,"age":50,"city":"北京","province":"北京","country":"中国","address":"中国北京市朝阳区国贸","location":{"lat":"39.918256","lon":"116.467910"}}
{ "index" : { "_index" : "twitter", "_id": 6} }
{"user":"虹桥-老吴","message":"好友来了都今天我生日,好友来了,什么 birthday happy 就成!","uid":7,"age":90,"city":"上海","province":"上海","country":"中国","address":"中国上海市闵行区","location":{"lat":"31.175927","lon":"121.383328"}}
在上面,我们的第一个记录里,我们使用了 create 来创建第一个 id 为 1 的记录。因为之前,我们已经创建过了,所以我们可以看到如下的信息:
从上面的信息,我们可以看出来 index 和 create 的区别。index 总是可以成功,它可以覆盖之前的已经创建的文档,但是 create 则不行,如果已经有以那个 id 为名义的文档,就不会成功。
我们可以使用 delete 来删除一个已经创建好的文档:
代码语言:javascript复制POST _bulk
{ "delete" : { "_index" : "twitter", "_id": 1 }}
我们可以看到 id 为 1 的文档已经被删除了。我可以通过如下的命令来查看一下:
显然,我们已经把 id 为 1 的文档已经成功删除了。
我们也可以是使用 update 来进行更新一个文档。
代码语言:javascript复制POST _bulk
{ "update" : { "_index" : "twitter", "_id": 2 }}
{"doc": { "city": "长沙"}}
运行的结果如下:
同样,我们可以使用如下的方法来查看我们修改的结果:
我们可以清楚地看到我们已经成功地把城市 city 修改为“长沙”。
注意:通过 bulk API 为数据编制索引时,您不应在集群上进行任何查询/搜索。 这样做可能会导致严重的性能问题。
如果您对脚本编程比较熟悉的话,你可能更希望通过脚本的方法来把大量的数据通过脚本的方式来导入:
代码语言:javascript复制$ curl -s -H "Content-Type: application/x-ndjson" -XPOST localhost:9200/_bulk --data-binary @request_example.json
这里的 request_example.json 就是我们的 json 数据文件。我们可以做如下的实验:
下载测试数据:
代码语言:javascript复制wget https://github.com/liu-xiao-guo/elasticsearch-bulk-api-data/blob/master/es.json
然后在命令行中打入如下的命令:
代码语言:javascript复制curl -u elastic:123456 -s -H "Content-Type: application/x-ndjson" -XPOST localhost:9200/_bulk --data-binary @es.json
这里的 “elastic:123456” 是我们的 Elasticsearch 的用户名及密码,如果我们没有为我们的 Elasticsearch 设置安全,那么可以把 “-u elastic:123456” 整个去掉。等我们运行完上面的指令后,我们可以在 Kibana 中查看到我们的叫做 “bank_account” 的索引。
Open/close Index
Elasticsearch 支持索引的在线/离线模式。 使用脱机模式时,在群集上几乎没有任何开销地维护数据。 关闭索引后,将阻止读/写操作。 当您希望索引重新联机时,只需打开它即可。 但是,关闭索引会占用大量磁盘空间。 您可以通过将cluster.indices.close.enable 的默认值从 true 更改为 false 来禁用关闭索引功能,以避免发生意外。
一旦 twitter 索引被关闭了,那么我们再访问时会出现如下的错误:
我们可以通过 _open 接口来重新打开这个 index :
Freeze/unfreeze index
冻结索引(freeze index)在群集上几乎没有开销(除了将其元数据保留在内存中),并且是只读的。 只读索引被阻止进行写操作,例如 docs-index 或 force merge 。 请参阅冻结索引和取消冻结索引。
冻结索引受到限制,以限制每个节点的内存消耗。 每个节点的并发加载的冻结索引数受 search_throttled 线程池中的线程数限制,默认情况下为1。 默认情况下,即使已明确命名冻结索引,也不会针对冻结索引执行搜索请求。 这是为了防止由于误将冻结的索引作为目标而导致的意外减速。 如果要包含冻结索引做搜索,必须使用查询参数 ignore_throttled = false 来执行搜索请求。
我们可以使用如下的命令来对 twitter 索引来冻结:
代码语言:javascript复制POST twitter/_freeze
在执行上面的命令后,我们再对 twitter 进行搜索:
我们搜索不到任何的结果。按照我们上面所说的,我们必须加上 ignore_throttled=false 参数来进行搜索:
显然对于一个 frozen 的索引来说,我们是可以对它进行搜索的。我们可以通过如下的命令来对这个已经冻结的索引来进行解冻:
代码语言:javascript复制POST twitter/_unfreeze
一旦我们的索引被成功解冻,那么它就可以像我们正常的索引来进行操作了,而不用添加参数 ignore_throttled=false 来进行访问。
总结
在这篇文章中,我们详细地介绍了如果在 Elasticserch 中创建我们的索引,文档,并对他们进行更改,删除,查询的操作。希望对大家有所帮助。在接下来的文章里,我们将重点介绍如何对 Elasticsearch 里的 index 进行搜索和分析。
如果你想了解更多关于 Elastic Stack 相关的知识,请参阅我们的官方网站:https://www.elastic.co/guide/index.html
下一步
接下来,我们可以学习教程:
- 开始使用Elasticsearch (2)
- 开始使用Elasticsearch (3)
————————————————
版权声明:本文为CSDN博主「Elastic 中国社区官方博客」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://elasticstack.blog.csdn.net/article/details/99481016
最新活动
包含文章发布时段最新活动,前往ES产品介绍页,可查找ES当前活动统一入口
Elasticsearch Service自建迁移特惠政策>>
Elasticsearch Service 新用户特惠狂欢,最低4折首购优惠 >>
Elasticsearch Service 企业首购特惠,助力企业复工复产>>