场景:索引加了新字段,以前的的文档没有此字段,所以需要把旧文档的数据补充
1、ES6.3
POST 索引/_update_by_query?conflicts=proceed
{
"script": {
"source": "ctx._source['查询的字段']='符合查询的字段的值';"
},
"query": {
"term": {
"需要修改的字段": "修改值"
}
}
}
上面conflicts=proceed
代表如果你想计算有多少个版本冲突,而不是中止,可以在URL中设置为conflicts=proceed或者在请求体中设置"conflicts": “proceed”,还有很多关键字,可以去官网查看Update By Query API
支持script 自定义的方式,这样查询查询条件自由很多。
2、遇到的问题
公司的这个索引因为每天的数据量很大,所以我们按天建的索引,在仪表盘上有统计的报表,但是新加的这个的字段的报表如果时间跨度有今天以前的则会报一个异常,说分片失败,看了返回的异常,是下面这个
"reason": "Fielddata is disabled on text fields by default. Set fielddata=true on [字段] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead."
出现上面的原因是下面这个
"新字段": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
因为今天的索引我把新字段加上了,以前的那些索引没有加,但是补充数据把以前的索引都加上了,又因为没有字段提前定义,所以是数据在旧索引的格式就是上面这种,不能直接用于仪表盘,因为不用关键字或者fielddata的话ES会把text的数据放在磁盘上,
就像上面给你返回的异常信息一样,现在有两种选择:
- 采用新的关键字,来补充数据,在补充数据之前预定义好字段的类型,
- 在索引字段上启用fielddata
到底采用什么可以看一下采用fielddata还是新关键字的优缺点官方说明
最后我们决定用新关键字解决,
当然第二种方案也给出
PUT index/_mapping/type
{
"your_type": {
"properties": {
"字段名": {
"type": "text",
"fielddata": true
}
}
}
}
3、总结
旧索引补充新加字段数据时,一定先查看旧索引中是否有此字段,预定义了吗!!! 必须一定要预定义!!!