增加文档
在Elasticsearch中如果有相同ID的文档存在,则更新此文档
示例:
PUT /secisland/secilog/1
{
"collect_type":"syslog",
"collect_date":"2016-01-11T09:32:12",
"message":"xxxxx"
}
返回:
{
"_index": "secisland",
"_type": "secilog",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,//文档被创建的时候,在多少个分片中进行了操作,包括主分片和副本分片
"successful": 1,//成功建立索引分片的数量,最少为1
"failed": 0//失败建立索引的数量
},
"created": true
}
自动创建索引
当创建文档的时候,如果索引不存在,则会自动创建该索引。自动创建的索引会自动映射每个字段的类型。
可以通过配置文件设置action.auto_create_index
为false在所有节点的配置文件中禁用自动创建索引。自动映射的字段类型可以通过配置文件设置index.mapper.dynamec
为false警用。
版本号
每个文档都有一个版本号,版本号的具体值放在创建索引的返回值中(_version
)。通过版本号参数可以达到并发控制的效果。当在操作文档的过程中指定版本号,如果和版本号不一致的时候操作会被拒绝。
示例:
PUT /secisland/secilog/1?version=2
{
"message": "yyyyyyy"
}
返回:
{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[secilog][1]: version conflict, current version [1] is different than the one provided [2]",
"index_uuid": "lNWvsNq7QLuxpA-_Nq_RKQ",
"shard": "3",
"index": "secisland"
}
],
"type": "version_conflict_engine_exception",
"reason": "[secilog][1]: version conflict, current version [1] is different than the one provided [2]",
"index_uuid": "lNWvsNq7QLuxpA-_Nq_RKQ",
"shard": "3",
"index": "secisland"
},
"status": 409
}
默认情况下对文档的操作版本号从1开始递增,包括修改文档和删除文档。
版本号也可以从外部获取,比如从数据库中获取,要启用此功能,version_type
应设置为extternal,这个值必须是一个大于0小于9.2e+18的数字。当使用外部版本号来代替自动生成的版本号时,在操作文档的时候,系统通过对比参数中的版本号是否大于文档中的版本号来做判断,当参数中的版本号大于系统中的版本号,则执行此操作,并更新版本号。反之则拒绝操作。
操作类型
系统同时支持通过op_type=create
参数强制命令执行创建操作,只有系统中不存在此文档的时候才会创建成功。如果不指定此操作类型,如果存在此文档,则会更新此文档。
示例:再次创建id存在的文档
PUT /secisland/secilog/1?op_type=create
{
"collect_type":"syslog",
"collect_date":"2016-01-11T09:32:12",
"message":"zzzzz"
}
返回:
{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[secilog][1]: version conflict, document already exists (current version [1])",
"index_uuid": "lNWvsNq7QLuxpA-_Nq_RKQ",
"shard": "3",
"index": "secisland"
}
],
"type": "version_conflict_engine_exception",
"reason": "[secilog][1]: version conflict, document already exists (current version [1])",
"index_uuid": "lNWvsNq7QLuxpA-_Nq_RKQ",
"shard": "3",
"index": "secisland"
},
"status": 409
}
当不指定op_type=create时候,则更新此文档。
创建操作的另一个写法:
PUT /secisland/secilog/1/_create
自动创建ID
当创建文档的时候,如果不指定ID,系统会自动创建ID。自动生成的ID是一个不会重复的随机数。使用GUID算法,可以保证在分布式环境下,不同节点同一时间创建的_id一定是不冲突的。
分片选择
默认情况下,分片的选择是通过ID的散列值进行控制。这个只可以通过router参数进行手动的控制。可以在每个操作的基础上直接通过哈希函数的值来指定分片的选择。
示例:
POST /secisland/secilog/>routing=secisland
分片的选择是通过指定routing=secisland参数的哈希值来确定的。
其它说明
- 分布式:索引操作主要是针对主节点的分片进行,当主节点完成索引操作后,如果有副本节点,则分发到副本中。
- 一致性:为了防止当网络出现问题时写入不一致,系统只有在有效节点的数量大于一定数量的时候生效(总结点数/2+1),该值可以通过
action.write_consistency
参数进行修改。 - 刷新:更新的时候可以指定
refresh
参数为true来立即刷新所有的副本,当refresh设置为true的时候,系统做了充分的优化,不会对系统产生任何影响,需要注意的是查询操作refresh参数没有任何的意义。 - 空操作:当文档内容没有任何改变的时候,更新文档操作也会生效,具体体现在版本号会发生变化。如果不希望此情况发生,在更新的时候指定
detect_noop
为true。这个参数在创建索引的时候无效。 - 超时:默认情况下系统的超时时间是1分钟。可以通过设置timeout修改超时的时间,例如timeout-5m,表示超时的时间是5分钟。
更新删除文档
更新操作从索引中获取文档,执行脚本,然后获得返回结果。它使用版本号来控制文档获取或者重建索引。
脚本开启功能
在config/elasticsearch.yml文件添加以下代码:
script.inline:on
script.indexed:on
script.file:on
用脚本更新文档
示例:
POST /secisland/secilog/1/_update?pretty
{
"script": {
"source": "ctx._source.counter += count"
}
}
POST /secisland/secilog/1/_update
{
"script": {
"source": "ctx._source.tags.add(params.tag)",
"params": {"tag": "xxx"}
}
}
在脚本中,除了_source外其它内置参数也可以使用,例如_index,_type,_version,_routing,_parent,_timestamp,_ttl等。
POST /secisland/secilog/1/_update
{
"script": {
"source":"ctx._source.newfield = 'newvalue'"
}
}
删除文档
DELETE /secisland/secilog/1
查询文档
GET /secisland/secilog/1
返回:
{
"_index": "secisland",
"_type": "secilog",
"_id": "1",
"_version": 5,
"found": true,
"_source": {
"counter": 3,
"tags": [
"red",
"xxx"
],
"newfield": "newvalue"
}
}
默认情况下,查询获得的数据接口是实时的,并且不受索引的刷新率影响,为了禁用实时性,可以将参数realtime
设置为false,或全局设置action.get.realtime
为false。
禁用_source
GET /secisland/secilog/1?_source=false
返回:
{
"_index": "secisland",
"_type": "secilog",
"_id": "1",
"_version": 5,
"found": true
}
获取source中的一部分内容
GET /secisland/secilog/1?_source_include=counter
返回:
{
"_index": "secisland",
"_type": "secilog",
"_id": "1",
"_version": 5,
"found": true,
"_source": {
"counter": 3
}
}
当一个文档内容非常多的时候,用包含或者过滤可以减少很多的网络负担。如果有多个,可以用逗号分开,或者用*通配符。
GET /secisland/secilog/1?_source_include=counter,tags
只获取文档内容:
GET /secisland/secilog/1/_source
分片选择:
可以在查询的时候指定路由选择(routing),当路由不存在的时候,返回为空值.
GET /secisland/secilog/1/?routing=secisland
查询参数:
通过参数控制,查询的时候可以指定查询是在主节点上查询还是在副本节点上查询,参数有:
- _primary:在主节点上查询
- _local:尽可能在本地节点上进行查询
- refresh:可以设置为true,使之在搜索操作前刷新相关的分片保证可以即时查询到。(非常耗费资源,尽量不要设置)
GET /secisland/secilog/1?_primary&refresh=true
多文档操作
多文档查询可以在同一个接口中查询多个文档,可以分别指定index、type、id来进行多个文档的查询。响应包括所有查询到的文档数组,每个元素在结构上类似单个文档查询。
POST _mget
{
"docs":[
{"_index":"secisland","_type":"secilog","_id":"1"},
{"_index":"secisland","_type":"secilog","_id":"2"}
]
}
返回:
{
"docs": [
{
"_index": "secisland",
"_type": "secilog",
"_id": "1",
"_version": 5,
"found": true,
"_source": {
"counter": 3,
"tags": [
"red",
"xxx"
],
"newfield": "newvalue"
}
},
{
"_index": "secisland",
"_type": "secilog",
"_id": "2",
"found": false
}
]
}
在查询的时候,index、type可以在URL中直接填写。
POST /secisland/_mget?
{
"docs": [
{"_type":"secilog","_id":"1"},
{"_type":"secilog","_id":"2"}
]
}
type参数说明:
在多文档查询中,_type
允许为空,它设置为空或者_all的时候,系统会匹配第一个查询到的结果。如果不设置_type,当有许多文件有相同的_id的时候,系统最终得到的只有第一个匹配的文档。
块操作:
块操作可以在一个接口中处理文档的内容,包括创建、删除和修改文档。
示例:
POST _bulk
{"index":{"_index":"secisland","_type":"secilog","_id":"1"}}
{"counter":"1"}
{"index":{"_index":"secisland","_type":"secilog","_id":"2"}}
{"counter":"2"}
返回:
{
"took": 3,
"errors": false,
"items": [
{
"index": {
"_index": "secisland",
"_type": "secilog",
"_id": "1",
"_version": 7,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": false,
"status": 200
}
},
{
"index": {
"_index": "secisland",
"_type": "secilog",
"_id": "2",
"_version": 2,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"created": false,
"status": 200
}
}
]
}
和批量查询类似,/_bulk、/{index}/_bulk、{index}/{type}/_bulk这三种方式都尅执行,只需要在请求的参数中做出相应的对应。