ES 13 - Elasticsearch的元欄位(_index、_type、_source、_routing等)

来源:https://www.cnblogs.com/shoufeng/archive/2019/04/09/10679725.html
-Advertisement-
Play Games

元欄位是ES為每個文檔配置的內置欄位, 主要用於ES內部相關操作. ES有多種類型的元欄位, 在使用和提高性能方面有很強大的地方, 這篇文章列舉常用元欄位的功能和使用方法, 包括_index、_type、_source、_routing等, 歡迎交流吖~ ...


目錄

元欄位是ES為每個文檔配置的內置欄位, 主要用於ES內部相關操作.

1 標識元欄位

1.1 _index - 文檔所屬的索引

_index標註document屬於哪個index, 是一個虛擬欄位, 不會被添加到Lucene索引中.

將類似的文檔 (也就是具有相同field的文檔) 存放到同一個index中, 是一種良好的數據建模思想.
提供大量查詢的index, 最好不要同時提供大量的統計、聚合等操作——通過把特定的index路由到指定的shard上, 便於系統的優化.

註意: 索引名稱必須是小寫的字母, 不能以下劃線"_"開頭, 不能包含逗號 ",".

在term或者terms查詢, 聚合、腳本以及排序時, 可以訪問_index欄位的值.

在多個索引中執行查詢時, 可以通過添加查詢子句來關聯特定的索引文檔, 使用示例——同時查詢多種index:

GET website,book_shop/_search
{
    "query": {
        "terms": {    // 查詢_index是website和book_shop的文檔
            "_index": [ "website", "book_shop"] }
    },
    "aggs": {
        "indices": {  // 對_index欄位進行聚合操作
            "terms": { "field": "_index", "size": 10 }
        }
    },
    "sort": {         // 對_index欄位進行排序操作
        "_index": { "order": "asc" }
    },
    "script_fields": {  // 使用腳本, 顯示_index欄位
        "index_name": {
            "script": { 
                "lang": "painless",
                "source": "doc['_index']"
            }
        }
    }
}

1.2 _uid - 包含_type和_id的複合欄位

_uid_type_id的組合, 形式為{type}#{id}. 可以用於查詢、聚合、腳本和排序.

(1) 添加文檔:

PUT website/blog/4
{
    "text": "blog with ID 4"
}

PUT website/blog/5?refresh=true
{
    "text": "blog with ID 5"
}

(2) 檢索文檔:

說明: 對_uid欄位的訪問API已經過期, 需要使用_id替換.

#! Deprecation: Fielddata access on the _uid field is deprecated, use _id instead
GET website/_search
{
    "query": { 
        "terms": {       // 通過_uid查詢_type和_id的複合欄位
            "_uid": ["blog#4", "blog#5"]
        }
    },
    "aggs": {
        "uid_aggs": {
            "terms": {    // 這裡通過_uid聚合的操作已經過期
                "field": "_id", "size": 10
              }
        }
    }, 
    "sort": {             // 這裡通過_uid排序的操作已經過期
        "_id": { "order": "desc"}
    }, 
    "script_fields": {
        "uid_script": {
            "script": {   // 這裡對_uid的腳本操作已經過期
                "lang": "painless", 
                "source": "doc['_id']" 
            }
        }
    }
}

1.3 _type - 文檔的類型

_type元欄位用來標註document屬於哪個類型, 也被稱作映射類型.

註意: type的名稱可以是大寫或小寫字母, 但不能以下劃線"_"開頭, 不能包含逗號",".

在Elasticsearch 6.0之前的版本中, 一個index可能會被劃分為多個type, 例如: 商品中有電子商品, 服裝商品, 生鮮商品...

在Elasticsearch 6.0之後, 一個index只能包含一個type, 否則將出現錯誤.

每一個索引文檔都包含_type_id欄位, _type欄位的目的是通過類型名加快搜索速度.

_type欄位可以在查詢、聚合、排序以及腳本中訪問到.

關於type的底層數據結構, 可參見ES XX - Elasticsearch對索引類型(_type)的處理方式.

1.4 _id - 文檔的id

_id代表document的唯一標識, 與_index_type一起, 唯一標識和定位一個document.

註意: 可以手動指定document的id(PUT index/type/id), 也可以不指定, Elasticsearch在添加文檔時會自動為其創建id.

可以在查詢、腳本中訪問, 查詢示例:

GET website/_search
{
    "query": {
        "terms": {"_id" : ["1", "2"]}
    },
    "aggs": {
        "id_aggs": {
            "terms": {
                "field": "_id", "size": 10
            }
        }
    }, 
    "script_fields": {
        "id_script": {
            "script": {
                "lang": "painless", 
                "source": "doc['_id']"
            }
        }
    }
}

2 文檔來源元欄位

2.1 _source - 文檔原始JSON內容

文檔的原始JSON內容將索引到_source欄位中, 該欄位本身不建立索引, 但是會被存儲.

搜索文檔時預設返回該欄位及其內容, 但無法用於搜索.

2.1.1 關閉_source功能

_source功能預設是開啟的, 它會產生額外的存儲開銷, 可以關閉:

PUT website
{
    "mappings": {
        "blog": {
            "_source": {"enabled": false}
        }
    }
}

// 或者:
PUT website/_mapping/blog
{
    "_source": {"enabled": false}   
}

註意: 必須在創建索引時關閉, 創建之後不允許修改, 否則將會發生如下錯誤:

{
  "error": {
    "root_cause": [
      {
        "type": "resource_already_exists_exception",
        "reason": "index [website/zIUdhInBQsOUi_4Tt2SSkQ] already exists",
        "index_uuid": "zIUdhInBQsOUi_4Tt2SSkQ",
        "index": "website"
      }
    ],
    "type": "resource_already_exists_exception",
    "reason": "index [website/zIUdhInBQsOUi_4Tt2SSkQ] already exists",
    "index_uuid": "zIUdhInBQsOUi_4Tt2SSkQ",
    "index": "website"
  },
  "status": 400
}

2.1.2 查詢時指定返回欄位

_source功能被禁止, 將造成大量功能無法使用:

partial update 功能基於_source實現;
hilight 高亮顯示功能基於_source實現;
reindex 重建索引功能基於_source實現, 不需要從其他外部存儲中獲取數據, 再index;
基於_source定製返回field;
調試query時更容易, 因為可以很直觀地看到_source內容……

可以在創建index時, 在mapping中通過includes/excludes參數來減少_source欄位的內容:

PUT logs
{
    "mappings": {
        "event": {
            "_source": {
                "includes": ["*.count", "meta.*"],         // 包含的欄位
                "excludes": ["meta.desc", "meta.other.*"]  // 不包含的欄位
            }
        }
    }
}

移除的欄位不會被存儲在_source中, 但仍然可以搜索到這些欄位.

可以在檢索時, 禁止返回原始內容:

GET website/blog/1?_source=false

如果只想獲取_source的部分內容, 可以使用_source_includes_source_excludes參數:

GET website/blog/1?_source_includes=title,content
GET website/blog/1?_source_excludes=post_date,author_id

Elasticsearch 6.0之前的版本中: 使用_source_include_source_exclude用來指定檢索的結果中是否包含_source中的某個欄位;
Elasticsearch 6.0之後的版本中: 相關的API修改為: _source_includes_source_excludes——多加了s.

2.2 _size - _source欄位占用的位元組數

記錄_source欄位占用的位元組數, 由插件mapper-size提供.

3 索引元欄位

3.1 _all - 文檔所有欄位的值

(1) ES 6.0之後的方法:

在Elasticsearch 6.0版本中, _all欄位已經被禁用了. 若要開啟, 官方建議是:

"Enabling [_all] is disabled in 6.0. As a replacement, you can use [copy_to] on mapping fields to create your own catch all field."
——大致意思是: _all已經不允許使用了, 作為替換, 我們可以使用copy_to關鍵字來創建需要獲取的所有欄位的內容.

copy_to的使用方法如下:

PUT logs
{
    "mappings": {
        "event": {
            "properties": {
                "event_id": {
                    "type": "text",
                    "copy_to": {"enabled": true}    
                },
                  "event_desc": {
                    "type": "text",
                    "copy_to": {"enabled": true},
                    "analyzer": "english"
                },
                "time": {
                    "type": "date",
                    "copy_to": {"enabled": true},
                    "format": "strict_date_optional_time||epoch_millis"
                }
            }
        }
    }
}

(2) ES 6.0以前的方法:

在Elasticsearch 6.0之前, _all欄位的使用方式如下:

_all欄位包含1個文檔的全部field的內容: 用一個大字元串關聯其他所有欄位的值, 用空格作為分隔符.
_all欄位可以被分析和索引, 但不會被存儲 —— 預設的搜索field.
通過_all欄位可以對文檔的值進行搜索而不必知道相關的欄位名.
_all欄位丟失了長欄位(低相關性)和短欄位(高相關性)之間的區別 —— 在相關性搜索要求比較高的時候, 應該明確指出要查詢的欄位.

① **_all欄位需要額外的處理器周期, 且耗費更多的磁碟空間, 若不需要, 建議禁用此功能:**

PUT website/_mapping/blog
{
    "_all": {"enabled": false}
}

② 或 在field中設置include_in_all —— 是否要將field的值包含在_all中:

PUT website/_mapping/blog
{
    "properties": {
        "test_field": {
            "type": "text",
            "include_in_all": false
        }
    }
}

3.2 _field_names - 文檔所有非空欄位名

該欄位可以用在查詢、聚合以及腳本中 —— 用於查找指定欄位的值非空的文檔是否存在.

使用示例:

GET website/_search
{
    "query": {
        "terms": {"_field_names": ["content"]}
    }
}

4 路由元欄位

4.1 [過期]_parent - 在type間創建父子關係

(1) 創建映射:

PUT store
{
    "mappings": {
        "book": {},
        "it_book": {
            "_parent": {"type": "book"}     // 指定其父類
        }
    }
}

(2) 插入父文檔:

PUT store/book/1
{ "desc": "this is parent book"}

(3) 插入子文檔, 並指出其父文檔:

PUT store/it_book/2?parent=1
{ "desc": "this is child it_book"}

(4) 父子文檔的限制:

① 父type和子type必須不同.
② _parent的type的值只能是不存在的類型 —— 一個type被創建後就不能稱為父類型了.

(5) 其他說明:

父子文檔必須索引在同一個分片上:
① parent的編號用於子文檔的路由值, 確保子文檔被索引到父文檔所在的分片中.
② 查詢、更新、刪除子文檔時, 也需要提供相同的parent值.

4.2 _routing - 自定義的路由值

用於將文檔路由到指定的分片上. 通過如下公式將文檔路由到特定的分片:

shard_num = hash(_routing) % num_primary_shards

如果不指定_routing的值, 預設使用文檔的_id欄位. 如果存在父文檔則使用其_parent的編號.

可以通過為某些文檔都指定相同的路由值, 來實現對這些文檔的自定義路由功能:

// 此文檔使用'user_5220'作為其路由值, 在查詢、更新、刪除時同樣需要提供此路由值
PUT website/blog/1?routing=user_5220
{
    "title": "xxx"
}

_routing欄位可以在查詢、聚合、腳本以及排序的時候訪問. 比如直接指定路由值來搜索相關的文檔:

GET website/_search
{
    "query": {
        "terms": {"_routing": [ "user_5220" ] }
    }
}

5 其他元欄位

_meta - 應用特定的元欄位: 每個type都可以擁有自定義的元數據 —— ES並不會使用, 但可以用來存儲應用程式的特定信息.

使用示例:

PUT website
{
    "mappings": {
        "user": {
            "_meta": {
                "class": "com.healchow.website.pojo.User",
                "version": {"min": "1.0", "max": "1.3"}
            }
        }
    }
}

參考資料

Elasticsearch官方文檔 - Meta-Fields

版權聲明

作者: 馬瘦風

出處: 博客園 馬瘦風的博客

您的支持是對博主的極大鼓勵, 感謝您的閱讀.

本文版權歸博主所有, 歡迎轉載, 但請保留此段聲明, 併在文章頁面明顯位置給出原文鏈接, 否則博主保留追究相關人員法律責任的權利.


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

-Advertisement-
Play Games
更多相關文章
  • mkdir 作用:創建目錄 主要參數:-p -p:遞歸參數 使用{}創建多個目錄 上面是幾個簡單但是非常重要的參數,以後重要的參數會繼續更新。 ...
  • 我是19年3月轉向使用Linux進行開發,沒啥特別的理由,就是覺得使用Linux系統是每個程式員必須經歷的吧。 選擇版本 一開始,在網上瞭解到現在流行的Linux發行版有基於Redhat的,還有基於debian的,就簡單瞭解一下而已,太冷門的系統對新手也不友好。 我推薦的版本就Ubuntu和Deep ...
  • 多表查詢: 顯示內連接: select 欄位列表 from 表名1 inner join 表名1 on 條件 * inner 可忽略 select * from student inner join class on student.clas_id=class.id 隱式內連接: 使用where: ...
  • (一)neo4j安裝 neo4j有社區版本和企業版,社區版本是免費的,企業版本是收費的。在linux上安裝如下步驟: 1、將下載的neo4j-enterprise-3.4.0-unix.tar.gz包上傳到linux伺服器,並解壓。 2、設置$NEO4J_HOME也就是解壓圖資料庫安裝包所在的目錄到 ...
  • 本系列筆記是在看完《neo4j權威指南》基礎上做的記錄。方便於自己後面查閱!! 1.圖庫介紹 圖資料庫(Graph Database)是基於圖論實現的一種新型NoSQL資料庫。它的數據存儲結構和數據的查詢方式都是以圖論為基礎的。圖論中圖的基本元素為節點和邊,在圖資料庫中對應的就是節點和關係。在圖數據 ...
  • 1.起因: 需要導入一個sql文件,發現死活導不進去.當執行到這一句時,就有問題.經過一番搜索,原來是我的資料庫版本(原先Mysql版本5.5)低了,而支持該語句的版本應該是至少要5.7.那我索性就去Mysql官網去下載了個最新版本的(8.0.15). 2.過程: 那麼問題來了:有兩個解決方案.1. ...
  • 關於視圖的用法以及作用。 作用一: 提高了重用性,就像一個函數。如果要頻繁獲取user的name和goods的name。就應該使用以下sql語言。示例: select a.name as username, b.name as goodsname from user as a, goods as b ...
  • 背景 從mysql.slow_log 獲取慢查詢日誌很慢,該表是csv表,沒有索引。 想添加索引來加速訪問,而csv引擎不能添加索引(csv引擎存儲是以逗號分割的文本來存儲的),只能改存儲引擎來添加索引了 mysql.slow_log表能改成myisam,不能改成innodb mysql.gener ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...