使用elasticsearch存儲訂單的主要信息,document內的field,基本上是long或keyword,建立索引的order.json文件以下:java
{ "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 } } } }
某天發現有個查詢功能(單獨使用payment字段查詢)沒有數據出來,最近未修改此部分代碼。對比研發環境,研發環境是正常的,一樣的代碼在測試環境下無數據返回。json
QueryBuilders.termQuery("payment", req.getFilter().getOrder().getPayment())
在kibana上用命令診斷查詢數據,一樣沒有結果返回,查詢命令以下:架構
GET /order/doc/_search { "query": { "bool": { "must": [ {"term": { "payment": "Alipay" }} ] } } }
GET /order/_mapping/doc
併發
響應返回(只展現payment字段):app
{ "order": { "mappings": { "doc": { "properties": { "payment": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } } } }
按照mapping返回結果來看,字段payment原定義的類型是keyword,如今變成text了,這個是payment字段使用termQuery查詢致使沒有數據的緣由。elasticsearch
keyword對保存的內容不分詞,也不改變大小寫,原樣存儲,默承認索引。 text對內容進行分詞,而且所有小寫存儲,同時會增長一個text.keyword字段,爲keyword類型,超過256字符後不索引。分佈式
因爲payment字段變成text了,原有的程序使用term查詢,用的"Alipay",而text存儲的是"alipay",因此查不到數據了。高併發
GET /order/doc/_search { "query": { "bool": { "must": [ {"term": { "payment": "alipay" }} ] } } }
GET /order/doc/_search { "query": { "bool": { "must": [ { "match": { "payment": "alipay" } } ] } } }
查詢有數據輸出,而且符合預期,嘗試方法有效。測試
明明order.json的對payment字段定義的類型是keyword,怎麼變成text了?ui
因爲出現此問題的環境是測試環境,有重刪索引數據,而後再所有導入的操做(有點不規範,但僅限於測試環境,生產環境不會這麼作),從新導入索引document數據的功能,es建立索引自動mapping時,payment字段的string內容,會變成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.觸發程序灌數據(也能夠用bulk)
問題雖小,但必定要追溯源頭,好比這次測試環境的不規範操做。後期若是有刪除索引的操做,應該先手動創建索引後,再灌數據,而不是直接讓其自動mapping創建索引,自動mapping創建的字段類型,可能不是咱們指望的。
專一Java高併發、分佈式架構,更多技術乾貨分享與心得,請關注公衆號:Java架構社區