本節書摘來華章計算機《深入了解elasticsearch(原書第2版)》一書中的第2章 ,第2.3.1節,[美]拉斐爾·酷奇(rafal ku) 馬雷克·羅戈任斯基(marek rogoziski)著 張世武 餘洪淼 商旦 譯 更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。
自elasticsearch 1.1.0版本開始,我們可以自定義查詢模闆。讓我們回到本書開頭的線上書店例子中。假定我們已經确定了需要傳遞給elasticsearch的查詢語句的類型,不過查詢結構并未最終确定,我們還需要對它進行微調和優化。通過使用查詢模闆,我們可以快速建構出查詢的基礎骨架,然後讓應用程式來提供對應的參數,最終由elasticsearch完成查詢參數的替換。
假定我們有一個針對library索引的查詢語句,可以傳回最相關的書籍記錄。在這個查詢中,我們還允許使用者選擇是否對書籍的庫存狀态做篩選。在這個場景中,我們需要傳入兩個參數—一個查詢短語和一個代表書籍庫存狀态的布爾變量。最初的簡化示例如下:

代碼中的query和boolean是占位符,代表應用程式傳遞給查詢的變量。顯然這個查詢語句對目前示例場景來說實在太簡陋了,不過之前我們已經說過,這隻是它的最初版本,我們馬上将對它進行改進。
既然已經有了最初版本的查詢語句,我們可以基于它建立第一個查詢模闆。對該查詢語句做簡單修改如下:
可以看出,原來的占位符被替換成了{{phrase}}和{{avail}}兩個變量,并且添加了一個新的params片段。當elasticsearch在解析查詢語句時,遇到一個{{phrase}}變量,它将嘗試從params片段中查找出名為phrase的參數,并用參數值替換掉{{phrase}}變量。通常,我們需要把參數值放到params片段中,并在query中使用形如{{var}}的标記來引用params片段中參數名為var的參數。此外,查詢本身被嵌套進一個template元素中。通過這種方式,我們實作了查詢的參數化。
接下來讓我們使用http get請求把以下查詢語句發送給位址為/library/_search/template的rest端點(注意這裡不是我們通常使用的/library/_search端點)。請求指令構造如下:
字元串形式的查詢模闆
查詢模闆也可以以字元串的形式提供。比如,剛才的查詢模闆可以變成這樣:
可見,這種形式不太适合閱讀和書寫,每個引号都需要被轉義,換行符容易引發格式問題,是以需要避免使用。盡管如此,如果你需要使用mustache(一個模闆引擎,我們将在下一小節探讨),則必須使用這種格式(至少在elasticsearch的1.1.0到1.4.0之間的所有版本中必須這樣做)。
本書寫作時,筆者所使用的elasticsearch相關版本中有一個關于查詢模闆的小陷阱。如果你提供的查詢模闆中有錯誤,被elasticsearch檢測到後,會把錯誤寫到服務日志裡,但是從api的視角來看,錯誤查詢将被忽略,接口将傳回所有文檔,就好像你剛剛發送了一個match_all查詢一樣。記得複查你的查詢模闆,直到這個缺陷不再存在。