Elasticsearch从入门到放弃:文档CRUD要牢记

2020-05-29 00:00:00 文档 操作 参数 指定 请求

在Elasticsearch中,文档(document)是所有可搜索数据的小单位。它被序列化成JSON存储在Elasticsearch中。每个文档都会有一个ID,这个ID你可以自己指定或者交给Elasticsearch自动生成。

如果延续我们之前不恰当的对比RDMS的话,我认为文档可以类比成关系型数据库中的表。

元数据

前面我们提到,每个文档都有一个ID来标识,获取文档时,“_id”字段记录的就是文档的ID,它是元数据之一。当然,文档还有一些其他的元数据,下面我们来一一介绍

  • _index:文档所属的索引名
  • _type:文档所属的type
  • _id:文档的ID

有了这三个,我们就可以确定一个document了,当然,7.0版本以后我们已经不需要_type了。接下来我们再来看看其他的一些元数据

  • _source:文档的原始JSON数据
  • _field_names:该字段用于索引文档中值不为null的字段名,主要用于exists请求查找指定字段是否为空
  • _ignore:这个字段用于索引和存储文档中每个由于异常(开启了ignore_malformed)而被忽略的字段的名称
  • _meta:该字段用于存储一些自定义的元数据信息
  • _routing:用来指定数据落在哪个分片上,默认值是Id
  • _version:文档的版本信息
  • _score:相关性打分

创建文档

创建文档有以下4种方法:

  • PUT /\/\_doc/<_id>
  • POST /\<index>/_doc/
  • PUT /\/_create/<_id>
  • POST /\/_create/<_id>

这四种方法的区别是,如果不指定id,则Elasticsearch会自动生成一个id。如果使用_create的方法,则必须保证文档不存在,而使用_doc方法的话,既可以创建新的文档,也可以更新已存在的文档。

在创建文档时,还可以选择一些参数。

请求参数

  • if_seq_no:当文档的序列号是指定值时才更新
  • if_primary_term:当文档的primary term是指定值时才更新
  • op_type:如果设置为create则指定id的文档必须不存在,否则操作失败。有效值为index或create,默认为index
  • op_type:指定预处理的管道id
  • refresh:如果设置为true,则立即刷新受影响的分片。如果是wait_for,则会等到刷新分片后,此次操作才对搜索可见。如果是false,则不会刷新分片。默认值为false
  • routing:指定路由到的主分片
  • timeout:指定响应时间,默认是30秒
  • master_timeout:连接主节点的响应时长,默认是30秒
  • version:显式的指定版本号
  • version_type:指定版本号类型:internal、 external、external_gte、force
  • wait_for_active_shards:处理操作之前,必须保持活跃的分片副本数量,可以设置为all或者任意正整数。默认是1,即只需要主分片活跃。

响应包体

  • _shards:提供分片的信息
  • _shards.total:创建了文档的总分片数量
  • _shards.successful:成功创建文档分片的数量
  • _shards.failed:创建文档失败的分片数量
  • _index:文档所属索引
  • _type:文档所属type,目前只支持_doc
  • _id:文档的id
  • _version:文档的版本号
  • _seq_no:文档的序列号
  • _primary_term:文档的主要术语
  • result:索引的结果,created或者updated

我们在创建文档时,如果指定的索引不存在,则ES会自动为我们创建索引。这一操作是可以通过设置中的action.auto_create_index字段来控制的,默认是true。你可以修改这个字段,实现指定某些索引可以自动创建或者所有索引都不能自动创建的目的。

更新文档

了解了如何创建文档之后,我们再来看看应该如何更新一个已经存在的文档。其实在创建文档时我们就提到过,使用PUT /\/_doc/\的方法就可以更新一个已存在的文档。除此之外,我们还有另一种更新文档的方法:

POST /\/_update/\<_id>

这两种更新有所不同。_doc方法是先删除原有的文档,再创建新的。而_update方法则是增量更新,它的更新过程是先检索到文档,然后运行指定脚本,后重新索引。

还有一个区别就是_update方法支持使用脚本更新,默认的语言是painless,你可以通过参数lang来进行设置。在请求参数方面,_update相较于_doc多了以下几个参数:

  • lang:指定脚本语言
  • retry_on_conflict:发生冲突时重试次数,默认是0
  • _source:设置为false,则不返回任何检索字段
  • _source_excludes:指定要从检索结果排除的source字段
  • _source_includes:指定要返回的检索source字段

下面的一个例子是用脚本来更新文档

curl -X POST "localhost:9200/test/_update/1?pretty" -H 'Content-Type: application/json' -d'
{
    "script" : {
        "source": "ctx._source.counter += params.count",
        "lang": "painless",
        "params" : {
            "count" : 4
        }
    }
}
'

相关文章