ES搜索引擎-簡單入門


基本概念:

  索引Index

    es吧數據放到一個或者多個索引中,如果用關系型數據庫模型對比,索引的地位與數據庫實例(db)相當。索引存放和讀取的基本單元是文檔 (document)。es內部使用的是apache lucene實現的索引中數據的讀寫。(es被視為單獨的一個索引,在lucene中不止一個,因為分布式中,es會用到分區shards和備份 replicas機制講一個索引存儲多份)。

  文檔document

    在es中,文檔主要是存儲實體。所有的es應用需求最后都需要統一建成一個檢索模型:檢索相關文檔。

文檔由一個或多個域,每個域field由一個域名或多個值組成(有多個值的稱為多值域)。

在es中每個文檔都可能會有不同的域field集合;也就是說文檔是沒有固定的模式和同意的結構的。文檔之間保持的相似性即可。

在客戶端角度來看,文檔就是一個json對象。

參數映射  所有的文檔在存儲之前都必須分析(analyze)流程,用戶可以配置輸入文本分解成token的方式:哪些token唄濾掉;或者其它的處理流程,比如去除html標簽。

  文檔類型(type)

    每個文檔在es中都必須設定它的類型。文檔類型使得同一個索引中在存儲結構不同文檔時,只需根據文檔類型就可以找到對應的參數映射信息,方便文檔的存取。

   節點Node

     單獨es服務器實例成為一個節點。

    集群Cluster

      集群能夠存儲超出單機容量的信息。由於目前單點就可以滿足咱們的需求,就不詳細介紹了。

    索引副本Replica

      通過索引分片機制可以想es集群中導入超過單機容量的數據,客戶端操作任意一個節點接口實現對集群數據的讀寫。(不做詳細解釋了)

    時間之門gateway

      在運行的過程中,es會收到集群的狀態,索引的參數等信息。這些唄存儲在gateway中。

    

  es背后核心理念:

    es是構造極少數的幾個極少數的概念之上的。

    開箱急用。

    天生集群。

    自動容錯。

    擴展性強。

   

  es工作原理:

    啟動過程:

    當es節點啟動后,會利用 多播(multicast)或單播(別問我什么是單播,多播,沒必要糾結這些)尋找病簡歷鏈接。如圖:

  在集群中,一個節點唄選舉成主節點。這個節點扶着管理集群的狀態,當集群的拓展結構改變時把索引分區分派到相對性的節點上。

  在用戶角度看節點在es中並沒有占據主要位置,這與其它系統是不同的(數據庫系統)。實際上用戶並不需要知道哪個節點是主節點;所有的操作需求 可以發到任意節點,es內部完成這些工作。必要時任意節點都可以並發的把查詢自居分發到其他節點,然后合並各個節點返回的查詢結果。最后返回用戶一個完整 結果集。所有的這些工作不需要經過主節點轉發(節點之前通過p2p的方式通訊)。

  在必要時,會進行恢復工作。這時主節點會去檢查哪些分片可用,決定用哪些分片。處理完后,集群轉入黃色狀態。

  這意味着集群可以處理搜索請求了。但是還沒有火力全開(這主要是由於所有的主索引分區都已經分配好了,但是索引副本還沒有)。接下來就是找到復 制好的分區,病設置成索引副本。當一個分區數量太少時,主節點會界定將缺少的分區放到哪個節點中,並且依照主分區創建副本。所有工作完成后,集群就會變成 綠色狀態(標示所有的主分區的索引副本都已經分配完成了)。

 

  探測是吧節點

  在正常工作時,主節點會監控所有節點,查看各個節點是否工作正常。如果在指定的時間里,節點無法訪問,就唄視為出現故障了,接下來錯誤處理程序 就會啟動。集群需要均衡——由於該節點出現故障,分配到該節點的索引分片丟失。其實節點上相應的分區就會吧工作接管過來的這個過程可以通過配置滿足用戶需 求。

 

  由於只是展示es的工作原理,就以下圖三個節點的集群為例。集群中有一個主節點和兩個數據節點。主節點想其他節點發送ping命令后等待回應。如果得到回應(實際上可能得不到恢復ping命令個數,取決於用戶配置),改節點就會被移出集群。

  

 

  與es進行通訊

    歸根到底,最重要的是如何往es中添加數據以及如何查詢數據。es提供了api,這些api都是基於rest風格。而且這些api非常容易與其他能夠處理http的系統進行集群。

    es為數據應該伴隨在url中,或作為請求主體requst body。以一種json格式的文檔發送給服務器。

    es內部,節點之間通訊解釋用的先關javaapi。

 

  重點來咯

  索引數據

    es提供了4中索引數據的方法。最簡單的就是索引api。通過它可以將文檔添加到指定的索引中去。比如curl工具。我可以通過如下命令創建一個新的文檔

    第2、3中方法,可以通過bulk API和UDP API批量添加文檔。通常的bulk API采用HTTP協議,UDP bulk api采用非連接的數據包協議。UDP協議傳輸速度更快,但可靠性差點、最后一種是通過rivier插件。river運行在es集群的節點上,能夠從外部 系統中獲取數據。

  有一點需要注意,索引數據的曹組只會發生在主分區上,而不會發生在分區副本上。如果索引數據的請求發送到節點上沒有合適的分片或者分片副本,那么請求就會被轉發到含有主分區的節點。

 

   數據查詢

    查詢api在es中有着很大的比重。通過query DSL(基於json,用於構造復雜的語言)

    使用類型查詢:簡單關鍵詞、短語、區間、布爾、模糊、跨度、通配符、地理位置等查詢方式。

    通過組合簡單查詢構造復雜的查詢。

    過濾文檔,去除不符合標准的文檔而且不影響打分排序。

    查找給定文檔的相似文檔。

    查找給定短語的搜索建議和查詢短語修正。

    通過faceting構建動態的導航和數據統計。

    使用prospective search而且找到匹配寫定文檔的查詢語句(prospective search一種推送方式。用戶的查詢語句存儲在索引中,如果新的文檔添加到索引中,就把文檔關聯到匹配的查詢語句中。這種適合於新聞,博客等定時更新的場景)。

 

關於數據查詢,其核心在於查詢過程不是一個簡單、單一的流程。通過這個過程分為兩個階段:查詢階段和結果匯總階段。在查詢分發階段,會從各個分支中查詢數據;在結果匯總階段,會從各個分群上查詢到結果進行合並,排序等其他處理過程,然后返回給用戶。

 

用戶可以通過指定搜索類型來控制查詢的分發和匯總過程。

 

  索引參數設置

    es索引參數會自動配置

    文檔結構以及域類型會自動識別。當然es也允許用戶自定修改默認配置。

比如,自行配置很多參數,比如通過mapping配置索引中的文檔結構,設置分區shard和副本replica的個數,設置文本組件……

集群管理和監控

  通過管理和監控部分的api,用戶可以更改集群設置。比如調整節點發現機制或更改索引的分片策略。用戶可以查看集群狀態信息,或者每個節點和索引和統計信息。集群監控的api非常廣泛。

 

  強大的用戶查詢語言DSL

     if/idf打分公式

這個就是打分公式的真面目。如果只是為了調整查詢語句之間的關聯關系,用戶不必去理解它的原理。但只搜啊要知道它是如何工作的。      

lucene概念上的打分公式

上面展示了布爾信息檢索和向量空間信息檢索模型的組合。(這個暫時忽略)

可以了解更多東西可以去這里

 

從es的角度看打分排序

  最重要的是利用lucene構建起來的es允許用戶修改默認的打分算法。但es不僅僅是lucene的簡單封裝,因為es中,文檔排序並非完全 依賴apache lucene的打分算法。es實現了多種不同的查詢類型,這些查詢類型可以完全依賴與文檔的打分計算方式,es允許通過腳本定制文檔的打分方式。

 

查詢重寫機制

  如果你曾經使用過很多不同的查詢類型,比如前綴查詢和通配符查詢,從本質上,任何的查詢都可以視為對多個關鍵詞查詢。查詢重寫(query rewrite),es對用戶查詢進行了重寫,這樣做為了保證性能。重寫過程是吧lucene角度認為原始的、開銷大的查詢對象轉變成一系列開銷小的查詢 對象的一個過程。

 

前綴查詢:

  例如:

我是知道所有字符以j開頭的文檔。這個需求非常簡單,在client索引上運行

 

查詢結果的重打分

有些場景對查詢語句的結果文檔進行重新打分是很有必要的。重新打分的原因可能各有相同。

其中一個原因可能是處於性能考慮,比如對整個有序的結果集進行重排序開銷會很大,通常就會只對結果集進行重排序。

 

理解重打分

在es中,重打分是一個對限定數目的查詢結果進行再次打分的一個過程。這意味着es會根據新的打分規則對結果的前n個文檔重新進行一次排序

 rescore query的結構:

  重打分的參數

    在查詢語句的rescore對象中,用戶可以添加如下參數

      window_size提供了與N個文檔的相關信息。用於執行分片上用於重打分的文檔個數

      query_weight默認1;原查詢的打分會先乘以query_weight,然后與rescore的得分相加。

      rescore_query_weight默認1,rescore的打分會先乘該值,在與原查詢的得分相加。

      rescore_mode默認tatal;在es0.90.0中引入用來指定重打分文檔的打分方式。可選值:total,max,avg和multiply。

total:最終得分為原查詢得分和rescore得分的和;

max,最終得分為原查詢得分和rescore得分的最大值;

min,最終得分為原查詢得分和rescore得分的最小值;

avg,最終得分為原查詢得分和rescore得分的平均值;

multiply,兩種查詢的得分相乘。

例如設置recore_mode參數值為total,文檔最終得分是

 

 

查詢結果的排序

  當給es發送查詢命令時,返回的文檔集合默認會按照計算出來的文檔打分排序。這個通常是

用戶希望的:結果集中的第一個文檔就是查詢命令想要的文檔。然而,有事我們希望改變這種排序

  

  

  

 

  

update API

    當往索引中添加新的文檔到索引中時,底層的lucene工具包會分析每個域,生成token流

  token流過濾后得到倒排索引。在這個過程中輸入文版中一系誒不必要的信息會丟掉。

  這些不必要的信息可能是一些特殊詞的位置,一些停用的詞或用同義詞代替的詞,或者詞尾

  。這也是為什么無法對lucene中的文檔進行修改,每次修改一個文檔時,必須吧文檔所有域   添加到索引中。es通過_source這個代理域來存儲或檢索文檔中的真是數據。

  當我們想更新文檔時,es會把數據放到_souce域中,然后做出修改,最后吧更新后的文檔

  添加到索引中。讓然前提是_source域的這項特性必須生效。文檔更新命令只能更新一個文檔

  查詢命令的文檔更新還沒有出來。

  更新:

  

  使用update API創建或刪除文檔

  update API不僅可以修改某個域,同時也能操作整個文檔。

  upsert特性使得在定位到一個不存在的文檔是,它會被創建愛你出來:

  

  如果文檔存在,該命令將重置year域中的值;否則會被創建。新的文檔包含upset中定義的titile域。當然,上面的命令還有可以使用腳本:

  

   update還允許用戶選擇性的刪除整個文檔。

          

     filters優化查詢:

    es支持多種類型的查詢,但是查詢那個匹配成功,哪個應該呈現給用戶,查詢並不是唯一的。es查詢dsl允許用戶使用絕大數查詢都會有各自的標示。

  

  過濾器(filters)和緩存

    ES提供了特殊的緩存,filter cache來存儲filters得到的結果集。此外,存儲filters不需要太多的內存(它只保留一種信息,即哪些文檔與filter相匹配),同時它可以與其他查詢復用,極大的提高查詢的性能。

例:

該命令查詢得到滿足如下條件的文檔:name域值為joe同時值為1981。

用上面命令格式構建查詢,查詢對象會將所有的條件綁定到一起存儲到緩存中;因此如果我們查詢人名相同但出生年份不同的運動員,es無法重用上面查詢命令中的任何信息。

因此,我們需要優化下查詢。由於1千個人可能有一千個人名,所以人名不太適合緩存起來;但是年份比較適合。因此我們引入一個不同的查詢命令,將一個簡單的query與一個filter結合起來。

我們使用一個filtered類型的查詢對象,查詢對象將query元素與filter元素包含進去。第一次運行查詢命令后,es會吧filter緩存起來,如果有查詢用到一樣的filter,就會直接用緩存。

並非所有的filters都會被默認緩存起來

實際上es不會緩存所有的filters。這是因為部分filters會用到域數據緩存(field date cache)。該緩存一般用於按域值排序和faceting操作場景中。默認情況,如下filters不會唄緩存:  

 

 

  盡管最后三種不會用到域緩存,它們主要用於控制filters,因此不會被緩存,但是它們控制的filters在用時都已經緩存好了。

  

  更改es緩存行為

  es允許用戶通過_cache和_cache_key屬性自行開啟或關閉filters功能。

  假設我們將關鍵詞過濾器結果緩存起來,病給緩存項的key取名為year_1981_cache:

  也可以用下面命令關閉過濾器緩存:

   

 

 

   為了獲取更多的控制權,我們需要給緩存項的key取名。

 比如,有些查詢復用機不多,我們希望指定定時清理這些查詢的緩存。如果不指定_cache_key。就只能清除整個過濾器緩存filter cacahe;反之,只需執行如下命令:

 

  關鍵詞查找過濾器

    緩存和標准的查詢並不是全部內容。

  

  

  

 索引定義了id信息,名字,用戶購書的id列表。

一些測試數據:

假設我們希望展示某個用戶購買的所有數據,以id為1的user為例。

 

 

 

 

  

 

  term filter的工作原理

    一個普通的es查詢命令。它只是一個過濾查詢,包含一個全量查詢和一個terms過濾器。

只是查詢命令中,terms過濾器使用了一種不同的技巧——不明確指定某些term值,而是從索引中動態加載。

  過濾器基於id域,因為我們只需要id域就整合其它所有的屬性。

index屬性指明了加載terms的索引源。

type屬性告訴es我們的目標文檔類型。

id屬性指明我們在執行索引文檔的books域。

path屬性告訴es應該從哪個域中加載term。

 

 terms lookup filter的緩存設置

  

 

 

filters和scope在es faceting的應用

faceting的結果只基於查詢結果。如使用filters,那filters不會對facet用來的統計計算文檔產生影響。

scope,可以擴展facet統計計算的文檔范圍。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM