ElasticSearch学习(二)--ElasticSearch在curl中的基本操作

开始第一步

让我们建立一个员工目录

我们首先要做的是存储员工数据,每个文档(document)(行)代表一个员工。所以为了创建员工目录,我们将进行如下操作:

  • 为每个员工的文档(document)建立索引,每个文档包含了相应员工的所有信息。
  • 每个文档的类型为employee
  • employee类型归属于索引megacorp
  • megacorp索引存储在ElasticSearch集群中。

实际上这些都是很容易的,我们通过一个命令执行完成操作。

curl -XPUT "localhost:9200/megacorp/employee/1?pretty" -d '{
   "first_name":"John",
   "last_name":"Smith",
   "age":25,
   "about":"I love to go rock climbing",
   "interests":["sports","music"]
}'

注:在Windows下命令如下:

curl -H "application/json" -XPUT "localhost:9200/megacorp/employee/1?pretty" -d "{
  \ "first_name\":\"John\",
   \"last_name\":\"Smith\",
  \ "age\":25,
   \"about\":\"I love to go rock climbing\",
  \ "interests\":[\"sports\",\"music\"]
}"

自增ID

curl -XPOST "localhost:9200/website/blog/" -d '{
    "title" : "My first blog entry",
    "text" : "Just trying this out...",
    "date" : "2014/01/01"
}'

响应如下:

{
  "_index" : "website",
  "_type" : "blog",
  "_id" : "X7cGE2UB2XL2Aw5Pme58",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

检索文档

curl -XGET "localhost:9200/website/blog/123?pretty"

响应如下:

{
  "_index" : "website",
  "_type" : "blog",
  "_id" : "123",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "title" : "My first blog entry",
    "text" : "Just trying this out...",
    "date" : "2014/01/01"
  }
}

检索文档的一部分

通常,GET请求将返回文档的全部,存储在_source参数中。但是你可能感兴趣的字段只是title。请求个别字段可以使用_source参数。多个字段可以使用逗号分隔:

curl -i -XGET "localhost:9200/website/blog/123?_source=title,text&pretty"

_source字段现在只包含我们请求的字段,而且过滤了date字段:

HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 197

{
  "_index" : "website",
  "_type" : "blog",
  "_id" : "123",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "text" : "Just trying this out...",
    "title" : "My first blog entry"
  }
}

或者你只想得到_source字段而不要其他的元数据,你可以这样请求:

curl -i -XGET "localhost:9200/website/blog/123/_source?pretty"

它仅仅返回:

HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 101

{
  "title" : "My first blog entry",
  "text" : "Just trying this out...",
  "date" : "2014/01/01"
}

检查文档是否存在

如果你想做的只是检查文档是否存在——-你对内容完全不感兴趣,那就使用HEAD方法代替GET,HEAD请求不会返回响应体。只有HTTP头:

curl -i -XHEAD "localhost:9200/website/blog/123?pretty"

ElasticSearch将会返回 200OK 状态(如果你的文档存在):

HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 224

如果不存在返回 404 Not Found:

HTTP/1.1 404 Not Found
content-type: application/json; charset=UTF-8
content-length: 83

当然,这只代表你在查询的那一刻文档不存在,但并不带表几毫秒后依旧不存在。另一进程在这期间可能创建新文档。

更新整个文档

文档在ElasticSearch中是不可变的——–我们不能修改他们。

curl -i -XPUT "localhost:9200/website/blog/123" -d '{
   "title":"My first blog entry",
   "text":"I am starting to get the hang of this...",
   "date":"2014/01/02"
}'

在响应中,我们可以看到ElasticSearch把_version增加了。

HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 223

{
  "_index" : "website",
  "_type" : "blog",
  "_id" : "123",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}

在内部,ElasticSearch已经标记旧文档为删除并添加了一个完整的新文档。旧版本文档不会立即消失,但你也不能去访问它。ElasticSearch会在你继续索引更多数据时清理被删除的文档。

创建一个新文档

当索引一个文档,我们如何确定是完全创建了一个新的还是覆盖了一个已经存在的呢?
请记住_index,_type,_id三者唯一确定一个文档。所以要想保证文档是新加入的,最简单的方式是使用POST方法让ElasticSearch自动生成唯一_id

curl -i -XPOST "localhost:9200/website/blog/" -d '{
....
}'

然而,如果想使用自定义的_id,我们必须告诉ElasticSearch应该在_index,_type,_id三者不同时才接受请求。为了做到这点有两种方法,他们其实做的是同一件事。你可以选择适合自己的方式:
第一种方法使用 op_type 查询参数:

curl -XPUT "localhost:9200/website/blog/123?op_type=create" -d '{
    ........
}'

第二种方法是在URL后加 /_create 作为端点

curl -XPUT "localhost:9200/website/blog/123/_create" -d '{
    ........
}'

如果请求成功的创建了一个新文档,ElasticSearch将返回正常的元数据且响应状态吗是201 Created。

另一方面,如果包含相同的 _index,_type,_id的文档已经存在,ElasticSearch将返回409 Conflict响应状态码,错误信息如下

{
  "error" : {
    "root_cause" : [
      {
        "type" : "version_conflict_engine_exception",
        "reason" : "[blog][123]: version conflict, document already exists (current version [2])",
        "index_uuid" : "U3-JJt16SKmUn6rBuBDOfw",
        "shard" : "0",
        "index" : "website"
      }
    ],
    "type" : "version_conflict_engine_exception",
    "reason" : "[blog][123]: version conflict, document already exists (current version [2])",
    "index_uuid" : "U3-JJt16SKmUn6rBuBDOfw",
    "shard" : "0",
    "index" : "website"
  },
  "status" : 409
}

删除文档

删除文档的语法模式与之前基本一致,只不过要使用 DELETE 方法:

curl -XDELETE "localhost:9200/website/blog/123"

如果文档被找到,ElasticSearch将返回 200OK 状态码, _version 数字增加;如果文档未找到,我们将得到一个404 Not Found 状态码,尽管文档不存在,_version 依旧增加了,这是内部记录的一部分,它确保在多节点间不同操作可以有正确的顺序。

文档局部更新

最简单的 update 请求表单接受一个局部文档参数doc,它会合并到现有文档中------对象合并在一起,存在的标量字段被覆盖,新字段被添加。

curl -XPOST "localhost:9200/website/blog/1/_update" -d '{
     "doc":{
          "tags":["testing"],
          "views":0
      }
}'

如果请求成功,我们将看到类似请求的响应结果:

{
  "_index":"website",
  "_id":"1",
  "_type":"blog",
   "_version":3
}

检索文档显示被更新的_source字段:

{
   "_index":"website",
   "_id":"1",
   "_type":"blog",
   "_version":3
   "found":true,
   "_source":{
         "title":"My first blog entry",
         "text":"Starting to get the hang of this...",
          "tags":["testing"],
          "views":0
   }
}

我们新添加的字段已经被添加到_source字段中。

检索多个文档

ElasticSearch检索多个文档依旧非常快。合并多个请求可以避免每个请求单独的网络开销。如果你需要从ElasticSearch中检索多个文档,相对于一个一个的检索,更快的方式是在一个请求中使用multi-get或者mget API。

mget API参数是一个 docs 数组,数组的每个节点定义一个文档的 _index,_type,_id 元数据。如果你只想检索一个或几个确定的字段,也可以定义一个 _source 参数:

curl -i -XGET "localhost:9200/_mget" -d '{
    "docs":[
     {
         "_index":"megacorp",
         "_type":"employee",
         "_id":2
     },{
          "_index":"megacorp",
         "_type":"employee",
         "_id":3,
         "_source":"age"
     }
   ]

}'

响应体如下:

HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 545

{
  "docs" : [
    {
      "_index" : "megacorp",
      "_type" : "employee",
      "_id" : "2",
      "_version" : 2,
      "found" : true,
      "_source" : {
        "first_name" : "Douglas",
        "last_name" : "Fir",
        "age" : 35,
        "about" : "I like to build cabinets",
        "interests" : [
          "forestry"
        ]
      }
    },
    {
      "_index" : "megacorp",
      "_type" : "employee",
      "_id" : "3",
      "_version" : 1,
      "found" : true,
      "_source" : {
        "age" : 32
      }
    }
  ]
}

如果你想检索的文档在同一个 _index 中(甚至在同一个 _type 中),你就可以在URL中定义一个默认的 _index 或者 /_index/_type
你依旧可以在单独的请求中使用这些值:

curl -i -XGET "192.168.6.101:9200/megacorp/employee/_mget" -d '{
     "docs":[
          {"_id":2},
          {"_index":"website","_type":"blog","_id":123}
     ]
}'

结果如下:

HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 655

{
  "docs" : [
    {
      "_index" : "megacorp",
      "_type" : "employee",
      "_id" : "2",
      "_version" : 2,
      "found" : true,
      "_source" : {
        "first_name" : "Douglas",
        "last_name" : "Fir",
        "age" : 35,
        "about" : "I like to build cabinets",
        "interests" : [
          "forestry"
        ]
      }
    },
    {
      "_index" : "website",
      "_type" : "blog",
      "_id" : "123",
      "_version" : 2,
      "found" : true,
      "_source" : {
        "title" : "My first blog entry",
        "text" : "I am starting to get the hang of this...",
        "date" : "2014/01/02"
      }
    }
  ]
}

事实上,如果所有文档具有相同的 _index_type,你可以通过简单的 ids 数组来代替完整的 docs 数组:

curl -i -XGET "192.168.6.101:9200/megacorp/employee/_mget" -d '{
  "ids":["2","3"]
}'

更省时的批量操作

就像 mget 允许我们一次性检索多个文档一样,bulk API允许我们使用单一请求来实现多个文档的create,index,delete,update操作。可以以成百上千的数据为一个批次按序进行操作。
bulk 的请求体如下所示,它有一点不同寻常。

{action : {metadata}}\n
{request  body}\n
{action:{metadata}}\n
{request body}\n
.........

这种格式类似于用"\n"符号连接起来的一行一行的JSON文档流,两个重要的点需要注意:

  • 每行必须以"\n"结尾,包括最后一行。
  • 每行不能包含未被转义的换行符,这意味着JSON不能被美化打印

action/metadata定义了文档行为发生在了哪个文档之上。
行为(action)必须是以下几种:

行为 解释
create 当文档不存在时创建
index 创建新文档或替换已有文档
update 局部更新文档
delete 删除一个文档

在索引,更新,删除,创建一个文档时必须指定文档的_index,_type,_id这些元数据。
例如删除请求看起来像这样:

{"delete":{"_index":"megacorp","_type","employee","_id","2"}}

请求体(request body)由文档的 _source组成-------文档包含的一些字段以及其值。它被indexcreate操作所必须,这是有道理的:你必须提供文档用来索引。

{"create":{"_index":"website","_type":"blog","_id":"123"}}
{"title":"My first blog post"}

如果不定义_id,ID将会被自动创建:

{"index":{"_index":"website","_type":"blog"}}
{"title":"My second blog post"}

为了将这些放在一起,bulk 请求表单是这样的:

curl -i -XPOST "localhost:9200/_bulk" -d '
{"delete":{"_index":"website","_type":"blog","_id":"123"}}
{"create":{"_index":"website","_type":"blog","_id":"123"}}
{"title":"My first blog post"}
{"index":{"_index":"website","_type":"blog"}}
{"title":"My second blog post"}
{"update":{"_index":"website","_type":"blog","_id":"123","_retry_on_conflict":3}}
{"doc":{"title":"My update blog post"}}
'

你可以在同一个 index 下的同一个 type 里批量索引日志数据。为每个文档指定相同的元数据是多余的。就像 mget API,bulk 请求也可以在URL中使用 /_index/_index/_type

curl -i -XPOST "localhost:9200/website/_bulk" -d '
{"index":{"_type":"log"}}
{"event":"User logged in"}
'

你依旧可以覆盖元数据行的 _index_type,在没有覆盖时它会使用URL中的值作为默认值:

curl -i -XPOST "localhost:9200/website/log/_bulk" -d '
{"index":{}}
{"event":"User logged in"}
{"index":{"_type":"blog"}}
{"title":"Overriding the default type"}
'
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,738评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,377评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,774评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,032评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,015评论 5 361
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,239评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,724评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,374评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,508评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,410评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,457评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,132评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,733评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,804评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,022评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,515评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,116评论 2 341

推荐阅读更多精彩内容

  • 博客原文一博客原文二 翻译作品,水平有限,如有错误,烦请留言指正。原文请见 官网英文文档 起步 Elasticse...
    rabbitGYK阅读 3,223评论 0 68
  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,872评论 2 89
  • 基础概念 Elasticsearch有几个核心概念,从一开始理解这些概念会对整个学习过程有莫大的帮助。 接近实时(...
    山天大畜阅读 2,101评论 0 4
  • 不觉天色又将晚,依依梅河畔。 柳枝轻拂,湖面无帆,月影疏淡。 愁看霓虹映水面,颇似旧时颜。 遥想当初,亭下依伴,笑...
    走过吴桥阅读 395评论 30 28
  • 难得一次四人结伴培训,好开心!白天的时间培训日程满满,晚上利用闲暇时间兜兜转转,陌生的城市啊!也有曾经熟悉的...
    00的角落阅读 273评论 0 0