基本環(huán)境
- elasticsearch版本:6.3.1
- 客戶端環(huán)境:kibana 6.3.4、Java8應(yīng)用程序模塊。
其中kibana主要用于數(shù)據(jù)查詢?cè)\斷和查閱日志,Java8為主要的客戶端,數(shù)據(jù)插入和查詢都是由Java實(shí)現(xiàn)的。
案例介紹
使用elasticsearch存儲(chǔ)訂單的主要信息,document內(nèi)的field,基本上是long或keyword,創(chuàng)建索引的order.json文件如下:
{
"doc": {
"properties": {
"id": {
"type": "keyword",
"index": true
},
"status": {
"type": "byte",
"index": true
},
"createTime": {
"type": "long",
"index": true
},
"uid": {
"type": "long",
"index": true
},
"payment": {
"type": "keyword",
"index": true
},
"commentStatus": {
"type": "byte",
"index": true
},
"refundStatus": {
"type": "byte",
"index": true
}
}
}
}
某天發(fā)現(xiàn)有個(gè)查詢功能(單獨(dú)使用payment字段查詢)沒(méi)有數(shù)據(jù)出來(lái),最近未修改此部分代碼。對(duì)比研發(fā)環(huán)境,研發(fā)環(huán)境是正常的,同樣的代碼在測(cè)試環(huán)境下無(wú)數(shù)據(jù)返回。
問(wèn)題定位
QueryBuilders.termQuery("payment", req.getFilter().getOrder().getPayment())
在kibana上用命令診斷查詢數(shù)據(jù),同樣沒(méi)有結(jié)果返回,查詢命令如下:
GET /order/doc/_search
{
"query": {
"bool": {
"must": [
{"term": {
"payment": "Alipay"
}}
]
}
}
}
GET /order/_mapping/doc
響應(yīng)返回(只展示payment字段):
{
"order": {
"mappings": {
"doc": {
"properties": {
"payment": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
}
問(wèn)題原因
按照mapping返回結(jié)果來(lái)看,字段payment原定義的類型是keyword,現(xiàn)在變成text了,這個(gè)是payment字段使用termQuery查詢導(dǎo)致沒(méi)有數(shù)據(jù)的原因。
text與keyword的區(qū)別
keyword對(duì)保存的內(nèi)容不分詞,也不改變大小寫(xiě),原樣存儲(chǔ),默認(rèn)可索引。
text對(duì)內(nèi)容進(jìn)行分詞,并且全部小寫(xiě)存儲(chǔ),同時(shí)會(huì)增加一個(gè)text.keyword字段,為keyword類型,超過(guò)256字符后不索引。
由于payment字段變成text了,原有的程序使用term查詢,用的"Alipay",而text存儲(chǔ)的是"alipay",所以查不到數(shù)據(jù)了。
嘗試排錯(cuò)方法
GET /order/doc/_search
{
"query": {
"bool": {
"must": [
{"term": {
"payment": "alipay"
}}
]
}
}
}
GET /order/doc/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"payment": "alipay"
}
}
]
}
}
}
查詢有數(shù)據(jù)輸出,并且符合預(yù)期,嘗試方法有效。
問(wèn)題追溯
明明order.json的對(duì)payment字段定義的類型是keyword,怎么變成text了?
由于出現(xiàn)此問(wèn)題的環(huán)境是測(cè)試環(huán)境,有重刪索引數(shù)據(jù),然后再全部導(dǎo)入的操作(有點(diǎn)不規(guī)范,但僅限于測(cè)試環(huán)境,生產(chǎn)環(huán)境不會(huì)這么做),重新導(dǎo)入索引document數(shù)據(jù)的功能,es創(chuàng)建索引自動(dòng)mapping時(shí),payment字段的string內(nèi)容,會(huì)變成text。
解決辦法:
1.刪除索引
DELETE /order
2.按照order.json重建索引
PUT /order
{
"mappings": {
"doc": {
"properties": {
"id": {
"type": "keyword",
"index": true
},
"status": {
"type": "byte",
"index": true
},
"createTime": {
"type": "long",
"index": true
},
"uid": {
"type": "long",
"index": true
},
"payment": {
"type": "keyword",
"index": true
},
"commentStatus": {
"type": "byte",
"index": true
},
"refundStatus": {
"type": "byte",
"index": true
}
}
}
}
}
3.觸發(fā)程序灌數(shù)據(jù)(也可以用bulk)
小結(jié)
問(wèn)題雖小,但一定要追溯源頭,比如此次測(cè)試環(huán)境的不規(guī)范操作。后期如果有刪除索引的操作,應(yīng)該先手動(dòng)建立索引后,再灌數(shù)據(jù),而不是直接讓其自動(dòng)mapping建立索引,自動(dòng)mapping建立的字段類型,可能不是我們期望的。
|