學(xué)習(xí)文檔地址:https://www.elastic.co/guide/cn/elasticsearch/guide/current/intro.html
基礎(chǔ)入門/你知道的,為了搜索.../索引員工文檔
一個 Elasticsearch 集群可以包含多個索引 空镜,每個索引可以包含多個類型 椭豫。這些不同的類型存儲著多個文檔 ,每個文檔又有多個屬性 蚓土。
索引在不同語境下的含義:
索引(名詞):
一個索引類似于傳統(tǒng)關(guān)系數(shù)據(jù)庫中的一個數(shù)據(jù)庫 ,是一個存儲關(guān)系型文檔的地方赖淤。 索引 (index) 的復(fù)數(shù)詞為 indices 或 indexes 蜀漆。
索引(動詞):
索引一個文檔就是存儲一個文檔到一個索引(名詞)中以便被檢索和查詢。這非常類似于 SQL 語句中的 INSERT 關(guān)鍵詞咱旱,除了文檔已存在時确丢,新文檔會替換舊文檔情況之外。
倒排索引:
關(guān)系型數(shù)據(jù)庫通過增加一個索引比如一個 B樹(B-tree)索引到指定的列上吐限,以便提升數(shù)據(jù)檢索速度鲜侥。Elasticsearch 和 Lucene 使用了一個叫做倒排索引的結(jié)構(gòu)來達(dá)到相同的目的。
基礎(chǔ)入門/你知道的诸典,為了搜索.../輕量搜索
我們使用下列請求來搜索索引庫為megacorp類型為employee所有文檔描函,一個搜索默認(rèn)返回十條結(jié)果:
GET /megacorp/employee/_search
基礎(chǔ)入門/你知道的,為了搜索.../使用查詢表達(dá)式搜索
使用 JSON 構(gòu)造了一個請求狐粱,查詢所有名為Smith的搜索:
GET /megacorp/employee/_search
{
"query" : {
"match" : {
"last_name" : "Smith"
}
}
}
基礎(chǔ)入門/你知道的舀寓,為了搜索.../全文搜索
Elasticsearch 默認(rèn)按照相關(guān)性得分排序,即每個文檔跟查詢的匹配程度肌蜻。如果搜索的屬性中包含了要搜索的內(nèi)容(注意這里不是全部匹配)
互墓,會在結(jié)果中展示。
基礎(chǔ)入門/你知道的宋欺,為了搜索.../短語搜索
找出一個屬性想要精確匹配一系列單詞或者短語 轰豆。(注意是一個屬性中胰伍,而且短語的單詞都是挨著的)。
基礎(chǔ)入門/你知道的酸休,為了搜索.../分布式特性
Elasticsearch 盡可能地屏蔽了分布式系統(tǒng)的復(fù)雜性骂租。這里列舉了一些在后臺自動執(zhí)行的操作:
分配文檔到不同的容器或分片中,文檔可以儲存在一個或多個節(jié)點(diǎn)中斑司。
按集群節(jié)點(diǎn)來均衡分配這些分片渗饮,從而對索引和搜索過程進(jìn)行負(fù)載均衡。
復(fù)制每個分片以支持?jǐn)?shù)據(jù)冗余宿刮,從而防止硬件故障導(dǎo)致的數(shù)據(jù)丟失互站。
將集群中任一節(jié)點(diǎn)的請求路由到存有相關(guān)數(shù)據(jù)的節(jié)點(diǎn)。
集群擴(kuò)容時無縫整合新節(jié)點(diǎn)僵缺,重新分配分片以便從離群節(jié)點(diǎn)恢復(fù)胡桃。
基礎(chǔ)入門/集群內(nèi)的原理/空集群
一個運(yùn)行中的 Elasticsearch 實(shí)例稱為一個節(jié)點(diǎn),而集群是由一個或者多個擁有相同 cluster.name 配置的節(jié)點(diǎn)組成磕潮, 它們共同承擔(dān)數(shù)據(jù)和負(fù)載的壓力翠胰。當(dāng)有節(jié)點(diǎn)加入集群中或者從集群中移除節(jié)點(diǎn)時,集群將會重新平均分布所有的數(shù)據(jù)自脯。
當(dāng)一個節(jié)點(diǎn)被選舉成為 主 節(jié)點(diǎn)時之景, 它將負(fù)責(zé)管理集群范圍內(nèi)的所有變更,例如增加膏潮、刪除索引锻狗,或者增加、刪除節(jié)點(diǎn)等焕参。
基礎(chǔ)入門/集群內(nèi)的原理/集群健康
green
所有的主分片和副本分片都正常運(yùn)行轻纪。
yellow
所有的主分片都正常運(yùn)行,但不是所有的副本分片都正常運(yùn)行叠纷。
red
有主分片沒能正常運(yùn)行桐磁。
基礎(chǔ)入門/集群內(nèi)的原理/添加索引
一個 分片 是一個底層的 工作單元 ,它僅保存了全部數(shù)據(jù)中的一部分讲岁。 而現(xiàn)在我們只需知道一個分片是一個 Lucene 的實(shí)例(?衬以?節(jié)點(diǎn)不是一個ES實(shí)例嗎缓艳??)看峻,以及它本身就是一個完整的搜索引擎阶淘。 我們的文檔被存儲和索引到分片內(nèi)。
Elasticsearch 是利用分片將數(shù)據(jù)分發(fā)到集群內(nèi)各處的互妓。分片是數(shù)據(jù)的容器溪窒,文檔保存在分片內(nèi)坤塞,分片又被分配到集群內(nèi)的各個節(jié)點(diǎn)里。
一個分片可以是 主 分片或者 副本 分片澈蚌。 索引內(nèi)任意一個文檔都?xì)w屬于一個主分片摹芙,所以主分片的數(shù)目決定著索引能夠保存的最大數(shù)據(jù)量。一個副本分片只是一個主分片的拷貝宛瞄。副本分片作為硬件故障時保護(hù)數(shù)據(jù)不丟失的冗余備份浮禾,并為搜索和返回文檔等讀操作提供服務(wù)。在索引建立的時候就已經(jīng)確定了主分片數(shù)份汗,但是副本分片數(shù)可以隨時修改盈电。
基礎(chǔ)入門/集群內(nèi)的原理/水平擴(kuò)容
主分片的數(shù)目在索引創(chuàng)建時就已經(jīng)確定了下來,定義了這個索引能夠 存儲的最大數(shù)據(jù)量杯活。 但是匆帚,讀操作——搜索和返回數(shù)據(jù)——可以同時被主分片或副本分片所處理,所以當(dāng)你擁有越多的副本分片時旁钧,也將擁有越高的吞吐量吸重。
基礎(chǔ)入門/數(shù)據(jù)輸入和輸出
JSON是一種以人可讀的文本表示對象的方法。當(dāng)一個對象被序列化成為 JSON均践,它被稱為一個 JSON 文檔 晤锹。
在 Elasticsearch 中, 每個字段的所有數(shù)據(jù) 都是 默認(rèn)被索引的 彤委。 即每個字段都有為了快速檢索設(shè)置的專用倒排索引鞭铆。
基礎(chǔ)入門/數(shù)據(jù)輸入和輸出/文檔元數(shù)據(jù)
一個文檔不僅僅包含它的數(shù)據(jù) ,也包含 元數(shù)據(jù) —— 有關(guān) 文檔的信息焦影。 三個必須的元數(shù)據(jù)元素如下:
_index
文檔在哪存放
_type
文檔表示的對象類別
_id
文檔唯一標(biāo)識
基礎(chǔ)入門/數(shù)據(jù)輸入和輸出/索引文檔
一個文檔的 _index 车遂、 _type 和 _id 唯一標(biāo)識一個文檔,_id 可以自定義:
PUT /{index}/{type}/{id}
{
"field": "value",
...
}
在 Elasticsearch 中每個文檔都有一個版本號斯辰。當(dāng)每次對文檔進(jìn)行修改時(包括刪除)舶担, _version 的值會遞增。
如果你的數(shù)據(jù)沒有自然的 ID彬呻, Elasticsearch 可以幫我們自動生成 ID 衣陶。 請求的結(jié)構(gòu)調(diào)整為: 不再使用 PUT 謂詞, 而是使用 POST 謂詞闸氮。
POST /{index}/{type}
{
"field": "value",
...
}
基礎(chǔ)入門/數(shù)據(jù)輸入和輸出/取回一個文檔
GET /website/blog/123?pretty
返回文檔的一部分:
GET /website/blog/123?_source=title,text
只想得到 _source 字段剪况,不需要任何元數(shù)據(jù):
GET /website/blog/123/_source
基礎(chǔ)入門/數(shù)據(jù)輸入和輸出/更新整個文檔
在 Elasticsearch 中文檔是不可改變的。相反蒲跨,如果想要更新現(xiàn)有的文檔译断,需要重建索引或者進(jìn)行替換。
PUT /website/blog/123
{
"title": "My first blog entry",
...
}
基礎(chǔ)入門/數(shù)據(jù)輸入和輸出/創(chuàng)建新文檔
已有自己的_id或悲,只有在相同的 _index 孙咪、 _type 和 _id 不存在時才接受我們的索引請求堪唐,兩種方式:
PUT /website/blog/123?op_type=create
{ ... }
PUT /website/blog/123/_create
{ ... }
基礎(chǔ)入門/數(shù)據(jù)輸入和輸出/刪除文檔
DELETE /website/blog/123
基礎(chǔ)入門/數(shù)據(jù)輸入和輸出/處理沖突
悲觀并發(fā)控制
這種方法被關(guān)系型數(shù)據(jù)庫廣泛使用,它假定有變更沖突可能發(fā)生翎蹈,因此阻塞訪問資源以防止沖突淮菠。 一個典型的例子是讀取一行數(shù)據(jù)之前先將其鎖住,確保只有放置鎖的線程能夠?qū)@行數(shù)據(jù)進(jìn)行修改杨蛋。
樂觀并發(fā)控制
Elasticsearch 中使用的這種方法假定沖突是不可能發(fā)生的兜材,并且不會阻塞正在嘗試的操作。 然而逞力,如果源數(shù)據(jù)在讀寫當(dāng)中被修改曙寡,更新將會失敗。應(yīng)用程序接下來將決定該如何解決沖突寇荧。 例如举庶,可以重試更新、使用新的數(shù)據(jù)揩抡、或者將相關(guān)情況報告給用戶户侥。
基礎(chǔ)入門/數(shù)據(jù)輸入和輸出/文檔的部分更新
我們也介紹過文檔是不可變的:他們不能被修改,只能被替換峦嗤。 update API 必須遵循同樣的規(guī)則蕊唐。 從外部來看,我們在一個文檔的某個位置進(jìn)行部分更新烁设。然而在內(nèi)部替梨, update API 簡單使用與之前描述相同的 檢索-修改-重建索引 的處理過程。
基礎(chǔ)入門/分布式文檔存儲/路由一個文檔到分片中
shard = hash(routing) % number_of_primary_shards
routing 是一個可變值装黑,默認(rèn)是文檔的 _id 副瀑,也可以設(shè)置成一個自定義的值。 routing 通過 hash 函數(shù)生成一個數(shù)字恋谭,然后這個數(shù)字再除以 number_of_primary_shards (主分片的數(shù)量)后得到 余數(shù) 糠睡。這個分布在 0 到 number_of_primary_shards-1 之間的余數(shù),就是我們所尋求的文檔所在分片的位置疚颊。
基礎(chǔ)入門/分布式文檔存儲/主分片和父分片如何交互
我們可以發(fā)送請求到集群中的任一節(jié)點(diǎn)狈孔。 每個節(jié)點(diǎn)都有能力處理任意請求。 每個節(jié)點(diǎn)都知道集群中任一文檔位置材义,所以可以直接將請求轉(zhuǎn)發(fā)到需要的節(jié)點(diǎn)上除抛。
基礎(chǔ)入門/搜索
Elasticsearch 不只會存儲(stores)文檔,為了能被搜索到也會為文檔母截。
搜索重要概念:
添加索引(indexes)
映射(Mapping)
描述數(shù)據(jù)在每個字段內(nèi)如何存儲
分析(Analysis)
全文是如何處理使之可以被搜索的
領(lǐng)域特定查詢語言(Query DSL)
Elasticsearch 中強(qiáng)大靈活的查詢語言
基礎(chǔ)入門/搜索/空搜索
返回集群中所有索引的文檔:
GET /_search
hits
hits它包含total字段來表示匹配到的文檔總數(shù),并且一個 hits數(shù)組包含所查詢結(jié)果的前十個文檔橄教。
在 hits 數(shù)組中每個結(jié)果包含文檔的** _index 清寇、 _type 喘漏、 _id ,加上 _source 字段华烟。
每個結(jié)果還有一個 _score 翩迈,它衡量了文檔與查詢的匹配程度**。默認(rèn)情況下盔夜,首先返回最相關(guān)的文檔結(jié)果负饲,就是說,返回的文檔是按照 _score 降序排列的喂链。
max_score 值是與查詢所匹配文檔的 _score 的最大值返十。
_shards 部分告訴我們在查詢中參與分片的總數(shù),以及這些分片成功了多少個失敗了多少個椭微。
基礎(chǔ)入門/搜索/多索引洞坑,多類型
/gb,us/user,tweet/_search
在 gb 和 us 索引中搜索 user 和 tweet 類型
基礎(chǔ)入門/搜索/輕量搜索
查詢在 tweet 類型中 tweet 字段包含 elasticsearch 單詞的所有文檔:
GET /_all/tweet/_search?q=tweet:elasticsearch
返回包含 mary 的所有文檔:
GET /_search?q=mary
當(dāng)索引一個文檔的時候,Elasticsearch 取出所有字段的值拼接成一個大的字符串蝇率,作為 _all 字段進(jìn)行索引迟杂。
基礎(chǔ)入門/映射和分析/分析與分析器
分析器 實(shí)際上是將三個功能封裝到了一個包里:
字符過濾器:
首先,字符串按順序通過每個 字符過濾器 本慕。他們的任務(wù)是在分詞前整理字符串排拷。一個字符過濾器可以用來去掉HTML,或者將 &
轉(zhuǎn)化成 and
锅尘。
分詞器:
其次监氢,字符串被 分詞器 分為單個的詞條。一個簡單的分詞器遇到空格和標(biāo)點(diǎn)的時候鉴象,可能會將文本拆分成詞條忙菠。
Token 過濾器:
最后,詞條按順序通過每個 token 過濾器纺弊。這個過程可能會改變詞條(例如牛欢,小寫化 Quick
),刪除詞條(例如淆游, 像 a
傍睹, and
, the
等無用詞)犹菱,或者增加詞條(例如拾稳,像 jump
和 leap
這種同義詞)。
基礎(chǔ)入門/映射和分析/映射
為了能夠?qū)r間域視為時間腊脱,數(shù)字域視為數(shù)字访得,字符串域視為全文或精確值字符串, Elasticsearch 需要知道每個域中數(shù)據(jù)的類型。這個信息包含在映射中悍抑。
簡單域類型:
字符串: string
整數(shù) : byte, short, integer, long
浮點(diǎn)數(shù): float, double
布爾型: boolean
日期: date
默認(rèn)鳄炉, string 類型域會被認(rèn)為包含全文。就是說搜骡,它們的值在索引前拂盯,會通過一個分析器,針對于這個域的查詢在搜索前也會經(jīng)過一個分析器记靡。
string 域映射的兩個最重要屬性是 index 和 analyzer
index 屬性控制怎樣索引字符串谈竿。它可以是下面三個值:
analyzed
首先分析字符串,然后索引它摸吠。換句話說空凸,以全文索引這個域。
not_analyzed
索引這個域蜕便,所以它能夠被搜索劫恒,但索引的是精確值。不會對它進(jìn)行分析轿腺。
no
不索引這個域两嘴。這個域不會被搜索到。
對于 analyzed 字符串域族壳,用 analyzer 屬性指定在搜索和索引時使用的分析器憔辫。默認(rèn), Elasticsearch 使用 standard 分析器仿荆, 但你可以指定一個內(nèi)置的分析器替代它贰您,例如 whitespace 、 simple 和 english拢操。
基礎(chǔ)入門/映射和分析/復(fù)雜核心域類型
復(fù)雜核心域類型:JSON 還有 null 值锦亦,數(shù)組,和對象
Lucene 不理解內(nèi)部對象令境。 Lucene 文檔是由一組鍵值對列表組成的杠园。為了能讓 Elasticsearch 有效地索引內(nèi)部類,它把我們的文檔轉(zhuǎn)化成這樣:
{
"tweet": [elasticsearch, flexible, very],
"user.id": [@johnsmith],
"user.gender": [male],
"user.age": [26],
"user.name.full": [john, smith],
"user.name.first": [john],
"user.name.last": [smith]
}
基礎(chǔ)入門/請求體查詢/空查詢
空查詢將返回所有索引庫(indices)中的所有文檔:
GET /_search
{}
基礎(chǔ)入門/請求體查詢/查詢表達(dá)式
一個簡單的查詢:查詢 tweet 字段中包含 elasticsearch 的文檔
GET /_search
{
"query": {
"match": {舔庶?
"tweet": "elasticsearch"
}
}
}
復(fù)雜一點(diǎn)的查詢:復(fù)合(Compound) 語句 主要用于 合并其它查詢語句:
{
"bool": {
"must": { "match": { "tweet": "elasticsearch" }},
"must_not": { "match": { "name": "mary" }},
"should": { "match": { "tweet": "full text" }},
"filter": { "range": { "age" : { "gt" : 30 }} }
}
}
基礎(chǔ)入門/請求體查詢/查詢與過濾
過濾(filter):
查詢被設(shè)置成一個“不評分”或者“過濾”查詢抛蚁。回答也是非常的簡單惕橙,yes 或者 no 瞧甩,二者必居其一。
查詢(query):
查詢就變成了一個“評分”的查詢弥鹦。和不評分的查詢類似肚逸,也要去判斷這個文檔是否匹配,同時它還需要判斷這個文檔匹配的有 多好(匹配程度如何)。
基礎(chǔ)入門/請求體查詢/最重要的查詢
match_all查詢:簡單的匹配所有文檔朦促。在沒有指定查詢方式時犬钢,它是默認(rèn)的查詢。
match查詢:
如果你在一個全文字段上使用 match 查詢思灰,在執(zhí)行查詢前,它將用正確的分析器去分析查詢字符串混滔。
如果在一個精確值的字段上使用它洒疚,例如數(shù)字、日期坯屿、布爾或者一個 not_analyzed 字符串字段油湖,那么它將會精確匹配給定的值。
對于精確值的查詢领跛,你可能需要使用 filter 語句來取代 query乏德,因?yàn)?filter 將會被緩存。
multi_match查詢:可以在多個字段上執(zhí)行相同的 match 查詢吠昭。
{
"multi_match": {
"query": "full text search",
"fields": [ "title", "body" ]
}
}
range查詢:找出那些落在指定區(qū)間內(nèi)的數(shù)字或者時間喊括。
term查詢:被用于精確值匹配,這些精確值可能是數(shù)字矢棚、時間郑什、布爾或者那些 not_analyzed 的字符串。
{ "term": { "age": 26 }}
{ "term": { "date": "2014-09-01" }}
terms查詢:和 term 查詢一樣蒲肋,但它允許你指定多值進(jìn)行匹配蘑拯。如果這個字段包含了指定值中的任何一個值,那么這個文檔滿足條件兜粘。
exists查詢和 missing查詢:被用于查找那些指定字段中有值 (exists) 或無值 (missing) 的文檔申窘。
基礎(chǔ)入門/請求體查詢/組合多查詢
你可以用 bool 查詢來實(shí)現(xiàn)你的需求。這種查詢將多查詢組合在一起孔轴,成為用戶自己想要的布爾查詢剃法。它接收以下參數(shù):
must
文檔 必須 匹配這些條件才能被包含進(jìn)來。
must_not
文檔 必須不 匹配這些條件才能被包含進(jìn)來距糖。
should
如果滿足這些語句中的任意語句玄窝,將增加 _score ,否則悍引,無任何影響恩脂。它們主要用于修正每個文檔的相關(guān)性得分。
filter
必須 匹配趣斤,但它以不評分俩块、過濾模式來進(jìn)行。這些語句對評分沒有貢獻(xiàn),只是根據(jù)過濾標(biāo)準(zhǔn)來排除或包含文檔玉凯。