,什麼事倒排序索引
elaticsearch是面向文檔型的,將文檔序列化未JSON形式,順序縮影的過程是已知文檔,查處文檔中保航的字符串,從文件到字符串的映射,可是elaticsearch是已知字符串查找文檔,即創建字符串和文檔的映射,這種映射被稱爲倒排索引。算法
二,elasticsearch如何使用倒排序索引完成全文檢索功能
1,建立索引:
1.1 已知文檔,將文檔交給分詞器進行分詞處理,分紅一個一個檔次,去除標點符號和停用詞等
1.2 將單詞交給語言處理組件,提取詞根
1.3 將單詞傳給索引組件,處理成字典,按照字母順序排序,合併相同的單詞,成文倒排鏈表數據庫
2,搜索索引:
2.1 根據用戶輸入的數據進行詞法,語法和語言處理,提取關鍵字和普通單詞,獲得語法樹
2.2 利用語法樹進行索引搜索,將結果與搜索內容的相關性進行排序返回elasticsearch
Elasticsearch
全文檢索的基本思路:對非結構化數據順序掃描很慢,對結構化數據的搜索卻相對較快(因爲結構化數據有必定的結構能夠採起必定的搜索算法加快速度),把咱們的非結構化數據想辦法弄得有必定結構,也就是將非結構化數據中的一部分信息提取出來,從新組織,使其變得有必定結構,而後咱們從新組織的有必定結構的數據進行搜索,從而達到搜索相對較快的目的。這部分從非結構化數據中提取出的而後從新組織的信息,咱們稱之索引 。oop
全文檢索大致分兩個過程:1.索引建立 (Indexing) ;2. 搜索索引 (Search) 。
1.索引建立:將現實世界中全部的結構化和非結構化數據提取信息,建立索引的過程。
2.搜索索引:就是獲得用戶的查詢請求,搜索建立的索引,而後返回結果的過程。ui
倒排索引:
順序查找的意思就是已知文件,欲求字符串的過程,也便是從文件到字符串的映射。而咱們想搜索的信息是哪些文件包含此字符串,也即已知字符串,欲求文件,也即從字符串到文件的映射。二者偏偏相反。因爲從字符串到文件的映射是文件到字符串映射的反向過程,因而保存這種信息的索引稱爲倒排索引 ,若是索引總可以保存從字符串到文件的映射,則會大大提升搜索速度。
索引裏面包含的東西以下
反向索引的所保存的信息通常以下:
假設個人文檔集合裏面有100篇文檔,爲了方便表示,咱們爲文檔編號從1到100,獲得下面的結構this
左邊保存的是一系列字符串,稱爲詞典 。
每一個字符串都指向包含此字符串的文檔(Document)鏈表,此文檔鏈表稱爲倒排表 (Posting List)。
有了索引,便使保存的信息和要搜索的信息一致,能夠大大加快搜索的速度。
好比說,咱們要尋找既包含字符串「lucene」又包含字符串「solr」的文檔,咱們只須要如下幾步:rest
雖然建立索引庫也須要流程,可是若是採用順序掃描的話,是每次都要掃描,而建立索引的過程僅僅須要一次,之後即是一勞永逸的了,每次搜索,建立索引的過程沒必要通過,僅僅搜索建立好的索引就能夠了。
如何建立索引
第一步:一些要索引的原文檔(Document)。
先說Elasticsearch的文件存儲,Elasticsearch是面向文檔型數據庫,一條數據在這裏就是一個文檔,用JSON做爲文檔序列化的格式,好比下面這條用戶數據:
{ "name" : "John", "sex" : "Male", "age" : 25, "birthDate": "1990/05/01", "about" : "I love to go rock climbing", "interests": [ "sports", "music" ]}
爲了方便說明索引建立過程,這裏特地用兩個文件爲例:
文件一:Students should be allowed to go out with their friends, but not allowed to drink beer.
文件二:My friend Jerry went to school to see his students but found them drunk which is not allowed.
第二步:將原文檔傳給分詞器(Tokenizer)。
分詞器(Tokenizer)會作如下幾件事情( 此過程稱爲Tokenize) :排序
所謂停詞(Stop word)就是一種語言中最普通的一些單詞,因爲沒有特別的意義,於是大多數狀況下不能成爲搜索的關鍵詞,於是建立索引時,這種詞會被去掉而減小索引的大小。
英語中停詞(Stop word)如:「the」,「a」,「this」等。
對於每一種語言的分詞組件(Tokenizer),都有一個停詞(stop word)集合。
通過分詞(Tokenizer) 後獲得的結果稱爲詞元(Token) 。
在咱們的例子中,便獲得如下詞元(Token):
「Students」,「allowed」,「go」,「their」,「friends」,「allowed」,「drink」,「beer」,「My」,「friend」,「Jerry」,「went」,「school」,「see」,「his」,「students」,「found」,「them」,「drunk」,「allowed」。
第三步:將獲得的詞元(Token)傳給語言處理組件(Linguistic Processor)。
語言處理組件(linguistic processor)主要是對獲得的詞元(Token)作一些同語言相關的處理。
對於英語,語言處理組件(Linguistic Processor) 通常作如下幾點:索引
Stemming 和 lemmatization的異同:
相同之處:Stemming和lemmatization都要使詞彙成爲詞根形式。
二者的方式不一樣:
Stemming採用的是「縮減」的方式:「cars」到「car」,「driving」到「drive」。
Lemmatization採用的是「轉變」的方式:「drove」到「drove」,「driving」到「drive」。
語言處理組件(linguistic processor)的結果稱爲詞典(Term) 。
在咱們的例子中,通過語言處理,獲得的詞(Term)以下:
【「student」,「allow」,「go」,「their」,「friend」,「allow」,「drink」,「beer」,「my」,「friend」,「jerry」,「go」,「school」,「see」,「his」,「student」,「find」,「them」,「drink」,「allow」】
第四步:將獲得的詞(Term)傳給索引組件(Indexer)。
索引組件(Indexer)主要作如下幾件事情:hadoop
在咱們的例子中字典以下:
Term
Document ID
student
1
allow
1
go
1
their
1
friend
1
allow
1
drink
1
beer
1
my
2
friend
2
jerry
2
go
2
school
2
see
2
his
2
student
2
find
2
them
2
drink
2
allow
2
Term
Document ID
allow
1
allow
1
allow
2
beer
1
drink
1
drink
2
find
2
friend
1
friend
2
go
1
go
2
his
2
jerry
2
my
2
school
2
see
2
student
1
student
2
their
1
them
2
在此表中,有幾個定義:
Document Frequency: 即文檔頻次,表示總共有多少文件包含此詞(Term)。
Frequency :即詞頻率,表示此文件中包含了幾個此詞(Term)。
因此對詞(Term) 「allow」來說,總共有兩篇文檔包含此詞(Term),從而詞(Term)後面的文檔鏈表總共有兩項,第一項表示包含「allow」的第一篇文檔,即1號文檔,此文檔中,「allow」出現了2次,第二項表示包含「allow」的第二個文檔,是2號文檔,此文檔中,「allow」出現了1次。
到此爲止,索引已經建立好了,咱們能夠經過它很快的找到咱們想要的文檔。
並且在此過程當中,咱們驚喜地發現,搜索「drive」,「driving」,「drove」,「driven」也可以被搜到。由於在咱們的索引中,「driving」,「drove」,「driven」都會通過語言處理而變成「drive」,在搜索時,若是您輸入「driving」,輸入的查詢語句一樣通過咱們這裏的一到三步,從而變爲查詢「drive」,從而能夠搜索到想要的文檔。
如何對索引進行搜索?
第一步:用戶輸入查詢語句。
舉個例子,用戶輸入語句:lucene AND learned NOT hadoop。
第二步:對查詢語句進行詞法分析,語法分析,及語言處理
如上述例子中,通過詞法分析,獲得單詞有lucene,learned,hadoop, 關鍵字有AND, NOT。
若是在詞法分析中發現不合法的關鍵字,則會出現錯誤。如lucene AMD learned,其中因爲AND拼錯,致使AMD做爲一個普通的單詞參與查詢。
若是發現查詢語句不知足語法規則,則會報錯。如lucene NOT AND learned,則會出錯。
如上述例子,lucene AND learned NOT hadoop造成的語法樹以下:
如learned變成learn等。
通過第二步,咱們獲得一棵通過語言處理的語法樹。
第三步:搜索索引,獲得符合語法樹的文檔。
此步驟有分幾小步:
首先,在反向索引表中,分別找出包含lucene,learn,hadoop的文檔鏈表。
其次,對包含lucene,learn的鏈表進行合併操做,獲得既包含lucene又包含learn的文檔鏈表。
而後,將此鏈表與hadoop的文檔鏈表進行差操做,去除包含hadoop的文檔,從而獲得既包含lucene又包含learn並且不包含hadoop的文檔鏈表。
此文檔鏈表就是咱們要找的文檔。
更多技術資訊可關注:gzitcast