新聞中心
1、背景
在我們使用es的開發(fā)過程中可能會(huì)遇到這么一種情況,比如我們的線路名稱字段lineName字段在設(shè)置mapping的時(shí)候使用的是text類型,但是后期發(fā)現(xiàn)需要使用這個(gè)字段來進(jìn)行聚合操作,那么我們除了對(duì)索引進(jìn)行reindex操作外,還有什么辦法可以解決這個(gè)問題呢?此處我們通過runtime field來解決。

我們提供的服務(wù)有:網(wǎng)站設(shè)計(jì)、做網(wǎng)站、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、庫(kù)爾勒ssl等。為1000多家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的庫(kù)爾勒網(wǎng)站制作公司
2、runtime field介紹
2.1 runtime field可以實(shí)現(xiàn)的功能
運(yùn)行時(shí)字段是在查詢時(shí)評(píng)估的字段。是在es7.11之后增加的運(yùn)行時(shí)字段使您能夠:
- 將字段添加到現(xiàn)有文檔,而無需重新索引數(shù)據(jù)
- 在不了解數(shù)據(jù)結(jié)構(gòu)的情況下開始處理數(shù)據(jù)
- 在查詢時(shí)覆蓋從索引字段返回的值
- 定義特定用途的字段,而不修改原始mappingruntime field 的作用
2.2 runtime field優(yōu)缺點(diǎn)
- runtime field是運(yùn)行時(shí)增加的字段,不會(huì)被索引和存儲(chǔ),不會(huì)增加索引的大小。
- runtime field 可以像普通字段一樣使用,可以進(jìn)行查詢,排序,聚合等操作。
- 可以動(dòng)態(tài)的添加字段。
- 可以在查詢時(shí)覆蓋字段的值。即fields中和_source中可以返回同名的字段,但是值可能不一樣。
- 阻止mapping爆炸,可以先使用后定義。
- 針對(duì)經(jīng)常被搜索或聚合等操作的字段,不適合使用runtime field,而應(yīng)該定義在mapping中。
- runtime field不會(huì)出現(xiàn)在_source中,需要通過fields api來獲取。
3、創(chuàng)建runtime field的方式
3.1 通過mapping的方式創(chuàng)建
3.1.1、添加runtime field
PUT /index_script_fields
{
"mappings": {
"runtime": {
"aggLineName": {
"type": "keyword",
"script": {
"source": "emit(doc['lineName'].value)"
}
}
},
"properties": {
"lineId": {
"type": "keyword"
},
"lineName": {
"type": "text"
}
}
}
}
3.1.2、更新 runtime field
POST /index_script_fields/_mapping
{
"runtime": {
"aggLineName": {
"type": "keyword",
"script": {
"source": "emit(doc['lineName'].value)"
}
}
}
}
3.1.3、刪除runtime field
POST /index_script_fields/_mapping
{
"runtime": {
"aggLineName": null
}
}
3.2 通過search request定義runtime field
GET /index_script_fields/_search
{
"runtime_mappings": {
"lineName": {
"type": "keyword",
"script": "emit(params['_source']['lineName']+'new')"
}
},
"query": {
"match_all": {}
},
"fields": [
"lineName"
]
}
通過search request定義runtime field
4、需求
我們存在一個(gè)線路mapping,其中l(wèi)ineName在設(shè)計(jì)的使用使用了text類型,現(xiàn)在我們需要根據(jù)這個(gè)字段來進(jìn)行聚合操作,那么使用runtime field該如何操作呢?
5、實(shí)現(xiàn)
5.1 mapping
PUT /index_script_fields
{
"mappings": {
"properties": {
"lineId": {
"type": "keyword"
},
"lineName": {
"type": "text"
}
}
}
}
注意此時(shí)的lineName的類型是text
5.2 插入數(shù)據(jù)
PUT /index_script_fields/_bulk
{"index":{"_id":1}}
{"lineId":"line-01","lineName":"線路A"}
{"index":{"_id":2}}
{"lineId":"line-01","lineName":"線路A"}
{"index":{"_id":3}}
{"lineId":"line-02","lineName":"線路C"}
5.3、根據(jù)線路來進(jìn)行聚合
從上方的mapping中可以lineName是text類型,是不可進(jìn)行聚合操作的,那么此時(shí)我們想進(jìn)行聚合操作,就可以使用runtime field來實(shí)現(xiàn)。
5.3.1 不使用runtime field
不使用runtime field
5.3.2 使用runtime field
5.3.2.1 dsl
GET /index_script_fields/_search
{
"runtime_mappings": {
"aggLineName": {
"type": "keyword",
"script": "emit(params['_source']['lineName']+'new')"
}
},
"query": {
"match_all": {}
},
"fields": [
"lineName"
],
"aggs": {
"agg_line_name": {
"terms": {
"field": "aggLineName",
"size": 10
}
}
}
}
5.3.2.2 java代碼
@Test
@DisplayName("lineName字段是text類型,無法進(jìn)行聚合操作,定義一個(gè)runtime field來進(jìn)行聚合操作")
public void test01() throws IOException {
SearchRequest request = SearchRequest.of(searchRequest ->
searchRequest.index(INDEX_NAME)
// 查詢所有數(shù)據(jù)
.query(query -> query.matchAll(matchAll -> matchAll))
// runtime field字段不會(huì)出現(xiàn)在 _source中,需要使用使用 fields api來獲取
.fields(fields -> fields.field("lineName"))
// 創(chuàng)建一個(gè) runtime filed 字段類型是 keyword
.runtimeMappings("aggLineName", runtime ->
runtime
// 此處給字段類型為keyword
.type(RuntimeFieldType.Keyword)
.script(script ->
script.inline(inline ->
// runtime field中如果使用 painless腳本語言,需要使用emit
inline.lang(ScriptLanguage.Painless)
.source("emit(params['_source']['lineName']+'new')")
)
)
)
// 進(jìn)行聚合操作
.aggregations("agg_line_name", agg ->
// 此處的 aggLineName即為上一步runtime field的字段
agg.terms(terms -> terms.field("aggLineName").size(10))
)
.size(100)
);
System.out.println("request: " + request);
SearchResponse
5.3.3.3 運(yùn)行結(jié)果
聚合
6、完整代碼
https://gitee.com/huan1993/spring-cloud-parent/blob/master/es/es8-api/src/main/java/com/huan/es8/runtimefield/RuntimeFieldCorrectMappingError.java
7、參考鏈接
1、https://www.elastic.co/guide/en/elasticsearch/reference/8.6/runtime.html?
當(dāng)前文章:Elasticsearch中使用RuntimeFields
轉(zhuǎn)載來源:http://fisionsoft.com.cn/article/dpdeoie.html


咨詢
建站咨詢
