专栏首页python学习指南Elasticsearch--数据索引

Elasticsearch--数据索引

前言

Elasticsearch可以支持全文检索,那么ES是以什么机制来支持的,这里索引就是一个重要的步骤,经过索引之后的文档才可以被分析存储、建立倒排索引。本篇就是以ES的数据检索操作来讨论的。 更多内容情参考:ELK教程

索引操作

ES索引可以根据指定的index和type进行增加或者更新文档,ID可以指定也可以不指定(index API为我们自动生成)

curl -XPUT 'http://localhost:9200/twitter/tweet/1' -d '{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}'

这里指定了索引twitter、类型tweet、Id为1 索引操作的结果如下:

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

上面_shards中描述了分片相关的信息,即当前一共有10个分片(5个主分片,5个副本); 以及index、type、id、version相关信息

  • total:表示现在在使用的分片数量(主分片和副本)
  • successful:操作成功的分片数量
  • failed:操作失败的分片数量

自动创建索引

如果上面索引操作之前,ES中还没有这个索引,那么默认会创建这个索引,并且type类型也会自动创建,也就是说,ES并不需要像传统数据库那样预先定义表的结构。 每个索引都有一个mapping映射,这个映射也是动态生成的,因此当添加新的字段时,会自动的添加mapping映射。 通过在所有节点的配置文件中设置action_create_indexfalse,可以关闭自动索引创建这个功能,默认是打开的 通过在所有节点的配置文件中设置index.mapper.dynamicfalse,可以关闭自动映射创建功能。 通过在所有节点的配置文间中设置action.auto_create_index+aaa,-bbb,+ccc,-有选择性的创建某些索引。 关闭自动mapping映射功能时,就会引发第一次索引的数据失败,这里我们就要自己手动的put一个映射Elasticsearch-Mapping映射

版本控制

Elasticsearch采用乐观并发控制,当程序并发性比较高的时候,就会产生脏读,所以ES就使用版本号用来避免文档冲突,这里不多过多介绍,分成专门的一篇来介绍ES的版本控制问题Elasticsearch-版本控制

操作类型

ES通过设置一个参数op_type控制索引操作"缺少即加入",当设置op_typecreate时,如果索引时指定的id已经存在,那么索引操作就会失败 上面的op_type=create与直接使用_create API,效果一样:

curl -XPUT 'http://localhost:9200/twitter/tweet/1?op_type=create' -d '{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}'

等价于:

curl -XPUT 'http://localhost:9200/twitter/tweet/1/_create' -d '{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}'

如果使用自动id生成就不存在这个问题了。

自动ID创建:

前面提到创建索引时可以指定ID,也可以不指定ID,如果不指定ID,那么ES会自动的生成一个ID,并且把op_type更改为create。 这里需要指出的就是此时HTTP方法将不再是put,更改为POST

 curl -XPOST 'http://localhost:9200/twitter/tweet/' -d '{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}'

返回的结果如下:

{
    "_index" : "twitter",
    "_type" : "tweet",
    "_id" : "6a8ca01c-7896-48e9-81cc-9f70661fcb32",
    "_version" : 1,
    "created" : true
}

路由routing

所有的文档API(get、index、delete、bulk、update、mget)都接收一个routing参数,它用来自定义文档到分片的映射。自定义路由值可以确保所有相关文档都被保存在同一分片上。

shard = hash(routing) % number_of_primary_shards

设置了路由值,就相当于告诉ES文档操作针对的具体分片。 一般情况下ID都是随机生成的,这样可以保证默认情况下分片的数据负载是相同的,如果我们需要在特定的分片上保持特定的内容,就需要用到这个属性。

Parent & Children父子查询

这个属性在父子连接中用到,类似于传统关系中的一对多关系,具体的介绍在连接查询mapping模块中介绍

curl -XPUT localhost:9200/blogs/blog_tag/1122?parent=1111 -d '{
    "tag" : "something"
}'

当索引一个child文档时,这个routing属性值被自动的设置成指定的parent文档相同的routing,除非指定routing值(即使parent指定routing,child文档还是parent文档的ID)

_timestamp设置时间戳

这个字段将被date字段替代,且在使用的时候(包括自定义timestamp),必须mapping设置为enable

{
  "mappings": {
    "my_type": {
      "_timestamp": {
        "enabled": true
      }
    }
  }
}

时间戳字段可以在索引的时候指定:

curl -XPUT localhost:9200/twitter/tweet/1?timestamp=2009-11-15T14%3A12%3A12 -d '{
    "user" : "kimchy",
    "message" : "trying out Elasticsearch"
}'

如果没有指定timestamp,_source中也不存在时间戳,就会指定为索引指定时间。

#测试timestamp
PUT /my_index
{
  "mappings": {
    "my_type": {
      "_timestamp": {
        "enabled": true
      }
    }
  }
}


GET my_index/_mapping
#回应如下
{
  "my_index": {
    "mappings": {
      "my_type": {
        "_timestamp": {
          "enabled": true
        }
      }
    }
  }
}

#索引数据
PUT /my_index/my_type/1?pretty
{
  "meas" : "timestamp测试"
}


GET /my_index/my_type/1
#回应如下
{
  "_index": "my_index",
  "_type": "my_type",
  "_id": "1",
  "_version": 2,
  "_timestamp": 1464418352065,
  "found": true,
  "_source": {
    "meas": "timestamp测试"
  }
}


#自定义timestamp
PUT /my_index3/my_type/1?timestamp=2019-12-12T14%3A12%3A23
{
  "message" : "自定义timestamp测试"
}


GET my_index3/my_type/1
#回应如下
{
  "_index": "my_index3",
  "_type": "my_type",
  "_id": "1",
  "_version": 3,
  "_timestamp": 1576159943000,
  "found": true,
  "_source": {
    "message": "自定义timestamp测试"
  }
}

ttl文档过期

ES中也可以设置文档自动过期,过期是设置一个正的时间间隔,然后以_timestamp为基准,一旦_ttl到0的时候,文档就会被自动删除。

如果想_ttl生效,必须mapping设置_timestamp和_ttl为enable

PUT my_index5
{
  "mappings": {
    "my_type" : {
      "_ttl": {
        "enabled": true
      },
      "_timestamp": {
        "enabled": true
      }
    }
  }
}

这时就可以使用_ttl删除文档了

PUT /my_index5/my_type/1?ttl=2m
{
  "user" : "kimchy",
  "post_date" : "2016-05-21T17:23:00",
  "messae" : "trying out Elasticsearch"
}

GET /my_index5/my_type/1
#回应如下
{
  "_index": "my_index5",
  "_type": "my_type",
  "_id": "1",
  "_version": 1,
  "_ttl": 78225,
  "_timestamp": 1464420120972,
  "found": true,
  "_source": {
    "user": "kimchy",
    "post_date": "2016-05-21T17:23:00",
    "messae": "trying out Elasticsearch"
  }
}

refersh手动刷新

由于ES并不是一个实时索引搜索的框架,因此数据在索引操作后,需要等1秒钟才能搜索到。这里的搜索是指进行检索操作。如果你使用的是get这种API,就是真正的实时操作了。他们之间的不同是,检索可能还需要进行分析和计算分值相关性排序等操作。 为了在数据索引操作后,马上就能搜索到,也可以手动执行refresh操作。只要在API后面添加refresh=true即可。 这种操作仅推荐在特殊情况下使用,如果在大量所以操作中,每个操作都执行refresh,那是很耗费性能的。 这一步是把缓冲区的请求数据刷到文件系统缓存上。

Timeout超时

分片并不是随时可用的,当分片进行备份等操作时,是不能进行索引操作的。因此需要等待分片可用后,再进行操作。这时,就会出现一定的等待时间,如果超过等地时间则返回并抛出错误,这个等待时间可以通过timeout设置:

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

table{ text-align: center; }

参数

可选值

备注

op_type

create

索引不存在就创建,存在报错

version

自定义值

用于指定版本号

version_type

internalexternal

定义外部版本

routing

parent

timestamp

ttl

consistency

onequorumall

refresh

--

timeout

针对index api暂时就先介绍到这,还有许多细节以后再慢慢补充。

参考文档

【1】官方Index API文档 【2】权威指南 索引

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python爬虫(二十三)_selenium案例:动态模拟页面点击

    本篇主要介绍使用selenium模拟点击下一页,更多内容请参考:Python学习指南 #-*- coding:utf-8 -*- import unit...

    用户1174963
  • Scala入门学习笔记三--数组使用

    前言 本篇主要讲Scala的Array、BufferArray、List,更多教程请参考:Scala教程 本篇知识点概括 若长度固定则使用Array,若...

    用户1174963
  • Python爬虫(十九)_动态HTML介绍

    JavaScript JavaScript是网络上最常用也是支持者对多的客户端脚本语言。它可以收集用户的跟踪数据,不需要重载页面直接提交表单,在页面嵌入多媒体文...

    用户1174963
  • 003.Ceph扩展集群

    需求:添加Ceph元数据服务器node1。然后添加Ceph Monitor和Ceph Manager node2,node3以提高可靠性和可用性。

    木二
  • Android使用剪切板传递数据

    在Activity之间传递数据还可以利用一些技巧,不管windows还是Linux操作系统,都会支持一种叫剪切板的技术,也就是某一个程序将一些数据复制到剪切板上...

    砸漏
  • 【iOS】修改checkra1n+chimera环境(chimera1n)

    这样海外和已经有系统全局代理设置的朋友们就可以直接使用 brew 命令安装软件了。

    zby1101
  • 触类旁通Elasticsearch:管理

    (1)创建模板 当待创建的索引与之前的索引有相同的设置和映射时,非常适合使用索引模板。正如其名,索引模板将会用于和预定义名称模式相匹配的索引创...

    用户1148526
  • Python自动化运维之高级函数

    一、协程 1.1 协程的概念 协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程。(其实并没有说明白~) 那么...

    小小科
  • Python自动化运维之高级函数

    协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程。(其实并没有说明白~) 那么这么来理解协程比较容易: 

    马哥linux运维
  • 【董天一】IPFS:Filecoin和复制证明

    这篇文章主要来讲一下Filecoin协议里面的复制证明(Proof of Replication),由于协议涉及到很多概念,可能看起来有点晕乎乎的,小编尽量把...

    圆方圆学院

扫码关注云+社区

领取腾讯云代金券