ES核心概念
- 索引
- 字段類型(mapping)
- 文檔(documents)
elasticsearch是面向文檔,關係行數據庫 和 elasticsearch 客觀的對比!一切都是JSON!
Relational DB (關係型數據庫) | Elasticsearch |
---|---|
數據庫(database) | 索引(indices) |
表(tables) | types |
行(rows) | documents |
字段(columns) | fields |
elasticsearch(集羣)中可以包含多個索引(數據庫),每個索引中可以包含多個類型(表),每個類型下又包含多 個文檔(行),每個文檔中又包含多個字段(列)。
物理設計:
elasticsearch 在後臺把每個索引劃分成多個分片,每分分片可以在集羣中的不同服務器間遷移
一個人就是一個集羣!默認的集羣名稱就是 elaticsearh
邏輯設計:
一個索引類型中,包含多個文檔,比如說文檔1,文檔2。 當我們索引一篇文檔時,可以通過這樣的一各順序找到 它: 索引 ▷ 類型 ▷ 文檔ID ,通過這個組合我們就能索引到某個具體的文檔。 注意:ID不必是整數,實際上它是個字 符串。
文檔
就是我們的一條條數據
user
1 zhangsan 18
2 kuangshen 3
之前說elasticsearch是面向文檔的,那麼就意味着索引和搜索數據的最小單位是文檔,elasticsearch中,文檔有幾個 重要屬性 :
- 自我包含,一篇文檔同時包含字段和對應的值,也就是同時包含 key:value!
- 可以是層次型的,一個文檔中包含自文檔,複雜的邏輯實體就是這麼來的! {就是一個json對象!fastjson進行自動轉換!}
- 靈活的結構,文檔不依賴預先定義的模式,我們知道關係型數據庫中,要提前定義字段才能使用,在elasticsearch中,對於字段是非常靈活的,有時候,我們可以忽略該字段,或者動態的添加一個新的字段。
儘管我們可以隨意的新增或者忽略某個字段,但是,每個字段的類型非常重要,比如一個年齡字段類型,可以是字符 串也可以是整形。因爲elasticsearch會保存字段和類型之間的映射及其他的設置。這種映射具體到每個映射的每種類型,這也是爲什麼在elasticsearch中,類型有時候也稱爲映射類型。
類型
索引
類型是文檔的邏輯容器,就像關係型數據庫一樣,表格是行的容器。 類型中對於字段的定義稱爲映射,比如 name 映 射爲字符串類型。 我們說文檔是無模式的,它們不需要擁有映射中所定義的所有字段,比如新增一個字段,那麼elasticsearch是怎麼做的呢?elasticsearch會自動的將新字段加入映射,但是這個字段的不確定它是什麼類型,elasticsearch就開始猜,如果這個值是18,那麼elasticsearch會認爲它是整形。 但是elasticsearch也可能猜不對, 所以最安全的方式就是提前定義好所需要的映射,這點跟關係型數據庫殊途同歸了,先定義好字段,然後再使用。
索引
就是數據庫!
索引是映射類型的容器,elasticsearch中的索引是一個非常大的文檔集合。索引存儲了映射類型的字段和其他設置。 然後它們被存儲到了各個分片上了。 我們來研究下分片是如何工作的。
物理設計 :節點和分片 如何工作
一個集羣至少有一個節點,而一個節點就是一個elasricsearch進程,節點可以有多個索引默認的,如果你創建索引,那麼索引將會有個5個分片 ( primary shard ,又稱主分片 ) 構成的,每一個主分片會有一個副本 ( replica shard ,又稱複製分片 )
上圖是一個有3個節點的集羣,可以看到主分片和對應的複製分片都不會在同一個節點內,這樣有利於某個節點掛掉 了,數據也不至於丟失。 實際上,一個分片是一個Lucene索引,一個包含倒排索引的文件目錄,倒排索引 的結構使 得elasticsearch在不掃描全部文檔的情況下,就能告訴你哪些文檔包含特定的關鍵字。
倒排索引
elasticsearch使用的是一種稱爲倒排索引的結構,採用Lucene倒排索作爲底層。這種結構適用於快速的全文搜索, 一個索引由文檔中所有不重複的列表構成,對於每一個詞,都有一個包含它的文檔列表。 例如,現在有兩個文檔, 每個文檔包含如下內容:
Study every day, good good up to forever # 文檔1包含的內容
To forever, study every day, good good up # 文檔2包含的內容
爲了創建倒排索引,我們首先要將每個文檔拆分成獨立的詞(或稱爲詞條或者tokens),然後創建一個包含所有不重 復的詞條的排序列表,然後列出每個詞條出現在哪個文檔 :
term | doc_1 | doc_2 |
---|---|---|
Study | √ | x |
To | x | x |
every | √ | √ |
forever | √ | √ |
day | √ | √ |
study | x | √ |
good | √ | √ |
every | √ | √ |
to | √ | x |
up | √ | √ |
現在,我們試圖搜索 to forever,只需要查看包含每個詞條的文檔 score
term | doc_1 | doc_2 |
---|---|---|
to | √ | × |
forever | √ | √ |
total | 2 | 1 |
兩個文檔都匹配,但是第一個文檔比第二個匹配程度更高。如果沒有別的條件,現在,這兩個包含關鍵字的文檔都將返回。
再來看一個示例,比如我們通過博客標籤來搜索博客文章。那麼倒排索引列表就是這樣的一個結構 :
如果要搜索含有 python 標籤的文章,那相對於查找所有原始數據而言,查找倒排索引後的數據將會快的多。只需要 查看標籤這一欄,然後獲取相關的文章ID即可。完全過濾掉無關的所有數據,提高效率!
elasticsearch的索引和Lucene的索引對比
在elasticsearch中, 索引 (庫)這個詞被頻繁使用,這就是術語的使用。 在elasticsearch中,索引被分爲多個分片,每份 分片是一個Lucene的索引。所以一個elasticsearch索引是由多個Lucene索引組成的。別問爲什麼,誰讓elasticsearch使用Lucene作爲底層呢! 如無特指,說起索引都是指elasticsearch的索引。