美文网首页
02-Elasticsearch API - 文档操作

02-Elasticsearch API - 文档操作

作者: M醉逍遥 | 来源:发表于2017-07-20 16:30 被阅读0次

    ES中文档的概念

    ES中一个文档即为一个json格式的文本,隶属于某个index的某个type下。当索引进ES后,一个文档不仅包含原始文档信息,还包含一下元数据:
    _index 文档存放在那个索引
    _type 文档属于什么对象类别
    _id 文档的唯一标识

    索引一个文档(新建一个文档)

    自己根据业务指定自定义id

    PUT /{index}/{type}/{id}
    {
      "field": "value",
      ...
    }
    

    实例:

    PUT /website/blog/123
    {
      "title": "My first blog entry",
      "text":  "Just trying this out...",
      "date":  "2014/01/01"
    }
    
    //result
    {
      "_index": "website",
      "_type": "blog",
      "_id": "123",
      "_version": 1,
      "result": "created",
      "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
      },
      "created": true
    }
    

    让ES为我们自动生成ID

    POST /{index}/{type}
    {
      "field": "value",
      ...
    }
    

    实例

    POST /website/blog/
    {
      "title": "My second blog entry",
      "text":  "Still trying this out...",
      "date":  "2014/01/01"
    }
    
    //result
    {
      "_index": "website",
      "_type": "blog",
      "_id": "AV1e6wxyr-eh0mA78TXL",
      "_version": 1,
      "result": "created",
      "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
      },
      "created": true
    }
    

    取回一个文档

    GET /{index}/{type}/{id}
    

    实例:

    //在请求的查询串参数中加上 pretty 参数, 正如前面的例子中看到的,这将会调用 Elasticsearch 的 pretty-print 功能,该功能 使得 JSON 响应体更加可读。但是, _source 字段不能被格式化打印出来。相反,我们得到的 _source 字段中的 JSON 串,刚好是和我们传给它的一样。
    GET /website/blog/123?pretty
    
    //result
    {
      "_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 /{index}/{type}/{id}?_source=field1,field2...
    

    实例:

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

    只想得到source字段

    GET /{index}/{type}/{id}/_source
    

    实例:

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

    检测文档是否存在

    将获取文档的GET请求改为HEAD请求即可,返回体只会返回一个HTTP请求报头

    HEAD /{index}/{type}/{id}
    

    返回的头信息:

    HTTP/1.1 200 OK
    Content-Type: text/plain; charset=UTF-8
    Content-Length: 0
    

    更新整个文档

    在 ES 中文档是 不可改变 的,不能修改它们。 相反,如果想要更新现有的文档,需要 重建索引 或者进行替换, 我们可以使用相同的 index API 进行实现
    实例:

    PUT /website/blog/123
    {
      "title": "My first blog entry",
      "text":  "I am starting to get the hang of this...",
      "date":  "2014/01/02"
    }
    
    //result
    {
      "_index": "website",
      "_type": "blog",
      "_id": "123",
      "_version": 2, //版本号增加了
      "result": "updated",
      "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
      },
      "created": false //是否创建为false
    }
    

    在内部,Elasticsearch 已将旧文档标记为已删除,并增加一个全新的文档。 尽管你不能再对旧版本的文档进行访问,但它并不会立即消失。当继续索引更多的数据,Elasticsearch 会在后台清理这些已删除文档。

    控制只是创建文档不会更新文档

    当使用POST不指定id时,ES始终都是新建文档,当指定id时可以使用一下两种方式控制新建,当id存在时,则返回失败

    PUT /{index}/{type}/{id}?op_type=create
    {...}
    
    PUT /{index}/{type}/{id}/_create
    {...}
    

    删除文档

    DELETE /{index}/{type}/{id}
    

    实例:

    DELETE /website/blog/123
    
    //result
    {
      "found": true,
      "_index": "website",
      "_type": "blog",
      "_id": "123",
      "_version": 3,
      "result": "deleted",
      "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
      }
    }
    

    文档的部分更新

    我们也介绍过文档是不可变的:他们不能被修改,只能被替换。 update API 必须遵循同样的规则。 从外部来看,我们在一个文档的某个位置进行部分更新。然而在内部, update API 简单使用与之前描述相同的 检索-修改-重建索引 的处理过程。 区别在于这个过程发生在分片内部,这样就避免了多次请求的网络开销。通过减少检索和重建索引步骤之间的时间,我们也减少了其他进程的变更带来冲突的可能性。

    POST /{index}/{type}/{id}/_update
    {
      "doc": {
        "field": value,
        ...
      }
    }
    

    实例:

    POST /website/blog/1/_update
    {
       "doc" : {
          "tags" : [ "testing" ],
          "views": 0
       }
    }
    
    //result
    {
      "_index": "website",
      "_type": "blog",
      "_id": "1",
      "_version": 2,
      "result": "updated",
      "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
      }
    }
    

    使用Groovy脚本更新文档

    //将views字段值加1
    POST /website/blog/1/_update
    {
       "script" : "ctx._source.views+=1"
    }
    
    //result
    {
      "_index": "website",
      "_type": "blog",
      "_id": "1",
      "_version": 3,
      "result": "updated",
      "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
      }
    }
    

    取回多个文档

    跨index与type取回文档

    GET /_mget
    GET /_mget
    {
       "docs" : [
          {
             "_index" : {index},
             "_type" : {type},
             "_id" : {id}
          },
          ...
       ]
    }
    

    实例:

    GET /_mget
    {
       "docs" : [
          {
             "_index" : "website",
             "_type" :  "blog",
             "_id" :    1
          },
          {
             "_index" : "website",
             "_type" :  "pageviews",
             "_id" :    1,
             "_source": "views"
          }
       ]
    }
    
    //result
    {
      "docs": [
        {
          "_index": "website",
          "_type": "blog",
          "_id": "1",
          "_version": 3,
          "found": true,
          "_source": {
            "title": "My first blog entry",
            "text": "I am starting to get the hang of this...",
            "date": "2014/01/02",
            "views": 1,
            "tags": [
              "testing"
            ]
          }
        },
        {
          "_index": "website",
          "_type": "pageviews",
          "_id": "1",
          "found": false
        }
      ]
    }
    

    如果想检索的数据都在相同的 _index 中(甚至相同的 _type 中),则可以在 URL 中指定默认的 /_index 或者默认的 /_index/_type
    实例:

    GET /website/blog/_mget
    {
       "docs" : [
          { "_id" : 2 },
          { "_type" : "pageviews", "_id" :   1 }
       ]
    }
    

    如果所有文档的 _index 和 _type 都是相同的,你可以只传一个 ids 数组
    实例:

    GET /website/blog/_mget
    {
       "ids" : [ "2", "1" ]
    }
    

    代价较小的批量操作

    与 mget 可以使我们一次取回多个文档同样的方式, bulk API 允许在单个步骤中进行多次 create 、 index 、 update 或 delete 请求。

    POST /_bulk
    { action: { metadata }}\n
    { request body        }\n
    { action: { metadata }}\n
    { request body        }\n
    ...
    

    这种格式类似一个有效的单行 JSON 文档 流 ,它通过换行符(\n)连接到一起。注意两个要点:
    每行一定要以换行符(\n)结尾, 包括最后一行 。这些换行符被用作一个标记,可以有效分隔行。
    这些行不能包含未转义的换行符,因为他们将会对解析造成干扰。这意味着这个 JSON 不 能使用 pretty 参数打印。

    action/metadata 行指定 哪一个文档 做 什么操作 。
    action 必须是以下选项之一:
    create
    如果文档不存在,那么就创建它。详情请见 创建新文档。
    index
    创建一个新文档或者替换一个现有的文档。详情请见 索引文档 和 更新整个文档。
    update
    部分更新一个文档。详情请见 文档的部分更新。
    delete
    删除一个文档。详情请见 删除文档。
    metadata 应该 指定被索引、创建、更新或者删除的文档的 _index 、 _type 和 _id 。

    实例:

    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"} } 
    

    多大是太大了?
    整个批量请求都需要由接收到请求的节点加载到内存中,因此该请求越大,其他请求所能获得的内存就越少。 批量请求的大小有一个最佳值,大于这个值,性能将不再提升,甚至会下降。 但是最佳值不是一个固定的值。它完全取决于硬件、文档的大小和复杂度、索引和搜索的负载的整体情况。

    幸运的是,很容易找到这个 最佳点 :通过批量索引典型文档,并不断增加批量大小进行尝试。 当性能开始下降,那么你的批量大小就太大了。一个好的办法是开始时将 1,000 到 5,000 个文档作为一个批次, 如果你的文档非常大,那么就减少批量的文档个数。

    密切关注你的批量请求的物理大小往往非常有用,一千个 1KB 的文档是完全不同于一千个 1MB 文档所占的物理大小。 一个好的批量大小在开始处理后所占用的物理大小约为 5-15 MB。

    相关文章

      网友评论

          本文标题:02-Elasticsearch API - 文档操作

          本文链接:https://www.haomeiwen.com/subject/rpqrkxtx.html