Go Elasticsearch index CRUD

Posted 恋喵大鲤鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go Elasticsearch index CRUD相关的知识,希望对你有一定的参考价值。

文章目录

1.简介

Elasticsearch 的索引(index)是文档(document)的集合,类似 mysql 的表。文档是 ES 中存储的一条 JSON 格式的数据。

index 是一个逻辑空间的概念,index 中的文档会分散放在不同的 shard 中,而 shard 在 ES 中则是个物理空间的概念。

index 由以下几个部份组成:

  • data:由 document + metadata 所組成;
  • mapping:用来定义文档结构,如字段名称 & 类型;
  • setting:定义数据是如何存放,如 shard 和 replica 数量。

下面设计一个 index 用来描述我们要存储的用户信息,index 也用一个 JSON 串来表示。

index = `
	"mappings":
		"dynamic": "strict",
		"properties":
			"id": 				 "type": "long" ,
			"username": 		 "type": "keyword" ,
			"nickname":			 "type": "text" ,
			"phone":			 "type": "keyword" ,
			"age":				 "type": "long" ,
			"ancestral":		 "type": "text" ,
			"identity":          "type": "text" ,
			"update_time":		 "type": "long" ,
			"create_time":		 "type": "long" 
		
	,
	"settings" : 
      "index" : 
        "number_of_shards" : "1",
        "number_of_replicas" : "1"
      
    
`

mapping 的 dynamic 属性控制类型,将 mapping 分为如下三类:

  • 动态映射(dynamic mapping)

dynamic 为 true。添加的文档中如果有新增的字段,则 ES 会自动把新的字段添加到映射中。

  • 静态(显式)映射(explicit mapping)

dynamic 为 false。当 ES 察觉到有新增字段时,会忽略该字段,但是仍会存储该字段。在有些情况下,静态映射依然不够,所以还需要更严谨的策略来进一步做限制。

  • 精确(严格)映射(strict mapping)

dynamic 为 strict,表示字段需要严格匹配,新增字段写入将会报错。

一般静态映射用的较多。就像 html 的 img 标签一样,src 为自带的属性,你可以在需要的时候添加 id 或者 class 属性。当然,如果你非常非常了解你的数据,并且未来很长一段时间不会改变,strict 不失为一个好选择。

2.增加

设计好了 index 及 mapping 后,我们开始编写代码进行创建。

// ESIndexExists 索引是否存在
func ESIndexExists(ctx context.Context, index string) (bool, error) 
	return GetESClient().IndexExists(index).Do(ctx)


// CrtESIndex 创建 ES 索引
func CrtESIndex(ctx context.Context, index, desc string) error 
	exist, err := ESIndexExists(ctx, index)
	if err != nil 
		return err
	
	// 已经创建
	if exist 
		return nil
	
	// 重复创建会报错
	_, err = GetESClient().CreateIndex(index).BodyString(desc).Do(ctx)
	return err

因为重复创建 index,ES 会报错,所以创建前先判断一下是否已经创建。

创建成功后,我们在 Kibana 上通过 Restful API 可以查看到刚刚创建的 index。

GET /es_index_userinfo


  "es_index_userinfo" : 
    "aliases" :  ,
    "mappings" : 
      "dynamic" : "strict",
      "properties" : 
        "age" : 
          "type" : "long"
        ,
        "ancestral" : 
          "type" : "text"
        ,
        "create_time" : 
          "type" : "long"
        ,
        "id" : 
          "type" : "long"
        ,
        "nickname" : 
          "type" : "text"
        ,
        "phone" : 
          "type" : "keyword"
        ,
        "update_time" : 
          "type" : "long"
        ,
        "username" : 
          "type" : "keyword"
        
      
    ,
    "settings" : 
      "index" : 
        "creation_date" : "1627546052453",
        "number_of_shards" : "1",
        "number_of_replicas" : "1",
        "uuid" : "_FIlQz-uQD2ynzITVPFpRw",
        "version" : 
          "created" : "7070099"
        ,
        "provided_name" : "es_index_userinfo"
      
    
  

其中 number_of_shards 为主分片数,缺省为 1,只能在创建索引时指定,后期无法修改。number_of_replicas 是指每个分片有多少个副本,后期可以动态修改。

对应的 RESTful API 为:

PUT /es_index_userinfo

  "mappings":
		"dynamic": "strict",
		"properties":
			"id": 				 "type": "long" ,
			"username": 		 "type": "keyword" ,
			"nickname":			 "type": "text" ,
			"phone":			 "type": "keyword" ,
			"age":				 "type": "long" ,
			"ancestral":		 "type": "text" ,
			"update_time":		 "type": "long" ,
			"create_time":		 "type": "long" 
		
	

2.删除

通过 RESTful API 删除 index 很简单,格式如下:

DELETE /<index>

比如删除上面创建的 es_index_userinfo。

DELETE /es_index_userinfo

3.修改

对于一个已经存在的 index,我们可以修改 index 的相关设置。

3.1 更新 mapping

3.1.1 增加字段

比如修改文档结构,即修改 index 的 mapping,我们想其中再增加一个字段爱好 hobby。

PUT /es_index_userinfo/_mapping

  "properties": 
    "hobby": 
      "type":"text"
    
  

3.1.2 删除字段

ES 中已经添加成功的字段是没法直接删除的,因为这会导致数据不可用。我们可以通过间接的方式来完成字段的删除。操作步骤如下:
(1)创建一个新的 index,不包含要删除的字段;
(2)删除原 index 中待删除字段的数据。只删除数据,不删除字段。因为如果不清空字段值的话,在下面的 reindex 会出现问题,如果新 index 的 mapping 的 dynamic 属性为 strict,会出错。

POST es_index_userinfo/_update_by_query

    "script" : "ctx._source.remove('hobby')",
    "query": 
        "match_all": 
    

(3)通过 redindex 将数据拷贝至新的 index;

POST /_reindex

  "source": 
    "index": "my-index"
  ,
  "dest": 
    "index": "my-new-index"
  

(4)删除旧的 index;
(5)给新 index 添加别名,别名是旧 index。

POST <target>/_alias/<alias>

注意:完成第四步后,才能进行第五步的操作,期间会导致依赖该 index 的服务短暂不可用,所以尽量在业务低峰时间段操作。最安全的做法,是完成上面前三部操作后,将服务通过配置的方式把使用的 index 切换到新的 index。再进行后面的两步操作。

3.2 重命名 index

ES 中不能直接重命名 index,因为这会造成旧 index 不可用。我们可以给 index 添加别名,达到重命名的效果。

POST <target>/_alias/<alias>

4.查询

查询一个 index 也很简单,接口调用格式如下:

GET /<index>

5.小结

本文只是简单的介绍了 index 的概念,组成和相关操作,关于 index 和 mapping 的更多操作,请参考官方文档 Elasticsearch Guide [8.0] » REST APIs » Index APIs


参考文献

Elasticsearch Guide [8.0] » REST APIs » Index APIs
Elasticsearch - mappings之dynamic的三种状态
简书.es删除字段

以上是关于Go Elasticsearch index CRUD的主要内容,如果未能解决你的问题,请参考以下文章

Go Elasticsearch 增加快速入门

Go Elasticsearch 更新快速入门

Go Elasticsearch 更新快速入门

Go Elasticsearch 删除快速入门

Go Elasticsearch 删除快速入门

Go Elasticsearch CRUD 快速入门