ElasticSearch开始(2)


ElasticSearch开始(2)–数据输入和输出

2018.10.17

聚合(aggregations)

聚合类似于GROUP BY,但更加强大.

想知道叫 Smith 的雇员中最受欢迎的兴趣爱好:
 GET /megacorp/employee/_search
 {
   "query":{
     "match": {
       "last_name":"smith"
     }
   },
   "aggs": {
     "all_interests": {
       "terms": {
         "field": "interests.keyword"
       }
     }
   }
 }

ES中的文档元数据

1)包含了三个必须的元数据元素:

①index
索引,文档在哪儿存放。一个 索引 应该是因共同的特性被分组到一起的文档集合,这个名字必须小写,不能以下划线开头,不能包含逗号。
②type
文档表示的对象类别。
③id
文档唯一标识。ID 是一个字符串, 当它和 index 以及 type 组合就可以唯一确定 Elasticsearch 中的一个文档。可以提供自定义的id值,或者让 index API 自动生成。

2)数据输入和输出

为文档建立索引

<HTTP谓词:PUT>

使用自定义ID【URL中包含了index,type,id】
 PUT {index}/{type}/{id}
 {
     "filed":"value",
     ……
 }

如果index,type,id的组合存在,则会将旧文档覆盖,如果想确保创建新文档,避免覆盖现有文档,则使用_create端点:

PUT {index}/{type}/{id}/_create
自动生成ID【URL中只包含index,type】
 PUT {index}/{type}
 {
     "field":"value"
     ……
 }

可以确保文档能够被创建

取回一个文档

<HTTP谓词:GET>

仍然使用index,type,id
GET {index}/{type}/{id}  

curl命令

curl -i -XGET http://localhost:9200/{index}/{type}/{id}   -i:显示响应头
返回文档的一部分【使用_source参数】
GET {index}/{type}/{id}?_source=filed1,filed2……

只返回_source字段,不返回其他元数据【使用_source端点】

GET {index}/{type}/{id}/_source
检查文档是否存在
<HTTP谓词:HEAD>
curl -i -XHEAD http://localhost:9200/{index}/{type}/{id}
删除文档
<HTTP谓词:DELETE>
DELETE {index}/{type}/{id} 
处理冲突
乐观并发控制

可以利用_version号来确保应用中相互冲突的变更不会导致数据丢失。通过指定想要修改文档的_version号来达到这个目的。如果该版本不是当前版本号,请求将会失败。

 PUT /{index}/{type}/{id}?version=1 
 {
   "title": "My first blog entry",
   "text":  "Starting to get the hang of this..."
 }

外部版本号
<参数:versiontype = external>
外部版本号的处理方式和之前的内部版本号的处理方式有些不同,ElasticSearch 不是检查当前_version和请求中指定的版本号是否相同, 而是检查当前_version是否小于指定的版本号。如果是,则请求成功,外部的版本号作为文档的新_version 进行存储。

 PUT /website/blog/2?version=5&versiontype=external
 {
   "title": "My first external blog entry",
   "text":  "Starting to get the hang of this..."
 }
文档的部分更新

<HTTP谓词:POST>.
<API:_update>. update 请求最简单的一种形式是接收文档的一部分作为 doc 的参数, 它只是与现有的文档进行合并。对象被合并到一起,覆盖现有的字段,增加新的字段。

增加字段
 POST /website/blog/1/_update
 {
    "doc" : {
       "tags" : [ "testing" ],
       "views": 0
    }
 }
使用脚本部分更新文档

脚本可以在 update API中用来改变_source 的字段内容,它在更新脚本中称为ctx._source 。例如,我们可以使用脚本来增加博客文章中 views 的数量:

 POST /website/blog/1/_update
 {
    "script" : "ctx._source.views+=1"
 }

也可以通过使用脚本给 tags 数组添加一个新的标签:

 POST /website/blog/1/_update
 {
    "script" : "ctx._source.tags.add(params.new_tag)",
    "params" : {
       "new_tag" : "search"
    }
 }
更新的文档可能尚不存在

<参数:upsert>. 可以使用 upsert 参数,指定如果文档不存在就应该先创建它:

 POST /website/pageviews/1/_update
 {
    "script" : "ctx._source.views+=1",
    "upsert": {
        "views": 1
    }
 }
取回多个文档

<API:_mget>
<参数:docs>
mget API 要求有一个 docs 数组作为参数,每个 元素包含需要检索文档的元数据, 包括index、type 和id 。如果想检索一个或者多个特定的字段,那么你可以通过_source 参数来指定这些字段的名字:

 GET /_mget
 {
    "docs" : [
       {
          "index" : "website",
          "type" :  "blog",
          "id" :    2
       },
       {
          "index" : "website",
          "type" :  "pageviews",
          "id" :    1,
          "_source": "views"
       }
    ]
 }
代价较小的批量操作

<API:bulk>.
bulk允许在单个步骤中进行多次 create 、index 、 update 或 delete 请求。 如果你需要索引一个数据流比如日志事件,它可以排队和索引数百或数千批次。 格式: { action: { metadata }} { request body } { action: { metadata }} { request body } … metadata 应该指定被索引、创建、更新或者删除的文档的index、type 和id。

{"delete":{"index":"","type":"","d":""}}

request body行由文档的_source本身组成–文档包含的字段和值。它是 index 和 create 操作所必需的,你必须提供文档以索引。 它也是 update 操作所必需的,并且应该包含你传递给 update API 的相同请求体: doc 、 upsert 、 script 等等。 删除操作不需要 request body 行。

 { "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请求:

POST /_bulk
 { "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 updated blog post"} } ②
 
//①:delete不能有请求体,其后跟着另一个操作
//②:最后必须有换行符