elasticsearch聚合,排序,腳本處理文本數據查詢異常
今天執行一個聚合查詢操作時發生異常,相關信息如下:
執行聚合查詢命令如下:
GET /megacorp/_search
{
"aggs" : {
"all_interests" : {
"terms" : { "field" : "interests" }
}
}
}
異常信息:
{
"type" : "illegal_argument_exception",
"reason" : "Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [field_data] in order to load field data by uninverting the inverted index. Note that this can use significant memory."
}
具體原因是由於Text類型字段被分析時,通過分析器將該字符串轉換成單獨字符集合(a list of individual terms)后進行索引.這樣elasticsearch就可以實現在全文檢索中查詢指定單詞.Text字段默認是可查詢的,但是Text字段不用於排序,聚合和腳本處理中.
那么如何實現聚合和排序那?
其實上面的異常提示中已經介紹了如何進行聚合排序,具體方式如下:
- 1 (推薦方式)在Text類型字段上增加keyword參數.這是字段就具備了全文檢索能力(text)和聚合排序能力(keyword).
- 2 使用fielddata內存處理能力.如果要對分析后文本字段進行聚合排序或執行腳本處理文本時,只能使用fielddata方式.
keyword使用方式:
a. 增加keyword字段參數,即fields.keyword的定義
添加索引字段映射,即將about字段映射為text類型和keyword類型
PUT /indexname
{
"mappings": {
"properties": {
"about":{
"type": "text",
"fields":{
"keyword":{
"type":"keyword"
}
}
}
}
}
}
b. 增加文檔數據
PUT indexname/_doc/1
{
"about":"aaa"
}
PUT indexname/_doc/2
{
"about":"bbb"
}
c.進行數據查詢並通過about.keyword進行排序
GET indexname/_search
{
"sort": [
{
"about.keyword": {
"order": "desc"
}
}
]
}
fielddata使用方式:
a. 添加索引映射
PUT indexname/_mapping
{
"properties": {
"about": {
"type": "text",
"fielddata": true
}
}
}
b.查詢
GET indexname/_search
{
"sort": [
{
"about": {
"order": "desc"
}
}
]
}
一般不推薦在Text字段上啟用fielddata,因為field data和其緩存存儲在堆中,這使得它們的計算成本很高.計算這些字段會造成延遲,增加的堆占用會造成集群性能問題.
這keyword和fielddata兩種方式的區別除了具體實現方式外,主要在於是否要求對於文本字段進行解析操作,由於keyword不要求進行文本解析,所以它的效率更高.
