Elasticsearch 基于不可修改field的重建索引

本文介绍当Elasticsearch中的字段类型需要变更时,如何通过创建新索引、使用scroll API进行批量数据迁移的方法实现索引重构,确保应用平滑过渡。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Elasticsearch 基于不可修改field的重建索引

重建索引原因分析

一个 field 的设置是不能修改的,如果要修改一个 field,那么应该重新按照新的mapping,建立一个index,然后将数据批量查询出来,重新用 bulk api 写入到新的index中。

批量查询的时候,建议采用scroll api,并且采用多线程并发的方式来reindex数据,每次scroll就查询指定日期扽一段数据,交给一个线程即可。

重建索引

# 创建一个索引并写入一条数据,根据数据动态建立mapping,content类型设为date
PUT /index1/type1/4
{
	"content": "1990-12-12"
}

# 查询数据
GET /index1/type1/_search
# 查看mapping
GET /index1/type1/_mapping

# 下面的PUT报错,因为前面的写入,动态设定了mapping中content被设定为date类型
PUT /index1/type1/4
{
	"content": "I am very happy."
}

# 修改content的类型为string,报错,mapping一旦设定将不能修改
PUT /index1/_mapping/type1
{
	"properties": {
		"content": {
			"type": "text"
		}
	}
}

# 通过下面的方案,解决上面的问题
# 创建一个新的索引,把index1索引中数据查询出来导入到新的索引中
# 但是应用程序使用的是之前的索引,为了不用重启应用程序,给index1这个索引起个别名
PUT /index1/_alias/index2

# 创建新的索引,把content的类型改为字符串
PUT /newindex
{
	"mappings": {
		"type1": {
			"properties": {
				"content": {
					"type": "text"
				}
			}
		}
	}
}

# 使用scroll批量查询
GET /index1/type1/_search?scroll=1m
{
	"query": {
		"match_all": {}
	},
	"sort": {
		"_doc"
	},
	"size": 2
}

# 使用bulk批量写入新的索引
POST /_bulk
{
	"index": {
		"_index": "newindex",
		"_type": "type1",
		"_id": 1
	}
}
{
	"content": "1990-12-12"
}

# 将别名index2和新索引关联,应用程序不用重启
POST /_aliases
{
	"actions": [
		{
			"remove": {
				"index": "index1",
				"alias": "index2"
			}
		},
		{
			"add": {
				"index": "newindex",
				"alias": "index2"
			}
		}
	]
}

GET index2/type2/_search
<think>好的,用户想了解如何在Elasticsearch中创建索引和映射。首先,我得回忆一下Elasticsearch的基本概念。索引类似于数据库中的表,而映射则定义了字段的类型和属性,这很重要,因为正确的映射能提高搜索效率和准确性。根据引用[1]中的内容,映射过程包括定义文档如何映射到搜索引擎,包括哪些字段可搜索以及如何处理它们。 接下来,创建索引的步骤。用户可能使用REST API或者客户端库,比如Java。需要说明两种方法。例如,使用PUT请求创建索引,可以指定设置如分片数和副本数。然后,映射的创建,可以在创建索引时定义,或者后续更新。但要注意,已有字段的映射不能修改,只能新增,这点需要强调,避免用户犯错。 然后,引用[4]中的代码示例展示了如何通过JSON构建映射,特别是添加分析器。这里要解释如何为字段指定分析器,比如英文分析器如何处理文本。同时,用户可能需要知道动态映射和显式映射的区别,动态映射虽然方便,但显式映射更可控。 用户可能遇到的问题包括如何更新映射,这时候需要说明索引只能新增字段,不能修改现有字段类型。另外,路由和别名也是相关话题,引用[3]提到使用别名管理不同类型的数据,这可能对索引设计有帮助。不过用户的问题主要集中在创建,所以这部分可以简要带过。 最后,确保步骤清晰,先创建索引,再定义映射,或者一步完成。给出具体的curl命令和Java代码示例,帮助用户实际操作。同时,注意LaTeX格式的要求,比如行内公式用$...$,但这里可能用不上,主要确保代码块和引用正确。</think>### 如何在Elasticsearch中创建索引和映射? #### 1. 创建索引 Elasticsearch通过`PUT`请求创建索引,可指定分片、副本等配置。 **示例(使用HTTP API)**: ```bash curl -XPUT "http://localhost:9200/my_index" -H 'Content-Type: application/json' -d' { "settings": { "number_of_shards": 3, "number_of_replicas": 1 } }' ``` 此命令创建名为`my_index`的索引,包含3个主分片和1个副本[^1]。 #### 2. 定义映射 映射定义字段的类型、分析器等属性。支持两种方式: **方式一:创建索引时定义映射** ```bash curl -XPUT "http://localhost:9200/my_index" -H 'Content-Type: application/json' -d' { "mappings": { "properties": { "title": { "type": "text", "analyzer": "english" }, "date": { "type": "date" }, "location": { "type": "geo_point" } } } }' ``` **方式二:更新现有索引映射** 通过`_mapping`端点添加新字段(已有字段无法修改)[^4]: ```bash curl -XPUT "http://localhost:9200/my_index/_mapping" -H 'Content-Type: application/json' -d' { "properties": { "new_field": { "type": "keyword" } } }' ``` #### 3. Java客户端实现(使用High Level REST Client) ```java CreateIndexRequest request = new CreateIndexRequest("my_index"); request.settings(Settings.builder() .put("index.number_of_shards", 3) .put("index.number_of_replicas", 1)); XContentBuilder mappingBuilder = XContentFactory.jsonBuilder() .startObject() .startObject("properties") .startObject("title") .field("type", "text") .field("analyzer", "english") .endObject() .endObject() .endObject(); request.mapping(mappingBuilder); CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT); ``` #### 关键注意事项 - 字段类型一旦定义不可修改,需通过重建索引实现 - 动态映射(Dynamic Mapping)可自动推断类型,但显式定义更可控 - 使用`analyzer`指定文本处理逻辑(如英文分词)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值