Elasticsearch 同一索引不同類型下同名字段的映射沖突實(shí)例
來(lái)源:易賢網(wǎng) 閱讀:3957 次 日期:2015-04-09 15:58:34
溫馨提示:易賢網(wǎng)小編為您整理了“Elasticsearch 同一索引不同類型下同名字段的映射沖突實(shí)例”,方便廣大網(wǎng)友查閱!

這個(gè)標(biāo)題肯定繞暈很多人吧。具體說(shuō)明一下場(chǎng)景就明白了:Nginx 和 Apache 的訪問(wèn)日志,因?yàn)槎紝儆诰W(wǎng)站訪問(wèn),所以寫(xiě)入到同一個(gè)索引的不同類型下,比方 logstash-accesslog-2015.04.03/nginx 和 logstash-accesslog-2015.04.03/apache。既然都是訪問(wèn)日志,肯定很多字段的內(nèi)容含義是雷同的,比如 clientip, domain, urlpath 等等。其中 nginx 有一個(gè)變量叫 $request_time,apache 有一個(gè)變量叫 %T,乍看上去也是同義的,我就統(tǒng)一命名為 “requestTime” 了。這就是”同一索引(logstash-accesslog-YYYY.MM.DD)下不同類型(nginx,apache)的同名字段(requestTime)”。

但事實(shí)上,這里有個(gè)問(wèn)題:nginx 中的以秒為單位,是把毫秒算作小數(shù);apache 中的以秒為單位,是真的只記秒鐘整數(shù)位!

所以,這兩個(gè)類型生成的映射在這個(gè)字段上是不一致的。nginx 類型的 requestTime 是 double,apache 類型的 requestTime 是 long。

不過(guò)平常看起來(lái)似乎也沒(méi)什么影響,寫(xiě)入數(shù)據(jù)都照常,查看數(shù)據(jù)的時(shí)候默認(rèn)顯示的 JSON 也各自無(wú)異。直到我準(zhǔn)備用一把 scripted field 的時(shí)候,發(fā)現(xiàn)計(jì)算 doc['requestTime'].value * 1000 得到的數(shù)都大的嚇人!

因?yàn)轭愃朴?jì)算之前在只有 nginx 日志入庫(kù)的時(shí)候曾經(jīng)正確運(yùn)行過(guò),所以只能是猜測(cè) apache 日志對(duì)此造成了影響,但是即使我把請(qǐng)求修改成限定在 nginx 類型數(shù)據(jù)中進(jìn)行,結(jié)果也沒(méi)發(fā)生變化。

仔細(xì)閱讀 scripting module 的文檔,其中提到了 doc['fieldname'].value 和 _source.fieldname 兩種寫(xiě)法的區(qū)別:前者會(huì)利用內(nèi)存中的數(shù)據(jù),而后者強(qiáng)制讀取磁盤上 _source 存儲(chǔ)的 JSON 內(nèi)容,從中釋放出相應(yīng)字段內(nèi)容。莫非是 requestTime 字段跟 _source JSON 里存的數(shù)據(jù)確實(shí)不一樣,而我們平常搜索查看的都是從 JSON 里釋放出來(lái)的,所以才會(huì)如此?

為了驗(yàn)證我的猜測(cè),做了一個(gè)請(qǐng)求測(cè)試:

# curl es.domain.com:9200/logstash-accesslog-2015.04.03/nginx/_search?q=_id:AUx-QvSBS-dhpiB8_1f1&pretty -d '{

"fields": ["requestTime", "bodySent"],

"script_fields" : {

"test1" : {

"script" : "doc["requestTime"].value"

},

"test3" : {

"script" : "_source.bodySent / _source.requestTime"

},

"test2" : {

"script" : "doc["requestTime"].value * 1000"

}

}

}'

得到的結(jié)果如下:

{

"took" : 43,

"timed_out" : false,

"_shards" : {

"total" : 56,

"successful" : 56,

"failed" : 0

},

"hits" : {

"total" : 1,

"max_score" : 1.0,

"hits" : [ {

"_index" : "logstash-accesslog-2015.04.03",

"_type" : "nginx",

"_id" : "AUx-QvSBS-dhpiB8_1f1",

"_score" : 1.0,

"fields" : {

"test1" : [ 4603039107142836552 ],

"test2" : [ -8646911284551352000 ],

"requestTime" : [ 0.54 ],

"test3" : [ 2444.4444444444443 ],

"bodySent" : [ 1320 ]

}

} ]

}

}

果然!直接讀取的字段,以及采用 _source.fieldname 方式讀取的內(nèi)容,都是正確的;而采用 doc['fieldname'].value 獲取的內(nèi)存數(shù)據(jù),就不對(duì)。(0.54 存成 long 型會(huì)變成 4603039107142836552。這個(gè) 460 還正好能跟 540 湊成 1000,應(yīng)該是某種特定存法,不過(guò)這里我就沒(méi)深究了)

再作下一步驗(yàn)證。我們知道,ES 數(shù)據(jù)的映射是根據(jù)第一條數(shù)據(jù)的類型確定的,之后的數(shù)據(jù)如何類型跟已經(jīng)成型的映射不統(tǒng)一,那么寫(xiě)入會(huì)失敗?,F(xiàn)在這個(gè) nginx 和 apache 兩個(gè)類型在 requestTime 字段上的映射是不一樣的,但是內(nèi)存里卻并沒(méi)有按照映射來(lái)處理。那么,我往一個(gè)類型下寫(xiě)入另一個(gè)類型映射要求的數(shù)據(jù),會(huì)報(bào)錯(cuò)還是會(huì)通過(guò)呢?

# curl -XPOST es.domain.com:9200/test/t1/1 -d '{"key":1}'

{"_index":"test","_type":"t1","_id":"1","_version":1,"created":true}

# curl -XPOST es.domain.com:9200/test/t2/1 -d '{"key":2.2}'

{"_index":"test","_type":"t2","_id":"1","_version":1,"created":true}

# curl -XPOST es.domain.com:9200/test/t1/2 -d '{"key":2.2}'

{"_index":"test","_type":"t1","_id":"2","_version":1,"created":true}

# curl -XPOST es.domain.com:9200/test/t2/2 -d '{"key":1}'

{"_index":"test","_type":"t2","_id":"2","_version":1,"created":true}

# curl -XPOST es.domain.com:9200/test/t1/3 -d '{"key":"1"}'

{"_index":"test","_type":"t1","_id":"3","_version":1,"created":true}

# curl -XPOST es.domain.com:9200/test/t2/3 -d '{"key":"1"}'

{"_index":"test","_type":"t2","_id":"3","_version":1,"created":true}

# curl -XPOST es.domain.com:9200/test/t2/4 -d '{"key":"abc"}'

{"error":"RemoteTransportException[[10.10.10.10][inet[/10.10.10.10:9300]][indices:data/write/index]]; nested: MapperParsingException[failed to parse [key]]; nested: NumberFormatException[For input string: "abc"]; ","status":400}

# curl -XGET es.domain.com:9200/test/_mapping

{"test":{"mappings":{"t1":{"properties":{"key":{"type":"long"}}},"t2":{"properties":{"key":{"type":"double"}}}}}}

結(jié)果出來(lái)了,在映射相互沖突以后,實(shí)際數(shù)據(jù)只要是 numeric detect 能通過(guò)的,就都通過(guò)了!

BTW: kibana 4 中,已經(jīng)會(huì)對(duì)這種情況以黃色感嘆號(hào)圖標(biāo)做出提示;而根據(jù)官方消息,ES 未來(lái)會(huì)在 2.0 版正式杜絕這種可能。

更多信息請(qǐng)查看IT技術(shù)專欄

更多信息請(qǐng)查看技術(shù)文章
由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請(qǐng)考生以權(quán)威部門公布的正式信息和咨詢?yōu)闇?zhǔn)!

2025國(guó)考·省考課程試聽(tīng)報(bào)名

  • 報(bào)班類型
  • 姓名
  • 手機(jī)號(hào)
  • 驗(yàn)證碼
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡(jiǎn)要咨詢 | 簡(jiǎn)要咨詢須知 | 加入群交流 | 手機(jī)站點(diǎn) | 投訴建議
工業(yè)和信息化部備案號(hào):滇ICP備2023014141號(hào)-1 云南省教育廳備案號(hào):云教ICP備0901021 滇公網(wǎng)安備53010202001879號(hào) 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號(hào)
云南網(wǎng)警備案專用圖標(biāo)
聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號(hào):hfpxwx
咨詢QQ:526150442(9:00—18:00)版權(quán)所有:易賢網(wǎng)
云南網(wǎng)警報(bào)警專用圖標(biāo)