記一次ES查詢數據突然變為空的問題

来源:https://www.cnblogs.com/huangying2124/archive/2019/11/05/11796112.html

基本環境 elasticsearch版本:6.3.1 客戶端環境:kibana 6.3.4、Java8應用程式模塊。 其中kibana主要用於數據查詢診斷和查閱日誌,Java8為主要的客戶端,數據插入和查詢都是由Java實現的。 案例介紹 使用elasticsearch存儲訂單的主要信息,docum ...


基本環境

  • elasticsearch版本:6.3.1
  • 客戶端環境:kibana 6.3.4、Java8應用程式模塊。
    其中kibana主要用於數據查詢診斷和查閱日誌,Java8為主要的客戶端,數據插入和查詢都是由Java實現的。

案例介紹

使用elasticsearch存儲訂單的主要信息,document內的field,基本上是long或keyword,創建索引的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
      }
    }
  }
}

某天發現有個查詢功能(單獨使用payment欄位查詢)沒有數據出來,最近未修改此部分代碼。對比研發環境,研發環境是正常的,同樣的代碼在測試環境下無數據返回。

問題定位

  • 程式中使用該欄位用的是termQuery,如下:
QueryBuilders.termQuery("payment", req.getFilter().getOrder().getPayment())

在kibana上用命令診斷查詢數據,同樣沒有結果返回,查詢命令如下:

GET /order/doc/_search
{
  "query": {
    "bool": {
      "must": [
        {"term": {
          "payment": "Alipay"
        }}
      ]
    }
  }
}
  • 查詢mapping信息,看是否為keyword:

GET /order/_mapping/doc

響應返回(只展示payment欄位):

{
  "order": {
    "mappings": {
      "doc": {
        "properties": {
          "payment": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

問題原因

按照mapping返回結果來看,欄位payment原定義的類型是keyword,現在變成text了,這個是payment欄位使用termQuery查詢導致沒有數據的原因。

text與keyword的區別

keyword對保存的內容不分詞,也不改變大小寫,原樣存儲,預設可索引。
text對內容進行分詞,並且全部小寫存儲,同時會增加一個text.keyword欄位,為keyword類型,超過256字元後不索引。

由於payment欄位變成text了,原有的程式使用term查詢,用的"Alipay",而text存儲的是"alipay",所以查不到數據了。

嘗試排錯方法

  • payment的值改成小寫
GET /order/doc/_search
{
  "query": {
    "bool": {
      "must": [
        {"term": {
          "payment": "alipay"
        }}
      ]
    }
  }
}
  • 或將term查詢改成match查詢
GET /order/doc/_search
{
  "query": {
    "bool": {
      "must": [
        {
            "match": {
              "payment": "alipay"
            }
        }
      ]
    }
  }
}

查詢有數據輸出,並且符合預期,嘗試方法有效。

問題追溯

明明order.json的對payment欄位定義的類型是keyword,怎麼變成text了?

由於出現此問題的環境是測試環境,有重刪索引數據,然後再全部導入的操作(有點不規範,但僅限於測試環境,生產環境不會這麼做),重新導入索引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架構社區
Java架構社區


您的分享是我們最大的動力!

更多相關文章
  • 工作中偶爾會出現:想用A數據表替換B數據表,然後把B數據表刪除。但是,又不知道B數據表在哪個視圖、存儲過程、函數、觸發器中使用過? 經過一番度娘,看到實現方法也不難,主要涉及兩個系統表:sysobjects及syscomments。 1、先來複習一下sysobjects表結構。 列名 數據類型 描述 ...
  • MySQL DDL操作執行的三種方式 1,INPLACE,在進行DDL操作時,不影響表的讀&寫,可以正常執行表上的DML操作,避免與COPY方法相關的磁碟I/O和CPU周期,從而最小化資料庫的總體負載。 最小化負載有助於在DDL操作期間保持良好的性能和高吞吐量。 2,COPY,不允許併發執行過多個D ...
  • 在註冊表中找到 HKEY_CURRENT_USER\Software 選中其中的類似下列文件名的文件 HKEY_CURRENT_USER\Software\{d58cb4b1-47f3-45cb-a209-f298d0c3f756} HKEY_CURRENT_USER\Software\{FBC48 ...
  • 許多時候當要使用Mysql時,會遇到如下情況: 1. 信息比較重要,希望通信被加密。2. 一些埠,比如3306埠,被路由器禁用。 對第一個問題的一個比較直接的解決辦法就是更改mysql的代碼,或者是使用一些證書,不過這種辦法顯然不是很簡單。 這裡要介紹另外一種方法,就是利用SSH通道來連接遠程的 ...
  • [[email protected] ~]# /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql_data1 /usr/local/mysql/bin/my ...
  • 創建表空間及用戶CREATE TABLESPACE OracleDBFDATAFILE 'D:\app\zhoulx\oradata\bdc\OracleDBF.DBF' SIZE 100M AUTOEXTEND ON NEXT 20M MAXSIZE UNLIMITED -- 這裡是你設置資料庫存 ...
  • 1.select * from SYS_DICT as of timestamp to_timestamp('2019-11-05 10:00:00','yyyy-mm-dd hh24:mi:ss'); 時間點在刪除數據之前,又儘量精確 sys_dict 是表名 2.insert into SYS_ ...
  • 阿裡開發手冊的描述,禁止多表join: 手冊上寫著【強制】,相信很多同學項目裡面的代碼都不滿足這個要求。 但是關鍵問題是:不用join,這SQL究竟要怎麼寫?! 分解關聯查詢 即對每個要關聯的表進行單表查詢,然後將結果在應用程式中進行關聯。下麵的這個查詢: 可以分解成下麵這些查詢來代替: 但是該方案 ...
一周排行
  • 前幾天發佈了 "抄抄《CSS 故障藝術》的動畫" 這篇文章,在這篇文章里介紹瞭如何使用Win2D繪製文字然後配合BlendEffect製作故障藝術的動畫。本來打算就這樣收手不玩這個動畫了,但後來又發現性能不符合理想。明明只是做做Resize動畫和用BlendEffect混合,為什麼性能會這麼差呢? ...
  • 控制條控制項: progressBar 不能按照你程式的進程自動變化,需認為計算,調整變化量 private void progressBar1_Click(object sender, EventArgs e) { this.progressBar1.Maximum = 100;//設置進度條最大長 ...
  • 首先創建一個asp.net core web應用程式 第二步 目前官方預置了7種模板項目供我們選擇。從中我們可以看出,既有我們熟悉的MVC、WebAPI,又新添加了Razor Page,以及結合比較流行的Angular、React前端框架的模板項目。 空項目模板 Program.cs using S ...
  • 對閉包的理解 1.對於成員變數和局部變數:成員變數就是方法外部,類的內部定義的變數;局部變數就是方法或語句塊內部定義的變數。局部變數必須初始化。 形式參數是局部變數,局部變數的數據存在於棧記憶體中。棧記憶體中的局部變數隨著方法的消失而消失。成員變數存儲在堆中的對象裡面,由垃圾回收器負責回收。 成員變數它 ...
  • Xamarin.Forms讀取並展示Android和iOS通訊錄 TerminalMACS客戶端 本文同步更新地址: https://dotnet9.com/11520.html https://terminalmacs.com/861.html 閱讀導航: 一、功能說明 二、代碼實現 三、源碼獲取 ...
  • 做下對文件複製操作相關的筆記: /// <summary> /// 文件幫助類 /// </summary> public class FileHelper { /// <summary> /// 複製一個目錄下所有文件到一個新目錄下 /// </summary> /// <param name=" ...
  • 前言 有一個東西叫做鴨子類型,所謂鴨子類型就是,只要一個東西表現得像鴨子那麼就能推出這玩意就是鴨子。 C 裡面其實也暗藏了很多類似鴨子類型的東西,但是很多開發者並不知道,因此也就沒法好好利用這些東西,那麼今天我細數一下這些藏在編譯器中的細節。 不是只有 和 才能 在 C 中編寫非同步代碼的時候,我們經 ...
  • [toc] 1.應用背景 底端設備有大量網路報文(位元組數組):心跳報文,數據採集報文,告警報文上報。需要有對應的報文結構去解析這些位元組流數據。 2.結構體解析 由此,我第一點就想到了用結構體去解析。原因有以下兩點: 2.1.結構體存在棧中 類屬於引用類型,存在堆中;結構體屬於值類型,存在棧中,在一個 ...
  • 《深入淺出 C#》 (第3版) [作者] (美) Andrew Stellman (美) Jennifer Greene[譯者] (中) 徐陽 丁小峰 等譯[出版] 中國電力出版社[版次] 2016年08月 第1版[印次] 2018年04月 第4次 印刷[定價] 148.00元 【引子】 要學習編程 ...
  • 記錄使用對象初始值設定項初始化對象。 using System; using System.Collections.Generic; namespace ConsoleApp2 { class Program { static void Main(string[] args) { // 使用構造函數 ...
x