ES在各复制分片之间如何同步,如何索引和查询数据:
write model(需要重写)
1.根据文档ID确定路由复制组(通常根据ID确定路由到哪一组复制分片上,路由规则可以自定义)。
2.转发到该复制组的主分片上,主分片验证数据并转发给其他复制分片。如果有多个复制组,并行执行。
3.所有复制成功后,返回给客户端。
4.如果有副本同步数据失败,
read model(需要重写)
单个文档API
(所有的CRUD都是针对单个文档的,index
参数接受单个索引名称,或者alias
指向单个索引。)
- 索引API indexAPI
#索引不存在时,自动创建;类型不存在时自动创建;
curl -XPUT 'localhost:9200/twitter/tweet/1?pretty' -H 'Content-Type: application/json' -d'
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
'
#id没有指定的话,自动生成,注意是POST而不是PUT
XPOST 'localhost:9200/twitter/tweet/?pretty' -H 'Content-Type: application/json' -d'
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
'
version_type
external 来启动版本号外部值补充
#指定操作类型,强制执行create操作,如果id为1的文档已经存在,此次操作失败
curl -XPUT 'localhost:9200/twitter/tweet/1?op_type=create&pretty' -H 'Content-Type: application/json' -d'
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
'
#也可写成如下方式
curl -XPUT 'localhost:9200/twitter/tweet/1/_create?pretty' -H 'Content-Type: application/json' -d'
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
'
#指定路由方式,默认使用id的散列值将文档路由到某一个的分片上,指定路由方式的好处是可以使相关的文档路由到相同的分片上,可使用_routing从文档中获取路由值
curl -XPOST 'localhost:9200/twitter/tweet?routing=kimchy&pretty' -H 'Content-Type: application/json' -d'
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
'
#指定超时参数为5min
curl -XPUT 'localhost:9200/twitter/tweet/1?timeout=5m&pretty' -H 'Content-Type: application/json' -d'
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
'
- 获取API /GET API
#获取id为0的文档
curl -XGET 'localhost:9200/twitter/tweet/0?pretty'
#检查id为0的文档是否存在
curl -XHEAD 'localhost:9200/twitter/tweet/0?pretty'
GET API是实时操作,更新的文档还未Refresh,则会搜索到更新前的文档信息,可设置realtime参数为false,禁用实时GET
#1.直接获取_source,2.设置_source=false,结果中就不返回source内容
curl -XGET 'localhost:9200/twitter/tweet/_source'
curl -XGET 'localhost:9200/twitter/tweet/0?_source=false&pretty'
#1.直接获取_source中自己指定的内容,2.设置_source_include和_source_exclude参数,过滤自己关心的内容,节省网络开销:返回*.id,排除entities,多个字段可用,号隔开
curl -XGET 'localhost:9200/twitter/tweet/1/_source?_source_include=*.id&_source_exclude=entities'&pretty'
curl -XGET 'localhost:9200/twitter/tweet/0?_source_include=*.id&_source_exclude=entities&pretty'
#如果只需要指定包含内容,可简化为:
curl -XGET 'localhost:9200/twitter/tweet/0?_source=*.id,retweeted&pretty'
#添加一个索引,counter字段不被存储,tags字段被存储
curl -XPUT 'localhost:9200/twitter?pretty' -H 'Content-Type: application/json' -d'
{
"mappings": {
"tweet": {
"properties": {
"counter": {
"type": "integer",
"store": false
},
"tags": {
"type": "keyword",
"store": true
}
}
}
}
}
'
#插入数据:
GET twitter/tweet/1?stored_fields=tags,counter
#获取数据:
curl -XGET 'localhost:9200/twitter/tweet/1?stored_fields=tags,counter&pretty'
#结果:没有存储的字段被忽略
{
"_index": "twitter",
"_type": "tweet",
"_id": "1",
"_version": 1,
"found": true,
"fields": {
"tags": [
"red"
]
}
}
#指定路由和字段,只有正确的路由和被存储的字段能返回结果
curl -XGET 'localhost:9200/twitter/tweet/2?routing=user1&stored_fields=tags,counter&pretty'
几个参数设置:
1.控制preference
哪个分片副本执行获取请求。默认情况下,操作在碎片副本之间是随机的。
preference
可设置为:
_primary
操作只会在主碎片上执行。
_local
如果可能,该操作将优选在本地分配的分片上执行。
2.refresh
参数可以设置为true
在get操作之前刷新相关分片并使其可搜索
3.version
只有当其当前版本等于指定的文档时,才可以使用该参数来检索文档。除了FORCE
总是检索文档的版本类型之外,所有版本类型的行为都是相同的。请注意,FORCE
版本类型已被弃用。
在内部,Elasticsearch将旧文档标记为已删除,并添加了一个全新的文档。旧版本的文档不会立即消失,尽管您无法访问它。随着您继续索引更多数据,Elasticsearch将在后台清理已删除的文档。
- 删除API/Delete API
#删除文档
curl -XDELETE 'localhost:9200/twitter/tweet/1?pretty'
#指定路由删除,当索引文档时使用了路由,删除时,也应当指定路由
curl -XDELETE 'localhost:9200/twitter/tweet/1?pretty'
#设置超时参数
curl -XDELETE 'localhost:9200/twitter/tweet/1?timeout=5m&pretty'
其他可设参数:
1.?refresh ---直接刷新
2. wait_for_active_shards 要求执行删除操作的最少副本数处于活跃状态
- Delete_by_query API
#对匹配到查询的文档进行删除
curl -XPOST 'localhost:9200/twitter/_delete_by_query?pretty' -H 'Content-Type: application/json' -d'
{
"query": {
"match": {
"message": "some message"
}
}
}
'
#删除过程中遇到版本冲突导致失败后继续执行
curl -XPOST 'localhost:9200/twitter/tweet/_delete_by_query?conflicts=proceed&pretty' -H 'Content-Type: application/json' -d'
{
"query": {
"match_all": {}
}
}
'
#一次性删除多个索引、多个文档
curl -XPOST 'localhost:9200/twitter,blog/tweet,post/_delete_by_query?pretty' -H 'Content-Type: application/json' -d'
{
"query": {
"match_all": {}
}
}
'
#删除路由到的分片中的数据
curl -XPOST 'localhost:9200/twitter/_delete_by_query?routing=1&pretty' -H 'Content-Type: application/json' -d'
{
"query": {
"range" : {
"age" : {
"gte" : 10
}
}
}
}
'
#默认scroll_size=1000,可以自己设置该参数
curl -XPOST 'localhost:9200/twitter/_delete_by_query?scroll_size=5000&pretty' -H 'Content-Type: application/json' -d'
{
"query": {
"term": {
"user": "kimchy"
}
}
}
'
delete_by_query URL支持的其他参数:
1.refresh----刷新所有涉及到查询的分片,在delete API中设置refresh只会刷新执行删除操作的分片
2.wait_for_completion=false----设置这个参数,es将会执行预检查,启动请求,返回一个可与task API一起使用的取消或查询状态的task,存放在.tasks/task/${taskId}
3.wait_for_active_shards
4.timeout
5.requests_per_second 可设置为任意正数,target_time = 1000 / 500 per second = 2 seconds(batch size/requests_per_second)
#根据task API查看任务状态
curl -XGET 'localhost:9200/_tasks?detailed=true&actions=*/delete/byquery&pretty'
#根据task ID直接查看
curl -XGET 'localhost:9200/_tasks/taskId:1?pretty'
#取消删除任务
curl -XPOST 'localhost:9200/_tasks/task_id:1/_cancel?pretty'
#改变正在执行的删除任务的rethrottle的值
curl -XPOST 'localhost:9200/_delete_by_query/task_id:1/_rethrottle?requests_per_second=-1&pretty'
#使用切片滚动,手动切片
curl -XPOST 'localhost:9200/twitter/_delete_by_query?pretty' -H 'Content-Type: application/json' -d'
{
"slice": {
"id": 0,
"max": 2
},
"query": {
"range": {
"likes": {
"lt": 10
}
}
}
}
'
curl -XPOST 'localhost:9200/twitter/_delete_by_query?pretty' -H 'Content-Type: application/json' -d'
{
"slice": {
"id": 1,
"max": 2
},
"query": {
"range": {
"likes": {
"lt": 10
}
}
}
}
'
#使用切片滚动,自动切片
curl -XPOST 'localhost:9200/twitter/_delete_by_query?refresh&slices=5&pretty' -H 'Content-Type: application/json' -d'
{
"query": {
"range": {
"likes": {
"lt": 10
}
}
}
}
'
- 更新API/Update API
根据提供的脚本更新文档,且使用版本控制来确保在“get”和“reindex”期间没有更新。此操作仍然意味着文档的完全重新索引,它只是消除了一些网络往返,并减少了获取和索引之间的版本冲突的机会。该_source
字段需要启用此功能才能正常工作。
#index一个文档
curl -XPUT 'localhost:9200/test/type1/1?pretty' -H 'Content-Type: application/json' -d'
{
"counter" : 1,
"tags" : ["red"]
}
'
#执行一个脚本,更新该文档count字段
curl -XPOST 'localhost:9200/test/type1/1/_update?pretty' -H 'Content-Type: application/json' -d'
{
"script" : {
"source": "ctx._source.counter += params.count",
"lang": "painless",
"params" : {
"count" : 4
}
}
}
'
#更新一个字段,给该字段添加一个值
curl -XPOST 'localhost:9200/test/type1/1/_update?pretty' -H 'Content-Type: application/json' -d'
{
"script" : {
"source": "ctx._source.tags.add(params.tag)",
"lang": "painless",
"params" : {
"tag" : "blue"
}
}
}
'
#给该文档添加一个新的字段
curl -XPOST 'localhost:9200/test/type1/1/_update?pretty' -H 'Content-Type: application/json' -d'
{
"script" : "ctx._source.new_field ='value_of_new_field'”
} '
#删除一个该文档的字段
curl -XPOST 'localhost:9200/test/type1/1/_update?pretty' -H 'Content-Type: application/json' -d'
{
"script" : "ctx._source.remove(’new_field’)"
}
'
#如果文档中的tags字段包含green,则删除,否则不做任何操作(noop)
curl -XPOST 'localhost:9200/test/type1/1/_update?pretty' -H 'Content-Type: application/json' -d'
{
"script" : {
"source": "if (ctx._source.tags.contains(params.tag)) { ctx.op = ’delete’ } else { ctx.op = ’none’}",
"lang": "painless",
"params" : {
"tag" : "green"
}
}
}
'
#不理解这是什么操作,应该是把文档中的“name”这个字段修改为“new_name”,官方文档:The update API also support passing a partial document, which will be merged into the existing document (simple recursive merge, inner merging of objects, replacing core "keys/values" and arrays). For example:
curl -XPOST 'localhost:9200/test/type1/1/_update?pretty' -H 'Content-Type: application/json' -d'
{
"doc" : {
"name" : "new_name"
}
}
'
#在上面的操作中,如果字段本身就是new_name ,返回结果中会有:“result”:“noop”,可以设置参数“detect_noop”来禁止此项检测
curl -XPOST 'localhost:9200/test/type1/1/_update?pretty' -H 'Content-Type: application/json' -d'
{
"doc" : {
"name" : "new_name"
},
"detect_noop": false
}
'
#如果文档不存在,则执行upsert的内容作为新文档插入,如果存在则更新count的值
curl -XPOST 'localhost:9200/test/type1/1/_update?pretty' -H 'Content-Type: application/json' -d'
{
"script" : {
"source": "ctx._source.counter += params.count",
"lang": "painless",
"params" : {
"count" : 4
}
},
"upsert" : {
"counter" : 1
}
}
'
#如果不关心文档存不存在,都执行脚本,则设置“scripted_upsert”为true
curl -XPOST 'localhost:9200/sessions/session/dh3sgudg8gsrgl/_update?pretty' -H 'Content-Type: application/json' -d'
{
"scripted_upsert":true,
"script" : {
"id": "my_web_session_summariser",
"params" : {
"pageViewEvent" : {
"url":"foo.com/bar",
"response":404,
"time":"2014-01-01 12:32"
}
}
},
"upsert" : {}
}
'
#如果文档不存在的话,doc作为upsert的值
curl -XPOST 'localhost:9200/test/type1/1/_update?pretty' -H 'Content-Type: application/json' -d'
{
"doc" : {
"name" : "new_name"
},
"doc_as_upsert" : true
}
'
更新操作可以设置的参数:
retry_on_conflict,routing,timeout,wait_for_active_shards,refresh,_source,version&version_type
update API不支持外部版本号(external version)
- upsert_by_query API