您好,登錄后才能下訂單哦!
這篇文章主要介紹“如何理解Elasticsearch的內(nèi)部數(shù)據(jù)結(jié)構(gòu)”,在日常操作中,相信很多人在如何理解Elasticsearch的內(nèi)部數(shù)據(jù)結(jié)構(gòu)問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何理解Elasticsearch的內(nèi)部數(shù)據(jù)結(jié)構(gòu)”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
正如 Elastic 官方文檔所說:
Elasticsearch 特點之一是:分布式文檔存儲。
Elasticsearch不會將信息存儲為類似列數(shù)據(jù)庫的行(row),而是存儲為已序列化為JSON文檔的復雜數(shù)據(jù)結(jié)構(gòu)。
當集群中有多個Elasticsearch節(jié)點時,存儲的文檔會分布在整個集群中,并且可以從任何節(jié)點立即訪問。
存儲文檔后,將在1秒鐘內(nèi)(默認刷新頻率為1s)幾乎實時地對其進行索引和完全搜索。
如何做到快速索引和全文檢索的呢?
Elasticsearch使用倒排索引的數(shù)據(jù)結(jié)構(gòu),該結(jié)構(gòu)支持非??焖俚娜谋舅阉鳌?/p>
倒排索引列出了出現(xiàn)在任何文檔中的每個唯一單詞,并標識了每個單詞出現(xiàn)的所有文檔。
索引可以認為是文檔的優(yōu)化集合,每個文檔都是字段的集合,這些字段是包含數(shù)據(jù)的鍵值對。
默認情況下,Elasticsearch 對每個字段中的所有數(shù)據(jù)建立索引,并且每個索引字段都具有專用的優(yōu)化數(shù)據(jù)結(jié)構(gòu)。
例如,文本字段存儲在倒排索引中,數(shù)字字段和地理字段存儲在BKD樹中。
數(shù)據(jù)類型 | 數(shù)據(jù)結(jié)構(gòu) |
---|---|
text/keyword | 倒排索引 |
數(shù)字/地理位置 | BKD樹 |
不同字段具有屬于自己字段類型的特定優(yōu)化數(shù)據(jù)結(jié)構(gòu),并具備快速響應返回搜索結(jié)果的能力使得 Elasticsearch 搜索飛快!
面對海量內(nèi)容,如何快速的找到包含用戶查詢詞的內(nèi)容,倒排索引扮演了關(guān)鍵角色。
倒排索引是單詞到文檔映射關(guān)系的最佳實現(xiàn)形式。
下圖是:書的末頁的索引結(jié)構(gòu),展示了核心關(guān)鍵詞與書頁碼的對應關(guān)系。
試想一下,沒有這個索引頁,根據(jù)關(guān)鍵詞從全書查找有多慢,就能直觀體會出索引的妙處!
拿官方文檔的示例:
假設(shè)我們有兩個文檔,每個文檔的 content 域包含如下內(nèi)容:
- 1、The quick brown fox jumped over the lazy dog
- 2、Quick brown foxes leap over lazy dogs in summer
對索引編制索引會受到標記化和標準化的處理analysis。
數(shù)據(jù)索引化制約因素:分詞器 analyzer 的選型。
倒排索引(基于 默認Standard 標準分詞器分詞)如下所示:
Term | Doc_1 | Doc_2 |
---|---|---|
Quick | X | |
The | X | |
brown | X | X |
dog | X | |
dogs | X | |
fox | X | |
foxes | X | |
in | X | |
jumped | X | |
lazy | X | X |
leap | X | |
over | X | X |
quick | X | |
summer | X | |
the | X |
如上所示,對于文檔中的每個詞,都包含了其所在文檔的列表。
在 Elasticsearch 中,Doc Values 就是一種列式存儲結(jié)構(gòu),默認情況下每個字段的 Doc Values 都是激活的(除了 text 類型),Doc Values 是在索引時創(chuàng)建的,當字段索引時,Elasticsearch 為了能夠快速檢索,會把字段的值加入倒排索引中,同時它也會存儲該字段的 Doc Values。
區(qū)別于倒排索引的定義,Doc Values 被定義為:“正排索引”。
仍然 以 1.2 文檔為例,Doc Values 結(jié)構(gòu)如下所示(僅做舉例):
Doc | Terms |
---|---|
Doc_1 | brown, dog, fox, jumped, lazy, over, quick, the |
Doc_2 | brown, dogs, foxes, in, lazy, leap, over, quick, summer |
Doc values 通過轉(zhuǎn)置兩者間的關(guān)系來解決適用倒排索引聚合效率低、難以擴展的問題。
對比可以看出:倒排索引將詞項映射到包含它們的文檔,doc values 將文檔映射到它們包含的詞項。
Elasticsearch 中的 Doc Values 常被應用到以下場景:
注意:
因為文檔值被序列化到磁盤,我們可以依靠操作系統(tǒng)的幫助來快速訪問。
當 工作集(working set) 遠小于節(jié)點的可用內(nèi)存,系統(tǒng)會自動將所有的文檔值保存在內(nèi)存中,使得其讀寫十分高速;
當其遠大于可用內(nèi)存,操作系統(tǒng)會自動把 Doc Values 加載到系統(tǒng)的頁緩存中,從而避免了 jvm 堆內(nèi)存溢出異常。
對于不需要:排序、聚合、腳本計算、地理位置過濾的業(yè)務場景,可以考慮禁用:Doc Values,以節(jié)約存儲。
PUT my_index
{
"mappings": {
"properties": {
"title": {
"type": "keyword",
"doc_values": false
}
}
}
}
如前第1、2小結(jié)所述:
text 類型字段是不支持 Doc Values正排索引的,text字段使用是:查詢時創(chuàng)建的基于的內(nèi)存數(shù)據(jù)結(jié)構(gòu)(query-time in-memory data structure) fielddata。
fielddata 將 text 字段用于聚合、排序或在腳本中使用時,將按需構(gòu)建此數(shù)據(jù)結(jié)構(gòu)。
實現(xiàn)機理:它是通過從磁盤讀取每個段的整個反向索引,反轉(zhuǎn)詞項??文檔關(guān)系并將結(jié)果存儲在JVM堆中的內(nèi)存中來構(gòu)建的。
嚴格意義講,2.2 的示例,放到這里會更合適。
DELETE test_001
PUT test_001
{
"mappings": {
"properties": {
"body":{
"type":"text",
"analyzer": "standard",
"fielddata": true
}
}
}
}
POST test_001/_bulk
{"index":{"_id":1}}
{"body":"The quick brown fox jumped over the lazy dog"}
{"index":{"_id":2}}
{"body":"Quick brown foxes leap over lazy dogs in summer"}
GET test_001/_search
{
"size": 0,
"query": {
"match": {
"body": "brown"
}
},
"aggs": {
"popular_terms": {
"terms": {
"field": "body"
}
}
}
}
_source 字段包含在索引時間傳遞的原始JSON文檔主體。
_source 字段本身未構(gòu)建索引(因此不可搜索),但已存儲該字段,以便在執(zhí)行獲取請求(如get或search)時可以將其返回。
第一:盡管非常方便,但是source字段確實會導致索引內(nèi)的存儲開銷。因此,可以將其禁用。
PUT my-index-000001
{
"mappings": {
"_source": {
"enabled": false
}
}
}
第二:禁用前要做好以下衡量 禁用 _source 后,如下操作將不可用:
update, update_by_query 和 reindex API
高亮操作
默認情況下,對字段值進行索引以使其可搜索(第1節(jié)的 倒排索引),但不存儲它們。
這意味著可以查詢該字段,但是無法檢索原始字段值。
通常這無關(guān)緊要。該字段值已經(jīng)是_source字段的一部分,默認情況下已存儲。
但,某些特殊場景下,如果你只想檢索單個字段或幾個字段的值,而不是整個_source的值,則可以使用源過濾來實現(xiàn)。
這個時候, store 就派上用場了。
DELETE news-000001
PUT news-000001
{
"mappings": {
"_source": {
"enabled": false
},
"properties": {
"title": {
"type": "text",
"store": true
},
"date": {
"type": "date",
"store": true
},
"content": {
"type": "text"
}
}
}
}
PUT news-000001/_doc/1
{
"title": "Some short title",
"date": "2021-01-01",
"content": "A very long content field..."
}
GET news-000001/_search
GET news-000001/_search
{
"stored_fields": [ "title", "date" ]
}
如 5.2 示例,在某些情況下,存儲字段可能很有意義。例如,采集的新聞數(shù)據(jù)是:帶有標題、日期和很大內(nèi)容字段的文檔,
則可能只想檢索標題和日期,而不必從較大的_source字段中提取這些字段。
到此,關(guān)于“如何理解Elasticsearch的內(nèi)部數(shù)據(jù)結(jié)構(gòu)”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。