Elasticsearch官档翻译——5.1 Index API

Index API

搜索API可以添加或修改一个 JSON 格式的文档到指定索引中,让它能被搜索到。一下例子插入了一个 ID 为1的 JSON 文档到 "twitter" 索引下的 tweet 类型中。

PUT /twitter/tweet/1
{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}

索引操作结果如下:

{
    "_shards" : {
        "total" : 10,
        "failed" : 0,
        "successful" : 10
    },
    "_index" : "twitter",
    "_type" : "tweet",
    "_id" : "1",
    "_version" : 1,
    "created" : true
}

_shard头提供了索引操作过程的复制信息

  • total - 表明索引操作在几个分片(主分片和副本分片)上执行了
  • successful - 表明索引操作在几个分片上操作成功
  • failures - 索引操作失败的分片数量

successful 至少为1索引才算插入成功。

译者批注:所有的增删改操作都必须要在主分片上执行,每个主分片维护了一组元数据,能够让我们找到某个分片在哪个具体的节点,当一个文档在一个主分片上操作完成后,请求会被同步到这个分片在其他节点上的副本

注意:副本可能还没有执行完就会返回 successful (默认半数以上执行完认为成功)。这种情况下,total 将会返回所有的主分片和副本,successful 将会返回所有执行成功的分片(主分片加副本)。如果没有错误发生,failed 等于0。

索引自动创建

如果插入操作的索引不存在则会自动创建(手动创建索引查看创建索引 API),并会自动创建type的映射到指定type下(手动创建映射,查看 创建映射API )。

映射本身十分灵活而且是无模式的。新的字段和对象将会加入指定 type 下的映射的定义中。映射定义详见 mapping章节。

动态索引创建可以通过在配置文件中配置 action.auto_create_indexfalse 来禁用。动态映射创建可以通过配置 index.mapper.dynamicfalse 来禁用(或者设置指定的索引的配置)。

动态创建可以基于一个黑白名单指定模式,例如,配置 action.auto_create_index的值为 +aaa*,-bbb*,+ccc*,-*等(+表示允许,-表示不允许)。

版本

每个文档都有一个版本号。版本号作为 index API 响应的一部分返回。当指定 version 参数的时候,index API 使用乐观锁并发控制,这能控制操作文档的版本。一个不错的使用版本的方法是使用读后再更新的事务策略。指定最初读取文档的版本,能够确保在此期间不会发生改变。(当更新前读取的时候,建议指定 preference 值为 _primary)。例如:

PUT /twitter/tweet/1?version=2
{
    "message" : "elasticsearch now has versioning support, double cool!"
}

注意:版本是完全实时的,并不受搜索操作的准实时方面的影响。如果没有提供版本,则不进行版本检查。

默认的,内部版本号从1开始,每次修改删除操作加1。版本可以由外部提供(例如在数据库保持一份)。为了支持这个功能,version_type 参数要指定为 external,版本值必须是大于等于0的数字或long类型。而且要小于 9.2*10^18。当使用外部版本类型时,不是匹配版本号是否一致,而是系统检查索引请求的版本号是否大于当前存储文档的版本,如果大于当前版本,则文档入索引并使用新版本;如果小于当前版本,则会触发版本冲突异常,并且当前请求失败。

译者批注:外部版本可以使用数据库记录的数据中的某些值,比如自增的id,或者数据库再记录一个插入时间戳。数据库的每个操作类似一个
elasticsearch 的操作日志,当出现同一个记录并发操作可能导致冲突的时候,更新带上版本号,这样就算新的操作再旧的操作后面,也不会被就的操作覆盖

警告:外部版本号支持以0开始。这样就支持使用从0开始的外部版本系统同步到索引中。当然副作用就是只要是版本号为0的文档,既不可以通过 Update-By-Query API更新,也不可以通过 Delete By Query API删除。

好的作用是只要外部版本数据源使用数据库,则异步的索引操作对于数据库数据源的变化,不用保持严格的排序。如果使用外部版本,即使是来自数据库的更新,索引更新也很简单,因为如果索引操作因为任何原因出问题,它将使用最新版本。

译者批注:此处翻译比较拗口,大概意思就是通过外部版本控制,不会导致数据库同步过程中出现并发冲突,及时出现版本不对的情况下,你的数据还是es里面最新的那个版本。

版本控制类型

紧接着上面介绍的内部版本和外部版本控制,Elasticsearch 还根据指定的业务场景支持其他的版本控制类型。以下是这些不同类型的版本控制以及他们的含义。

  • internal - 只有给定版本等于当前版本的时候才索引文档。
  • external & external_gt只有当给定版本严格大于存储的当前版本,或者文档不存在的时候,文档才会用指定版本作为当前版本并存储新的文档,给定版本不能是负数。
  • external_gte - 和 external的不同在于给定版本等于当前版本也能生效。

注意:external_gte 类型的版本控制用于特殊业务场景,要小心使用。使用不当会丢数据。还有一个选项:force,不过已经废弃了,因为会导致住副本分片数据不一致

操作类型

索引操作也可以接受一个 op_type 参数,可用来强制执行一个 create 操作,支持 put-if-absent 的行为(CAS)。当使用 create 操作时,如果文档存在,则索引操作将失败。
下面是使用 op_type 参数的例子:

PUT twitter/_doc/1?op_type=create
{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}

另一个使用 create 操作的方法如下:

PUT twitter/_doc/1/_create
{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}

ID自动生成

搜索操作可以不指定id,下面的这个例子,id将会自动创建。另外,op_type 将默认设置为 create。下面是例子(注意使用 POST请求):

POST twitter/_doc/
{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}

一下是索引操作的返回结果:

{
    "_shards" : {
        "total" : 2,
        "failed" : 0,
        "successful" : 2
    },
    "_index" : "twitter",
    "_type" : "_doc",
    "_id" : "6a8ca01c-7896-48e9-81cc-9f70661fcb32",
    "_version" : 1,
    "_seq_no" : 0,
    "_primary_term" : 1,
    "result": "created"
}

路由

默认情况下,分片的位置 —— 或者说路由 —— 使用文档id的哈希值控制。路由值还可以通过 routing 参数来指明。例如:

POST twitter/tweet?routing=kimchy
{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}

上面的例子中,文档根据 routing 参数值 "kimchy" 路由到某个分片。

当设置过映射后,_routing 字段用来指定索引操作到那个分片,并且路由值可以从文档中提取,这个方式会在解析文档时带来一点开销(非常少),如果 _routing 在映射的时候指定,并且设置了 required,当索引操作的文档对应的字段不存在时,操作会失败。

译者批注:2.0.0 以后就废弃的属性不做翻译了

父子关系

一个子文档在插入的时候可以指定它的父文档。例如:

PUT /blogs/blog_tag/1122?parent=1111
{
    "tag" : "something"
}

当索引子文档的时候,路由值会自动和父文档保持一致,除非子文档在参数中指定了 routing 参数。

分布式

索引操作会根据路由信息被分发到主分片并在主分片所在节点执行。当主节点执行完毕,请求会被分发到可用到副本分片上。

写一致性

为确保写操作不在网络分区时发生错误,默认情况下爱,索引操作只有当半数以上的分片(> replicas / 2 + 1)操作成功后才会返回成功。这个配置可以通过 action.write_consistency 选项覆盖。如果想一步操作修改这个参数,可以使用 consistency 请求。

合法的参数值有:one , quorum , all

注意副本为1的情况(总共只有两个分片),此时默认认为主分片写成功才算成功。

索引操作仅在所有可用分片,包括副本写入文档后才返回(使用同步副本方式)。

译者批注:使用异步方式,不等副本写完就可以返回,不会不建议这么做,特别是数据一致性高的场景,而且可能会使 ES 过载

刷新

为了能够让文档能在搜索结果中立刻被查看,要在索引操作后立马刷新分片(不是整个索引),可以设置 refreshtrue 实现这点。设置这个需要你仔细思考并确认会不会导致索引和搜索的性能问题。注意,使用 get API是完全实时的,不需要刷新。

空的更新

当你创建文档的时候,总是会给文档增加一个新版本,哪怕是这个请求没有对文档做出改变。如果使用 _update 你不想让它这样的话,可以设置 detect_nooptrue 。这个操作在 index API 是无效的,因为 index 请求并不会先获得旧的文档的source,也就没法比较文档是否相同。

没有一个硬性规则要求使用 noop 这个特性。这个选择包含了很多因素,例如你更新文档出现 noop 的频率,以及你在更新频率高的分片上查询的QPS等等。

超时

执行索引操作的那个主分片有可能执行失败,可能的原因比如主分片正在恢复或者后台在进行分片平移。默认情况下索引操作将等待1分钟让分片变为可用,超过则失败并返回一个异常。timeout 参数用来指定这个等待时间。下面的例子我们设置它为5分钟:

PUT /twitter/tweet/1?timeout=5m
{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}

译者批注:其实每种请求API理论上都是有请求超时限制的,建议给你的所有请求评估一个超时时间,一面部分请求超时阻塞请求队列导致其他请求也一起被阻塞,可以把这个时间做成动态可配置的,达到熔断效果

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • 博客原文一博客原文二 翻译作品,水平有限,如有错误,烦请留言指正。原文请见 官网英文文档 起步 Elasticse...
    rabbitGYK阅读 3,227评论 0 68
  • 文章名称:Elasticsearch Reference[2.2]原文地址:https://www.elastic...
    code4j阅读 1,062评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,591评论 18 139
  • 中秋月饼哪家强? 听筝读诗 不一样! 这个中秋,听筝读诗联合康爱公益为大家定制了一款纯手工皂哦。 丨关于这款手工皂...
    听筝读诗阅读 308评论 2 7
  • 他们笑着 沉默的你 唱着悲伤的歌 换来的 却是喜剧的效果 他们还笑着 滑稽的人啊 只剩下一把吉他 还要唱歌 你蹲在...
    倦凭秋树阅读 193评论 0 1