Elasticsearch

為什么需要ES

回憶時(shí)光

許多年前瓶殃,一個(gè)剛結(jié)婚的名叫 Shay Banon 的失業(yè)開(kāi)發(fā)者,跟著他的妻子去了倫敦副签,他的妻子在那里學(xué)習(xí)廚師遥椿。 在尋找一個(gè)賺錢(qián)的工作的時(shí)候,為了給他的妻子做一個(gè)食譜搜索引擎淆储,他開(kāi)始使用 Lucene 的一個(gè)早期版本冠场。
直接使用 Lucene 是很難的,因此 Shay 開(kāi)始做一個(gè)抽象層本砰,Java 開(kāi)發(fā)者使用它可以很簡(jiǎn)單的給他們的程序添加搜索功能碴裙。 他發(fā)布了他的第一個(gè)開(kāi)源項(xiàng)目 Compass。
后來(lái) Shay 獲得了一份工作点额,主要是高性能舔株,分布式環(huán)境下的內(nèi)存數(shù)據(jù)網(wǎng)格。這個(gè)對(duì)于高性能还棱,實(shí)時(shí)载慈,分布式搜索引擎的需求尤為突出, 他決定重寫(xiě) Compass珍手,把它變?yōu)橐粋€(gè)獨(dú)立的服務(wù)并取名 Elasticsearch办铡。
第一個(gè)公開(kāi)版本在2010年2月發(fā)布辞做,從此以后,Elasticsearch 已經(jīng)成為了 Github 上最活躍的項(xiàng)目之一寡具,他擁有超過(guò)300名 contributors(目前736名 contributors )秤茅。 一家公司已經(jīng)開(kāi)始圍繞 Elasticsearch 提供商業(yè)服務(wù),并開(kāi)發(fā)新的特性童叠,但是框喳,Elasticsearch 將永遠(yuǎn)開(kāi)源并對(duì)所有人可>用。

據(jù)說(shuō)拯钻,Shay 的妻子還在等著她的食譜搜索引擎…

學(xué)習(xí)了基礎(chǔ)的搜索引擎原理 我進(jìn)而想到大量的數(shù)據(jù)都是存放在哪里的呢? 為了快速查詢數(shù)據(jù)結(jié)構(gòu)必然發(fā)生變化,是不是需要有特殊存儲(chǔ)方式呢? 嘗試思考如下幾種方式來(lái)實(shí)現(xiàn).

Sql

對(duì)于關(guān)系型數(shù)據(jù)帖努,我們通常采用以下或類(lèi)似架構(gòu)去解決查詢瓶頸和寫(xiě)入瓶頸(拆表):
1.通過(guò)主從備份解決數(shù)據(jù)安全性問(wèn)題;
2.通過(guò)數(shù)據(jù)庫(kù)代理中間件心跳監(jiān)測(cè)粪般,解決單點(diǎn)故障問(wèn)題;
3.通過(guò)代理中間件將查詢語(yǔ)句分發(fā)到各個(gè)slave節(jié)點(diǎn)進(jìn)行查詢污桦,并匯總結(jié)果

NoSql

對(duì)于Nosql數(shù)據(jù)庫(kù)亩歹,以mongodb為例,其它原理類(lèi)似:
1.通過(guò)副本備份保證數(shù)據(jù)安全性凡橱;
2.通過(guò)節(jié)點(diǎn)競(jìng)選機(jī)制解決單點(diǎn)問(wèn)題小作;
3.先從配置庫(kù)檢索分片信息,然后將請(qǐng)求分發(fā)到各個(gè)節(jié)點(diǎn)稼钩,最后由路由節(jié)點(diǎn)合并匯總結(jié)果

內(nèi)存

但把大量數(shù)據(jù)存在內(nèi)存中并不靠譜,原因是內(nèi)存成本太高了.尤其是對(duì)于搜索引擎來(lái)說(shuō)需要存大量的數(shù)據(jù).內(nèi)存存儲(chǔ)的解決方案,例如redis還是主要用來(lái)做高數(shù)緩存的,以此來(lái)做數(shù)據(jù)庫(kù)就不合適了.

為解決以上問(wèn)題顾稀,從源頭著手分析,通常會(huì)從以下方式來(lái)尋找方法:
1.存儲(chǔ)數(shù)據(jù)時(shí)按有序存儲(chǔ)坝撑;
2.將數(shù)據(jù)和索引分離静秆;
3.壓縮數(shù)據(jù);

而這就引出了Elasticsearch巡李。


ES基礎(chǔ)

ES是elaticsearch簡(jiǎn)寫(xiě)抚笔, Elasticsearch是一個(gè)開(kāi)源的高擴(kuò)展的分布式全文檢索引擎,它可以近乎實(shí)時(shí)的存儲(chǔ)侨拦、檢索數(shù)據(jù)殊橙;本身擴(kuò)展性很好,可以擴(kuò)展到上百臺(tái)服務(wù)器狱从,處理PB級(jí)別的數(shù)據(jù)膨蛮。
Elasticsearch也使用Java開(kāi)發(fā)并使用Lucene作為其核心來(lái)實(shí)現(xiàn)所有索引和搜索的功能,但是它的目的是通過(guò)簡(jiǎn)單的RESTful API來(lái)隱藏Lucene的復(fù)雜性季研,從而讓全文搜索變得簡(jiǎn)單敞葛。

Lucene & elaticsearch

簡(jiǎn)化Lucene 使用

對(duì)于Lucene可以看: Lucene 入門(mén)

這里提到了Lucene 是什么呢? 它就是我們想找的那個(gè)特殊的存儲(chǔ)結(jié)構(gòu),但是想要使用它训貌,你必須使用Java來(lái)作為開(kāi)發(fā)語(yǔ)言并將其直接集成到你的應(yīng)用中制肮,更糟糕的是冒窍,Lucene非常復(fù)雜,你需要深入了解檢索的相關(guān)知識(shí)來(lái)理解它是如何工作的豺鼻。

而ES類(lèi)似于netty框架幫我們封裝了復(fù)雜的Nio實(shí)現(xiàn) 他使用Java開(kāi)發(fā)并使用Lucene作為其核心來(lái)實(shí)現(xiàn)所有索引和搜索的功能,他提供了簡(jiǎn)單的RESTful API來(lái)隱藏Lucene的復(fù)雜性综液,從而讓全文搜索變得簡(jiǎn)單。

ES做了什么

1.檢索相關(guān)數(shù)據(jù)儒飒;
2.返回統(tǒng)計(jì)結(jié)果谬莹;
3.速度要快。

優(yōu)點(diǎn):

  1. 分布式實(shí)時(shí)文件存儲(chǔ)桩了,可將每一個(gè)字段存入索引附帽,使其可以被檢索到。
  2. 實(shí)時(shí)分析的分布式搜索引擎井誉。
    分布式:索引分拆成多個(gè)分片蕉扮,每個(gè)分片可有零個(gè)或多個(gè)副本。集群中的每個(gè)數(shù)據(jù)節(jié)點(diǎn)都可承載一個(gè)或多個(gè)分片颗圣,并且協(xié)調(diào)和處理各種操作喳钟;
    負(fù)載再平衡和路由在大多數(shù)情況下自動(dòng)完成。
  3. 可以擴(kuò)展到上百臺(tái)服務(wù)器在岂,處理PB級(jí)別的結(jié)構(gòu)化或非結(jié)構(gòu)化數(shù)據(jù)奔则。也可以運(yùn)行在單臺(tái)PC上(已測(cè)試)
  4. 支持插件機(jī)制,分詞插件蔽午、同步插件易茬、Hadoop插件、可視化插件等及老。

原理

首先和我們熟悉的mysql對(duì)比一下:

對(duì)比
  1. 關(guān)系型數(shù)據(jù)庫(kù)中的數(shù)據(jù)庫(kù)(DataBase)抽莱,等價(jià)于ES中的索引(Index)
  2. 一個(gè)數(shù)據(jù)庫(kù)下面有N張表(Table),等價(jià)于1個(gè)索引Index下面有N多類(lèi)型(Type)
  3. 一個(gè)數(shù)據(jù)庫(kù)表(Table)下的數(shù)據(jù)由多行(ROW)多列(column写半,屬性)組成岸蜗,等價(jià)于1個(gè)Type由多個(gè)文檔(Document)和多Field組成。
  4. 在一個(gè)關(guān)系型數(shù)據(jù)庫(kù)里面叠蝇,schema定義了表璃岳、每個(gè)表的字段,還有表和字段之間的關(guān)系悔捶。 與之對(duì)應(yīng)的铃慷,在ES中:Mapping定義索引下的Type的字段處理規(guī)則,即索引如何建立蜕该、索引類(lèi)型犁柜、是否保存原始索引JSON文檔、是否壓縮原始JSON文檔堂淡、是否需要分詞處理馋缅、如何進(jìn)行分詞處理等扒腕。
  5. 在數(shù)據(jù)庫(kù)中的增insert、刪delete萤悴、改update瘾腰、查search操作等價(jià)于ES中的增PUT/POST、刪Delete覆履、改_update蹋盆、查GET.

進(jìn)一步理解

Elasticsearch是面向文檔型數(shù)據(jù)庫(kù),一條數(shù)據(jù)在這里就是一個(gè)文檔硝全,用JSON作為文檔序列化的格式

{
    "name" :     "John",
    "sex" :      "Male",
    "age" :      25,
    "birthDate": "1990/05/01",
    "about" :    "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}

而如果是mysql呢?

用MySQL這樣的數(shù)據(jù)庫(kù)存儲(chǔ)就會(huì)容易想到建立一張User表栖雾,有balabala的字段等,在Elasticsearch里這就是一個(gè)文檔伟众,當(dāng)然這個(gè)文檔會(huì)屬于一個(gè)User的類(lèi)型析藕,各種各樣的類(lèi)型存在于一個(gè)索引當(dāng)中。這里有一份簡(jiǎn)易的將Elasticsearch和關(guān)系型數(shù)據(jù)術(shù)語(yǔ)對(duì)照表:

關(guān)系數(shù)據(jù)庫(kù) ? 數(shù)據(jù)庫(kù) ? 表 ? 行 ? 列(Columns)
Elasticsearch ? 索引 ? 類(lèi)型 ? 文檔 ? 字段(Fields)

一個(gè) Elasticsearch 集群可以包含多個(gè)索引(數(shù)據(jù)庫(kù))凳厢,也就是說(shuō)其中包含了很多類(lèi)型(表)噪径。這些類(lèi)型中包含了很多的文檔(行),然后每個(gè)文檔中又包含了很多的字段(列)数初。

Elasticsearch的交互,可以使用Java API梗顺,也可以直接使用HTTP的Restful API方式泡孩,比如我們打算插入一條記錄,可以簡(jiǎn)單發(fā)送一個(gè)HTTP的請(qǐng)求:

PUT /megacorp/employee/1
{
    "name" :     "John",
    "sex" :      "Male",
    "age" :      25,
    "about" :    "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}

其有一下幾個(gè)核心點(diǎn):

Cluster:集群寺谤。

ES可以作為一個(gè)獨(dú)立的單個(gè)搜索服務(wù)器仑鸥。不過(guò),為了處理大型數(shù)據(jù)集变屁,實(shí)現(xiàn)容錯(cuò)和高可用性眼俊,ES可以運(yùn)行在許多互相合作的服務(wù)器上。這些服務(wù)器的集合稱(chēng)為集群粟关。

Node:節(jié)點(diǎn)疮胖。

形成集群的每個(gè)服務(wù)器稱(chēng)為節(jié)點(diǎn)。

Shard:分片闷板。

當(dāng)有大量的文檔時(shí)澎灸,由于內(nèi)存的限制、磁盤(pán)處理能力不足遮晚、無(wú)法足夠快的響應(yīng)客戶端的請(qǐng)求等性昭,一個(gè)節(jié)點(diǎn)可能不夠。這種情況下县遣,數(shù)據(jù)可以分為較小的分片糜颠。每個(gè)分片放到不同的服務(wù)器上汹族。
當(dāng)你查詢的索引分布在多個(gè)分片上時(shí),ES會(huì)把查詢發(fā)送給每個(gè)相關(guān)的分片其兴,并將結(jié)果組合在一起顶瞒,而應(yīng)用程序并不知道分片的存在。即:這個(gè)過(guò)程對(duì)用戶來(lái)說(shuō)是透明的忌警。

Replia:副本搁拙。

為提高查詢吞吐量或?qū)崿F(xiàn)高可用性,可以使用分片副本法绵。
副本是一個(gè)分片的精確復(fù)制箕速,每個(gè)分片可以有零個(gè)或多個(gè)副本。ES中可以有許多相同的分片朋譬,其中之一被選擇更改索引操作盐茎,這種特殊的分片稱(chēng)為主分片。
當(dāng)主分片丟失時(shí)徙赢,如:該分片所在的數(shù)據(jù)不可用時(shí)字柠,集群將副本提升為新的主分片。

全文檢索狡赐。

全文檢索就是對(duì)一篇文章進(jìn)行索引窑业,可以根據(jù)關(guān)鍵字搜索,類(lèi)似于mysql里的like語(yǔ)句枕屉。
全文索引就是把內(nèi)容根據(jù)詞的意義進(jìn)行分詞常柄,然后分別創(chuàng)建索引,例如”你們的激情是因?yàn)槭裁词虑閬?lái)的” 可能會(huì)被分詞成:“你們“搀擂,”激情“西潘,“什么事情“,”來(lái)“ 等token哨颂,這樣當(dāng)你搜索“你們” 或者 “激情” 都會(huì)把這句搜出來(lái)喷市。


數(shù)據(jù)結(jié)構(gòu)

主要就是其索引的建立思路

將磁盤(pán)里的東西盡量搬進(jìn)內(nèi)存,減少磁盤(pán)隨機(jī)讀取次數(shù)(同時(shí)也利用磁盤(pán)順序讀特性)威恼,結(jié)合各種奇技淫巧的壓縮算法品姓,用及其苛刻的態(tài)度使用內(nèi)存。
并且其一切設(shè)計(jì)都是為了提高搜索的性能 其余的部分肯定會(huì)有犧牲,比如插入/更新

倒排索引

這就要引出其核心數(shù)據(jù)結(jié)構(gòu)倒排索引了 對(duì)于其的簡(jiǎn)單理解可以先看一下之前的博客#搜索引擎入門(mén) 這里結(jié)合ES詳細(xì)介紹一下:

繼續(xù)上面的例子沃测,假設(shè)有這么幾條數(shù)據(jù)(為了簡(jiǎn)單缭黔,去掉about, interests這兩個(gè)field):

ID Name Age Sex
1 Kate 24 Female
2 John 24 Male
3 Bill 29 Male

ID是Elasticsearch自建的文檔id,那么Elasticsearch建立的索引如下:

Name:

Term Posting List
Kate 1
John 2
Bill 3

Age:

Term Posting List
24 [1,2]
29 3

Sex:

Term Posting List
Female 1
Male [2,3]
Posting List

Elasticsearch分別為每個(gè)field都建立了一個(gè)倒排索引蒂破,Kate, John, 24, Female這些叫term馏谨,而[1,2]就是Posting List。Posting list就是一個(gè)int的數(shù)組附迷,存儲(chǔ)了所有符合某個(gè)term的文檔id惧互。

接下來(lái)才是關(guān)鍵:

通過(guò)posting list這種索引方式似乎可以很快進(jìn)行查找哎媚,比如要找age=24的同學(xué),愛(ài)回答問(wèn)題的小明馬上就舉手回答:我知道喊儡,id是1拨与,2的同學(xué)。但是艾猜,如果這里有上千萬(wàn)的記錄呢买喧?如果是想通過(guò)name來(lái)查找呢?

Term Dictionary

Elasticsearch為了能快速找到某個(gè)term匆赃,將所有的term排個(gè)序淤毛,二分法查找term,logN的查找效率算柳,就像通過(guò)字典查找一樣低淡,這就是Term Dictionary。現(xiàn)在再看起來(lái)瞬项,似乎和傳統(tǒng)數(shù)據(jù)庫(kù)通過(guò)B-Tree的方式類(lèi)似啊蔗蹋,為什么說(shuō)比B-Tree的查詢快呢?

Term Index

B-Tree通過(guò)減少磁盤(pán)尋道次數(shù)來(lái)提高查詢性能囱淋,Elasticsearch也是采用同樣的思路猪杭,直接通過(guò)內(nèi)存查找term,不讀磁盤(pán)妥衣,但是如果term太多胁孙,term dictionary也會(huì)很大,放內(nèi)存不現(xiàn)實(shí)称鳞,于是有了Term Index,就像字典里的索引頁(yè)一樣稠鼻,A開(kāi)頭的有哪些term冈止,分別在哪頁(yè),可以理解term index是一顆樹(shù):

這棵樹(shù)不會(huì)包含所有的term候齿,它包含的是term的一些前綴熙暴。通過(guò)term index可以快速地定位到term dictionary的某個(gè)offset,然后從這個(gè)位置再往后順序查找慌盯。

所以term index不需要存下所有的term周霉,而僅僅是他們的一些前綴與Term Dictionary的block之間的映射關(guān)系,再結(jié)合FST(Finite State Transducers)的壓縮技術(shù)亚皂,可以使term index緩存到內(nèi)存中俱箱。從term index查到對(duì)應(yīng)的term dictionary的block位置之后,再去磁盤(pán)上找term灭必,大大減少了磁盤(pán)隨機(jī)讀的次數(shù)狞谱。

而FST是什么呢?

FSTs are finite-state machines that map a term (byte sequence) to an arbitrary output.

假設(shè)我們現(xiàn)在要將mop, moth, pop, star, stop and top(term index里的term前綴)映射到序號(hào):0乃摹,1,2跟衅,3孵睬,4,5(term dictionary的block位置)伶跷。最簡(jiǎn)單的做法就是定義個(gè)Map<String, Integer>掰读,大家找到自己的位置對(duì)應(yīng)入座就好了,但從內(nèi)存占用少的角度想想叭莫,有沒(méi)有更優(yōu)的辦法呢蹈集?答案就是:FST

O表示一種狀態(tài)

->表示狀態(tài)的變化過(guò)程,上面的字母/數(shù)字表示狀態(tài)變化和權(quán)重

將單詞分成單個(gè)字母通過(guò)O–>表示出來(lái)食寡,0權(quán)重不顯示雾狈。如果O后面出現(xiàn)分支,就標(biāo)記權(quán)重抵皱,最后整條路徑上的權(quán)重加起來(lái)就是這個(gè)單詞對(duì)應(yīng)的序號(hào)善榛。

FST以字節(jié)的方式存儲(chǔ)所有的term,這種壓縮方式可以有效的縮減存儲(chǔ)空間呻畸,使得term index足以放進(jìn)內(nèi)存移盆,但這種方式也會(huì)導(dǎo)致查找時(shí)需要更多的CPU資源。

壓縮

我們學(xué)習(xí)mysql的時(shí)候肯定知道 如果某個(gè)數(shù)據(jù)列包含許多重復(fù)的內(nèi)容伤为,為它建立索引就沒(méi)有太大的實(shí)際效果咒循。
但對(duì)于搜索來(lái)說(shuō)總不能不讓用戶搜索這種字段吧,例如男/女這樣的. ES對(duì)于這種索引就會(huì)進(jìn)行壓縮.

壓縮方法
ES為了壓縮索引真的是不擇手段。在壓縮過(guò)程中使用如下技巧,它會(huì)按依次檢測(cè)以下壓縮模式:

  1. 如果所有的數(shù)值各不相同(或缺失)绞愚,設(shè)置一個(gè)標(biāo)記并記錄這些值
  2. 如果這些值小于 256叙甸,將使用一個(gè)簡(jiǎn)單的編碼表
  3. 如果這些值大于 256,檢測(cè)是否存在一個(gè)最大公約數(shù)
  4. 如果沒(méi)有存在最大公約數(shù)位衩,從最小的數(shù)值開(kāi)始裆蒸,統(tǒng)一計(jì)算偏移量(增量)進(jìn)行編碼
Frame Of Reference

增量編碼壓縮,將大數(shù)變小數(shù)糖驴,按字節(jié)存儲(chǔ)

首先僚祷,Elasticsearch要求posting list是有序的(為了提高搜索的性能,再任性的要求也得滿足)贮缕,這樣做的一個(gè)好處是方便壓縮辙谜,看下面這個(gè)圖例:


如果數(shù)學(xué)不是體育老師教的話,還是比較容易看出來(lái)這種壓縮技巧的感昼。

原理就是通過(guò)增量装哆,將原來(lái)的大數(shù)變成小數(shù)僅存儲(chǔ)增量值,再精打細(xì)算按bit排好隊(duì),最后通過(guò)字節(jié)存儲(chǔ)烂琴,而不是大大咧咧的盡管是2也是用int(4個(gè)字節(jié))來(lái)存儲(chǔ)爹殊。

Roaring bitmaps

說(shuō)到Roaring bitmaps,就必須先從bitmap說(shuō)起奸绷。Bitmap是一種數(shù)據(jù)結(jié)構(gòu)梗夸,假設(shè)有某個(gè)posting list:
[1,3,4,7,10]
對(duì)應(yīng)的bitmap就是:
[1,0,1,1,0,0,1,0,0,1]

非常直觀,用0/1表示某個(gè)值是否存在号醉,比如10這個(gè)值就對(duì)應(yīng)第10位反症,對(duì)應(yīng)的bit值是1,這樣用一個(gè)字節(jié)就可以代表8個(gè)文檔id畔派,舊版本(5.0之前)的Lucene就是用這樣的方式來(lái)壓縮的铅碍,但這樣的壓縮方式仍然不夠高效,如果有1億個(gè)文檔线椰,那么需要12.5MB的存儲(chǔ)空間胞谈,這僅僅是對(duì)應(yīng)一個(gè)索引字段(我們往往會(huì)有很多個(gè)索引字段)。于是有人想出了Roaring bitmaps這樣更高效的數(shù)據(jù)結(jié)構(gòu)憨愉。

Bitmap的缺點(diǎn)是存儲(chǔ)空間隨著文檔個(gè)數(shù)線性增長(zhǎng)烦绳,Roaring bitmaps需要打破這個(gè)魔咒就一定要用到某些指數(shù)特性:

將posting list按照65535為界限分塊,比如第一塊所包含的文檔id范圍在0~65535之間配紫,第二塊的id范圍是65536~131071径密,以此類(lèi)推。再用<商躺孝,余數(shù)>的組合表示每一組id享扔,這樣每組里的id范圍都在0~65535內(nèi)了,剩下的就好辦了植袍,既然每組id不會(huì)變得無(wú)限大惧眠,那么我們就可以通過(guò)最有效的方式對(duì)這里的id存儲(chǔ)。

為什么是以65535為界限?

程序員的世界里除了1024外于个,65535也是一個(gè)經(jīng)典值锉试,因?yàn)樗?2^16-1,正好是用2個(gè)字節(jié)能表示的最大數(shù)览濒,一個(gè)short的存儲(chǔ)單位,注意到上圖里的最后一行“If a block has more than 4096 values, encode as a bit set, and otherwise as a simple array using 2 bytes per value”拖云,如果是大塊贷笛,用節(jié)省點(diǎn)用bitset存,小塊就豪爽點(diǎn)宙项,2個(gè)字節(jié)我也不計(jì)較了乏苦,用一個(gè)short[]存著方便。

那為什么用4096來(lái)區(qū)分采用數(shù)組還是bitmap的閥值呢?

這個(gè)是從內(nèi)存大小考慮的汇荐,當(dāng)block塊里元素超過(guò)4096后洞就,用bitmap更剩空間: 采用bitmap需要的空間是恒定的: 65536/8 = 8192bytes 而如果采用short[]掀淘,所需的空間是: 2*N(N為數(shù)組元素個(gè)數(shù)) N=4096剛好是邊界:


你也許會(huì)想 "好吧旬蟋,貌似對(duì)數(shù)字很好,不知道字符串怎么樣革娄?" 通過(guò)借助順序表(ordinal table)倾贰,String 類(lèi)型也是類(lèi)似進(jìn)行編碼的。String 類(lèi)型是去重之后存放到順序表的拦惋,通過(guò)分配一個(gè) ID匆浙,然后通過(guò)數(shù)字類(lèi)型的 ID 構(gòu)建 Doc Values。這樣String類(lèi)型和數(shù)值類(lèi)型可以達(dá)到同樣的壓縮效果厕妖。

而順序表本身也有很多壓縮技巧首尼,比如固定長(zhǎng)度、變長(zhǎng)或是前綴字符編碼等等言秸。

聯(lián)合索引

上面說(shuō)了半天都是單field索引软能,如果多個(gè)field索引的聯(lián)合查詢,倒排索引如何滿足快速查詢的要求呢井仰?

  • 利用跳表(Skip list)的數(shù)據(jù)結(jié)構(gòu)快速做“與”運(yùn)算埋嵌,或者
  • 利用上面提到的bitset按位“與”

先看看跳表的數(shù)據(jù)結(jié)構(gòu):

將一個(gè)有序鏈表level0,挑出其中幾個(gè)元素到level1及l(fā)evel2俱恶,每個(gè)level越往上雹嗦,選出來(lái)的指針元素越少,查找時(shí)依次從高level往低查找合是,比如55了罪,先找到level2的31,再找到level1的47聪全,最后找到55泊藕,一共3次查找,查找效率和2叉樹(shù)的效率相當(dāng)难礼,但也是用了一定的空間冗余來(lái)?yè)Q取的娃圆。

假設(shè)有下面三個(gè)posting list需要聯(lián)合索引:

如果使用跳表,對(duì)最短的posting list中的每個(gè)id蛾茉,逐個(gè)在另外兩個(gè)posting list中查找看是否存在讼呢,最后得到交集的結(jié)果。
如果使用bitset谦炬,就很直觀了悦屏,直接按位與节沦,得到的結(jié)果就是最后的交集。


最后

注意點(diǎn)

  1. 不需要索引的字段础爬,一定要明確定義出來(lái)甫贯,因?yàn)槟J(rèn)是自動(dòng)建索引的
  2. 同樣的道理,對(duì)于String類(lèi)型的字段看蚜,不需要analysis的也需要明確定義出來(lái)叫搁,因?yàn)槟J(rèn)也是會(huì)analysis的
  3. 選擇有規(guī)律的ID很重要,隨機(jī)性太大的ID(比如java的UUID)不利于查詢

詳細(xì)使用

Elasticsearch權(quán)威指南1
Elasticsearch權(quán)威指南2

ES對(duì)外接口

JAVA API接口
常見(jiàn)的增失乾、刪常熙、改、查操作實(shí)現(xiàn):
RESTful API接口

論壇

1)國(guó)外:https://discuss.elastic.co/
2)國(guó)內(nèi):http://elasticsearch.cn/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末碱茁,一起剝皮案震驚了整個(gè)濱河市裸卫,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纽竣,老刑警劉巖墓贿,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蜓氨,居然都是意外死亡聋袋,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)穴吹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)幽勒,“玉大人,你說(shuō)我怎么就攤上這事港令∩度荩” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵顷霹,是天一觀的道長(zhǎng)咪惠。 經(jīng)常有香客問(wèn)我,道長(zhǎng)淋淀,這世上最難降的妖魔是什么遥昧? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮朵纷,結(jié)果婚禮上炭臭,老公的妹妹穿的比我還像新娘。我一直安慰自己袍辞,他們只是感情好鞋仍,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著革屠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上似芝,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天那婉,我揣著相機(jī)與錄音,去河邊找鬼党瓮。 笑死详炬,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的寞奸。 我是一名探鬼主播呛谜,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼枪萄!你這毒婦竟也來(lái)了隐岛?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤瓷翻,失蹤者是張志新(化名)和其女友劉穎聚凹,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體齐帚,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡妒牙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了对妄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片湘今。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖剪菱,靈堂內(nèi)的尸體忽然破棺而出摩瞎,到底是詐尸還是另有隱情,我是刑警寧澤琅豆,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布愉豺,位于F島的核電站,受9級(jí)特大地震影響茫因,放射性物質(zhì)發(fā)生泄漏蚪拦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一冻押、第九天 我趴在偏房一處隱蔽的房頂上張望驰贷。 院中可真熱鬧,春花似錦洛巢、人聲如沸括袒。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)锹锰。三九已至芥炭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間恃慧,已是汗流浹背园蝠。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留痢士,地道東北人彪薛。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像怠蹂,于是被迫代替她去往敵國(guó)和親善延。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353