目錄html
優勢:高效,準確,分詞
全文檢索容許用戶輸入一些關鍵字,從數據層中查找到所須要的信息java
lucene是一個是一個開源的全文檢索引擎庫,Apache基金會贊助項目.不管在開源仍是專有領域,Lucene能夠被認爲是迄今爲止最早進、性能最好的、功能最全的搜索引擎庫(《Elastic Search 權威指南》)。lucene有不少優勢,包括:它的文本分析器能夠定製,檢索文件存儲方式能夠定製,查詢引擎也有不一樣的可選方案.此外,它提供一套很是強大的API接口,使客戶用起來很方便.算法
lucene是一個很是強大的全文檢索引擎庫,可是遺憾的是,它是一個庫,想要使用它,你必須使用Java來做爲開發語言並將其直接集成到你的應用中,更糟糕的是,Lucene很是複雜,你須要深刻了解檢索的相關知識來理解它是如何工做的。數據庫
Elasticsearch也使用Java開發並使用Lucene做爲其核心來實現全部索引和搜索的功能,可是它的目的是經過簡單的RESTful API來隱藏Lucene的複雜性,從而讓全文搜索變得簡單。json
ES的安裝很簡單,即裝即用.去官網下載ES下載地址,在任何配置了java運行環境的電腦上後將壓縮文件解壓縮便可.
解壓後進入解壓下的bin文件夾,啓動elasticserach.bat(windows系統),以下:
啓動後進入cmd窗口,以下圖所示即成功啓動:
而後咱們打開瀏覽器訪問如下ES,輸入http:localhost:9200,以下即爲成功運行:
windows
ES是數據存儲是面向文檔的,數據的存儲形式是以對象的形式(JSON)來存儲的,而不是像關係型數據庫同樣把數據抽象一行行記錄去適應數據庫.同時在存儲的時候,ES還會索引每條數據內容使得每條內容能夠被搜索.
ES存儲的相關概念與傳統關係型數據庫的對比:
其中的fields(字段)就至關於關係型數據庫的列;多個字段組成一個Document(文檔)至關於關係型數據庫的行(一條數據);相同類型的Documents組成一個type(類型),至關於關係型數據庫的一張數據表;而多個types就會組成一個index(索引),至關於關係型數據的數據庫.關係對應以下:api
Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices -> Types -> Documents -> Fields數組
ES對提供的REST ful接口,任何對數據的操做和查詢均可以經過想ES發送HTTP請求來完成.關於RESTful協議的相關知識能夠參照一下RESTful API 設計指南,瞭解一下RESTful協議能共更容易理解ES提供的接口.
如今咱們要創建一個因此,按照ES提供的RESTful接口,咱們應該對ES發一個PUT請求,以下:瀏覽器
須要注意的是index名字裏的字母都必須是小寫.
若是成功,咱們會獲取以下的返回結果:
{ "acknowledged": true }
而後咱們再向ES發送GET請求,來獲取咱們剛剛建立的testindex的屬性:
結果以下:
{ "testindex": { "aliases": {}, "mappings": {}, "settings": { "index": { "creation_date": "1465748163064", "uuid": "uYyeZC_bQ1Olwe8lDrqXaw", "number_of_replicas": "1", "number_of_shards": "5", "version": { "created": "2030399" } } }, "warmers": {} } }
相關的tpye,document最簡單的增刪查改也均可以經過PUT GET POST DELET 幾個經常使用的請求來完成,這裏就不作詳細的介紹了,詳細的能夠查看ElasticSearch權威指南中文版瞭解一下.
mapping能夠理解爲描述index/type以及field的元數據,經過mapping咱們能夠來設置index/type/field.
單獨的生成或者更新type的mappiing
{ "properties": { "activateTiem": { "type": "date", "format": "yyyy-MM-dd" }, "title": { "type": "string", "boost": 10, "store": true, "analyzer": "ik" } } }
參考文檔:更新mapping
一般咱們須要在構建mapping的時候來設置一些經常使用的屬性,主要是包括字段的類型,是否被分詞,分詞使用的分詞器,分詞時候本身所佔的比重等,以下:
- type:類型,包括date,string,boolean,integer等,跟經常使用的類型跟java很類似,同時也有array類型能夠直接存儲數組.
其他的更多的類型能夠參考官方文檔mapping
ES爲了可以更好的進行查詢,在保存數據以前,都會對數據進行索引(動詞),那麼在這個因此過程裏面,ES都作了什麼?
ES會對文檔進行一系列的操做和處理,是他們可以更容易被搜索.它包括以下的幾個過程:
字符過濾器的主要工做室對原始數據的特殊字符進行過濾和處理,好比去除掉文檔中的html標籤,把&變成單詞"and"等等
所謂的分詞器就是指某種算法,這個算法會按照本身的對文檔(通過字符過濾器處理過的文檔)進行處理,提取若干的單詞,這些被提取出來的單詞就成爲詞元(Token),顧名思義,這些詞元已是最小的不能分割了.
標記過濾(token filters)會對詞元(Token)進行進一步的處理,處理細節包括一些將單詞的大寫變成小寫、去除英語中的連詞或者介詞(to,for,of等)、去除漢語中的語氣詞等、進一步保證最後剩下的單詞都是有明確的天然語義的詞,這些剩下的單詞就被稱做詞(term)
到此整個文檔分析階段就結束了
Elasticsearch使用一種叫作倒排索引(inverted index)的結構來作快速的全文搜索。倒排索引由在文檔中出現的惟一的單詞列表,以及對於每一個單詞在文檔中的位置組成。
分詞結束後,es會根據分詞的結果詞(term)構建出一個倒序索引用於快速查詢.
在索引階段es作的另外一件事就是計算不一樣詞(term)在不一樣文檔中的相關度評分,這個評分會用在以後查詢時候的查詢結果的排序上,默認的會將相關度較高的文檔排在最前面
當咱們須要查詢的時候,最簡單的,咱們能夠向ES發送一個get請求,構造一個查詢的url,以下
默認的,會ES會發揮my_index下的全部數據,若是數據過多ES會自動進行分頁處理顯示一部分數據(默認是10個).會返回以下形式的結果:
{ "took": 62, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 1, "max_score": 1, "hits": [ { "_index": "my_index", "_type": "my_type", "_id": "1", "_score": 1, "_source": { "title": "Some short title", "date": "2015-01-01", "content": "A very long content field..." } } ] } }
若是咱們須要分頁功能,就須要在get請求的url中加入size和from倆個參數,size表示分頁大小,from表示開始位置,以下:
若是須要模糊查詢,能夠在URL參數中附加一個q(query的意思)參數,以下:
GET http://localhost:9200/my_index/_search?q=title:Some
意思是查詢my_index下title中包含"Some"的數據.
經過URL參數控制,咱們只能進行一下簡單的查詢,可是在實際過程當中,咱們通產的查詢條件都要更加複雜,這時候咱們就須要使用另外一種適用於複雜查詢的方式--結構體查詢.
按照rest ful協議,咱們也是應該想ES發送GET請求來獲取ES中的數據,可是在平常開發中,不少地方都不容許在GET請求上附加body數據,所以ES中咱們也能夠經過POST來獲取ES中的數據.發送POST請求的時候,除了請求方式以外,URL和數據體body都跟GET的徹底相同(如下都以POST請求爲例)
{ "query": { "bool": { "must": [ { "match": { "title": "Search" }}, { "match": { "content": "Elasticsearch" }} ], "filter": [ { "term": { "status": "published" }} ] } } }
上面的body的大意是要搜索title中即包含"search"而且content中包含"elasticsearch",同時status爲"published"數據.關於query有專門的queryDSL來規定query的形式,在後面文檔中會介紹.
{ "from" : 0, "size" : 10, "query" : { "term" : { "user" : "kimchy" } } }
{ "sort" : [ { "post_date" : {"order" : "asc"}}, { "price" : {"order" : "asc"}} ], "query" : { "term" : { "user" : "kimchy" } } }
如上,sort會優先按照post_date進行正序排序,當post_date相同的時候在按照price進行正序排序.特別的在平常的查詢中,查詢結果一般都會有相關的_scroe評分,默認的,ES會按照_score對搜索結果進行性倒敘排序,是的相關度最高的文檔在最前方顯示.
{ "query":{ "match":{"title":"some"} } }
查詢的返回結果默認的會包含全部保存的字段:
{ "_index": "my_index", "_type": "my_type", "_id": "1", "_score": 0.15342641, "_source": { "title": "Some short title", "date": "2015-01-01", "content": "A very long content field..." } }
當咱們使用fields的時候,body以下:
{ "fields":["title"], "query":{ "match":{"title":"some"} } }
返回結果的數據部分指揮顯示title字段:
{ "_index": "my_index", "_type": "my_type", "_id": "1", "_score": 0.15342641, "fields": { "title": [ "Some short title" ] } }
{ "query":{ "match":{"title":"some"} }, "highlight" : { "pre_tags" : ["<b>"], //設置高亮的前 後html標籤 "post_tags" : ["</b>"], "fields" : { "title" : {} } } }
在返回的數據部分,咱們會獲得高亮的字段,以下
{ "_index": "my_index", "_type": "my_type", "_id": "1", "_score": 0.15342641, "_source": { "title": "Some short title", "date": "2015-01-01", "content": "A very long content field..." }, "highlight": { "title": [ "<b>Some</b> short title" //這裏是高亮顯示的關鍵字 ] } }
ES的主要任務是經過全文搜索引擎進行全文搜索,在ES提供的接口中,這部分任務主要由請求體中的query部門來完成的.而query DSL就是來解釋query的用法.