作者:來自 Elastic?JD Armada
學習如何使用 _mapping 和 _search API、子字段、合成 _source 和運行時字段來顯示 Elasticsearch 索引的字段。
更多閱讀:
-
Elasticsearch:從搜索中獲取選定的字段 fields
-
Elasticsearch:inverted index,doc_values 及 source
-
Observability:Elasticsearch 新的索引 mode: Logsdb 初體驗
想獲得 Elastic 認證嗎?了解下一次 Elasticsearch Engineer 培訓的時間!
Elasticsearch 擁有眾多新功能,幫助你為你的使用場景構建最佳搜索解決方案。瀏覽我們的示例 notebooks 了解更多,開始免費 cloud 試用,或在本地機器上體驗 Elastic。
本文將討論如何顯示 Elasticsearch 索引的字段。這有助于了解你的數據結構,識別特定字段,以及排查問題。我們將涵蓋以下主題:
- 使用 _mapping API 獲取字段信息
- 使用 _search API 顯示字段值
- 顯示子字段
- 合成 _source
- 運行時字段
1)使用 _mapping API 獲取字段信息
_mapping API 允許你獲取一個或多個索引的映射定義。這包括字段、它們的數據類型以及其他屬性的信息。要獲取特定索引的映射,請使用以下請求:
GET /<index_name>/_mapping
例如,如果你有一個名為 my_index 的索引,可以使用以下請求來獲取它的映射:
GET /my_index/_mapping
響應將包含該索引的映射定義,其中包含字段及其屬性的信息。
你也可以獲取某個特定字段的映射。當映射較大且你只關注某個字段時,這會很有用。要獲取特定字段的映射,請使用以下請求:
GET /my_index/_mapping/field/my_field
你也可以通過用逗號分隔字段名來獲取多個字段的映射,如下所示的請求:
GET /my_index/_mapping/field/my_field_1,my_field_2,my_field_3
2)使用 _search API 顯示字段值
要顯示 Elasticsearch 索引中字段的值,可以使用 _search API。_search API 提供多種方式來控制返回哪些字段,主要有以下兩種:
- _source:_source 字段包含索引時的原始 JSON 文檔正文,包括通過攝取管道或預處理步驟所做的任何更改。要從源文檔中顯示特定字段,可以使用源過濾(source filtering),我們將在下文介紹。
- fields:fields 參數允許你在搜索時根據索引映射檢索文檔中的特定字段。與 _source 不同,fields 可以返回存儲字段(stored fields)、doc values 或運行時字段(runtime fields)的值,而無需引用 _source。不過,對于沒有 doc values 或存儲設置的標準字段,fields 會回退使用 _source。這樣可以帶來性能等多方面的優勢,我們將在下文看到。
使用 _source 字段
默認情況下,_search API 會返回 _source 字段,它包含被索引的原始 JSON 文檔。要顯示特定字段,你可以在搜索請求中使用 _source 參數添加過濾器,這稱為源過濾(source filtering)。
以下是一個搜索請求示例,用于返回 my_index 索引中文檔的 title 和 author 字段的值:
GET /my_index/_search
{"query": {"match_all": {}},"_source": ["title", "author"]
}
在這個例子中,_source 參數指定了要返回的字段。
如果你需要更細致的控制,可以使用 _source 對象的 includes 和 excludes 屬性。例如,下面的查詢返回頂層的 title 字段和 author 的所有子字段,但排除 author.description。
GET /my_index/_search
{"query": {"match_all": {}},"_source": {“includes”: [“title”, “author.*],“excludes”: [“author.description”]}
}
在這個例子中,我們使用 author.* 模式來獲取 author 對象的所有直接子字段。然后顯式排除 author.description,這樣只返回其他 author 字段。注意,這不會提升性能,因為仍需加載和解析源 JSON,但可以減少通過網絡傳輸的響應大小。
使用 fields 參數
你可以使用 fields 參數過濾搜索響應中返回的字段。相比 _source,使用 fields 有以下幾個好處:
-
性能提升:fields 可以直接從存儲字段(stored fields)或 doc values 返回值,無需加載完整的 _source,減小響應負載大小。
-
格式化輸出:對于標準字段,fields 可能回退到 _source 獲取值,但會參考索引映射正確格式化輸出,比如格式化日期,使其與聚合和排序中使用的格式一致。
-
訪問運行時字段:fields 可以返回運行時字段,這些字段在原始 _source 中不存在。
- 更多好處可以參考相關文檔。
例如,要僅返回 my_index 索引中的 title 和 author 字段,可以使用以下搜索請求:
GET /my_index/_search
{"query": {"match_all": {}},"fields": ["title", "author"],"_source": false
}
在上面的查詢中,我們將 _source 字段設置為 false,這樣就不返回源文檔。這可以大幅減少響應的負載大小,但請注意,這僅因為字段 title 和 author 是 keyword 類型,且默認啟用了 doc_values。如果字段未啟用 doc_values 且 _source 設置為 false,Elasticsearch 無法檢索這些字段,它們會在響應中被跳過。
需要注意的是,fields 響應總是返回每個字段的值數組,即使該字段只有一個值。這是因為 Elasticsearch 沒有專門的數組類型,任何字段都可能有多個值。關于 Elasticsearch 中數組的更多信息,請點擊這里。
其他獲取字段的方法
雖然推薦使用 _source 或 fields 來獲取字段,但也有其他方法適用于特定場景,例如:
Doc value 字段:如果你想完全避免使用 _source,可以使用 docvalue_fields 參數進行搜索。Doc values 存儲與 _source 相同的字段值,但采用的是磁盤上的數據結構,優化了排序和聚合。
因為它獨立于 _source 存儲的值,你可以請求特定字段而無需加載整個 _source。對于查詢大文檔但只需要少數字段且這些字段支持 doc values 的情況,這很有用。另一個使用 docvalue_fields 的場景是對日期和數值字段使用自定義格式化,如下面示例所示。
請注意,這只適用于你啟用了 doc_values 的字段或默認啟用 doc_values 的字段類型,如 keyword、date、numeric 和 boolean,不適用于 text 或 annotated_text。
在這個例子中,我們使用 docvalue_fields 參數來檢索 title、author 和 published 字段,而不加載完整的 _source 文檔:
GET /my_index/_search
{"query": {"match_all": {}},"docvalue_fields": ["title","author",{"field": "published","format": "epoch_millis"}],"_source": false
}
當這個查詢執行時,Elasticsearch 會直接從其磁盤上的列式存儲中獲取值,而不是引用每個文檔的 _source。由于查詢中提供了 format 參數,published 字段以 epoch_millis 格式返回,而不是默認格式。
存儲字段(Stored fields):如果你在映射中顯式將某些字段標記為 stored,可以使用 stored_fields 參數過濾這些字段。當你只想要輕量響應,僅包含這些特定字段,或想檢索你故意存儲的字段時,這很有用。存儲字段獨立于 _source,因此這種方法也適合避免加載 _source。
需要注意的是,這個選項默認是關閉的,且通常不推薦使用。建議使用源過濾(source filtering)來返回原始源文檔的某些子集。
在下面的示例查詢中,我們使用 stored_fields 參數來檢索 summary 字段,該字段的索引映射配置為 "store": true。
GET /my_index/_search
{"query": {"match_all": {}},"stored_fields": ["summary"]
}
當這個查詢執行時,Elasticsearch 會檢查該字段是否標記了 "store": true,如果沒有找到,則會完全跳過該字段。
顯示子字段
如果你的索引包含子字段,可以在 fields 參數中使用點號表示法指定字段路徑。注意,子字段不同于 nested 字段類型。例如,如果你有一個名為 address.city 的子字段,可以這樣包含在搜索響應中:
GET /my_index/_search
{"query": {"match_all": {}},"fields": ["title", "author", "address.city"],"_source": false
}
在這個例子中,搜索響應將包含 title、author 和 address.city 字段的值。
合成 _source
如果你想保留使用 _source 的功能,同時節省磁盤空間,可以在索引映射中使用合成 _source。合成 _source 是一個功能,允許 Elasticsearch 根據已有的數據(如存儲字段和 doc values)重建 _source,即使 _source 被禁用。這能節省大量存儲空間,但查詢時需要即時重建,速度會稍慢。你可以在索引設置中使用以下配置來啟用此功能:
PUT idx
{"settings": {"index": {"mapping": {"source": {"mode": "synthetic"}}}}
}
使用合成 _source 的一些好處包括:在使用 _search API 時可以完整顯示文檔,支持源過濾,并兼容像 Kibana 這樣期望 _source 可用的其他功能和工具,同時避免存儲完整的 _source 文檔。
運行時字段
運行時字段(Runtime fields)允許你在查詢時或索引映射的 runtime 塊中定義腳本字段。這些字段不會被索引,因此添加運行時字段不會增加索引大小,但也不會出現在 _source 中。映射中定義的運行時字段是持久的,所有查詢都可用;查詢時定義的運行時字段是臨時的,僅在該次搜索請求中可用。
使用運行時字段的主要好處是能夠在數據已被攝取后添加字段,簡化映射設計。運行時字段也適合用腳本生成原始文檔中不存在的值,比如格式化字符串或計算分數。
但需要注意,運行時字段會影響性能,因為每個結果文檔都需要運行腳本。你也可以通過 _search API 的 fields 參數來檢索運行時字段。
總結
顯示 Elasticsearch 索引的字段可以從簡單地使用索引映射或 _source 獲取值,到更高級地使用 fields、docvalue_fields 或運行時字段,以獲得更高的控制和效率。理解不同方法的權衡對優化搜索體驗非常關鍵。無論是優化響應負載,豐富文檔內容,還是使用合成 _source 節省存儲,Elasticsearch 都提供了多種工具和功能,幫助你以所需方式找到所需數據。這些技術能幫助你理解數據結構,識別特定字段,并排查問題。
原文:How to display fields of an Elasticsearch index - Elasticsearch Labs