ElasticSearch全文搜尋引擎

Flaming丶淡藍發表於2019-07-29

一、ElasticSearch簡介

1.1 什麼是ElasticSearch

  ElasticSearch簡稱ES,其中Elastic

     

   從名字裡我們可以知道,ES的特點就在於靈活的搜尋,其實ES本身就是一個全文搜尋引擎。

  1.是一個開源你的高擴充套件的分散式全文搜尋引擎。

  2.它可以近乎實時的儲存,然後檢索資料,延遲很小。

  3.本身擴充套件性很強,可以擴充套件到上百臺伺服器(分散式搜尋),處理PB級別的資料。

  4.ES使用java開發,底層是基於Lucene作為核心來實現所有索引和搜尋功能的,提供了一套RESTful風格的api是得全文搜尋變得簡單,隱藏了Lucene得複雜性,更易於使用和擴充套件。

    注意:Lucene只是一個庫,想要使用它,必須要了解它的原理,對於很複雜的搜尋,使用起來就非常的難受,ES就是基於Lucene庫進行了封裝和改造,使得開發人員對於複雜的搜尋也極其的簡單。

1.2 ES中的核心概念

   1. Node(節點)

   我們使用ES的時候是在一臺伺服器上安裝ES,然後再啟動,這時ES就可以使用了,預設訪問地址是 Http://localhost:9200,其實這就是一個節點(Node),由於我們前邊說到,ES是分散式的,所以我們可以在多臺伺服器上安裝ES,這樣我們就有了多個節點,一般的話,一臺伺服器上只部署一個節點,當然如果我們的伺服器效能比較優秀,就可以多部署幾個ES的例項,預設ES例項佔用9200埠,我們可以把其他的ES例項設定成9201、9202等埠,然後分別啟動,這樣我們就可以在一臺機器上啟動三個ES節點了。

    2.Cluster(叢集)

  上邊說的多個節點組合在一起就形成了一個叢集,在每個ES節點中,我們可以通過配置叢集的名稱來使各個節點組合在一起,成為一個叢集。當某些節點的叢集名稱一樣,ES會自動根據配置檔案中的地址找到這些節點,然後就自動組成一個叢集了,這一切都是ES自動來完成的,所以說ES的分散式擴充套件性很強,在這些節點中可以隨時增加和刪除節點不用費一點精力。

  綜上所述:一臺伺服器也可以有多個節點,所以我們就會看到有些大型企業所說的ES100多個叢集,200臺伺服器,500多個節點什麼的。

  3.Shard(分片)

  當我們有大量的文件時,倘若我們都存在一個節點(或伺服器上),由於機器效能的有限,就無法足夠快的響應客戶端你的請求,這是我們就可以把資料分成較小的分片,每個分片放在不同的伺服器或節點上,這樣,當你查詢的資料有多個分片時,ES就會發查詢請求同時分發到這些分片的節點上,之後每個伺服器獨自查詢較小的資料分片,然後ES再把資料結果組合起來,因為是並行,相當於多執行緒了,這樣吞吐率就非常高,對使用者來說,速度也就很快了。

  4.Replia(副本)

  副本,顧名思義就是複製,預設每一個資料集都會被分成幾個分片,我們把這些分片叫做主分片,副本就是把這些分片在複製一份,複本是按份數來衡量的,假設我們的一個資料集有5個分片,那麼一份副本也會有5個分片,二份副本就是10個分片,加上5個主分片,我們就把這個資料集分成了15個分片,副本是主分片的精確複製,當我們的副本多的話,我們就可以把這些副本分片再分佈到其他的伺服器上,這樣就顯然提高了我們的效能,另外,很多伺服器上都有我們的分片,假設我們的伺服器當機了,ES也能利用分片快速恢復我們的資料,即使我們停掉了幾臺機器,ES也能快速的利用副本保證資料分片的完整性,真正的實現了高可用性。

  5.ES中的資料架構概念

   

  1. 關係性資料庫中的(Database),對應ES中的索引(Index)。

   2.一個資料庫下有N張表(Table),對應一個ES索引中有N個型別(Type)。

   注意:ES6.x中已經限制了一個Index中只能有一個Type型別,使得一個Index就是一個型別,ES7.x中將取消Type的概念,ES8.x中將完全移除。參考連結:https://www.elastic.co/guide/en/elasticsearch/reference/6.0/removal-of-types.html

      

   不過問題不大,以後我們就認為一個Index就是一個型別就行了。

  

  3.在一個關係型資料庫中,我們會定義表的介面,什麼型別啊,長度啊,還有表之間的關係,對應ES中的Mapping,ES中Mapping類定義Type的欄位型別,處理規則什麼的。

  4.資料庫中的insert、update、detele、select對應ES中的api Put/Post、Delete、Get請求。

1.3 ES的特點和優勢

   1.分散式實時檔案儲存,可將每一個欄位存入索引,進行全文搜尋。

  2.實時分析的分散式搜尋引擎,ES將新資料建立索引,可以在很短的延遲後就能搜尋到信資料,近乎實時的搜尋,相比於傳統資料庫來,建索引的過程就很慢,就不能達到很實時的搜尋。

  3.ES中的資料負載均衡和路由都是自動完成了,開發人員完全不擔心某臺伺服器資料非常大而其他伺服器資料量非常小的情況,造成我們的資源利用率不高。

  4.可以擴充套件到上百臺伺服器,處理PB級別的資料的搜尋。

1.4 為什麼要使用ES

    但凡一個東西流行火起來,肯定有他的好處,而且也是經過很多實踐的,為什麼要用,因為大公司都在用,這玩意確實不錯。舉幾個例子:

  1.2013年初,GitHub拋棄了Solr,採取ElasticSearch 來做PB級的搜尋。 “GitHub使用ElasticSearch搜尋20TB的資料,包括13億檔案和1300億行程式碼”。

  2.維基百科:啟動以elasticsearch為基礎的核心搜尋架構。 

  3.SoundCloud:“SoundCloud使用ElasticSearch為1.8億使用者提供即時而精準的音樂搜尋服務”。 

  4.百度:百度目前廣泛使用ElasticSearch作為文字資料分析,採集百度所有伺服器上的各類指標資料及使用者自定義資料,通過對各種資料進行多維分析展示,輔助定位分析例項異常或業務層面異常。目前覆蓋百度內部20多個業務線(包括casio、雲分析、網 盟、預測、文庫、直達號、錢包、風控等),單叢集最大100臺機器,200個ES節點,每天匯入30TB+資料。

  博主本著求真務實,對廣大博友負責任的態度,鄭重宣告:

  注意:以上例子都是從網上搬過來的,也不知道是真的假的,估計不會騙人吧,大家都說厲害,那就很厲害了,反正自己也沒測試過。

  

二、ES的安裝

2.1 下載

  下載地址:https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.6.2.msi,下載windows的安裝版本,一般的我們學習使用一個東西都是先從windows上開始,這樣操作和學習都比較方便。

    注意:因為ES是java開發的,所以需要安裝jdk,安裝完之後要配置環境變數,這個就不再贅述了,不會的可以從網上搜尋怎麼配置。

2.2 安裝

  2.2.1 安裝玩之後來到es的目錄,如下,這是我的目錄  F:\Dev\elasticsearch-6.6.2

       

   2.2.2 進入bin目錄,開啟命令列(ps:在位址列直接輸入cmd,敲回車,就會在當前目錄開啟一個命令列視窗,這個操作估計很多人不知道)

      

    2.2.3 在命令列輸入:elasticsearch-service.bat install  把ES安裝為服務

       

   2.2.4 開啟工作管理員,檢視ES是否啟動,沒有啟動,就啟動

        

     2.2.5 直接訪問 http://localhost:9200/ ,瀏覽器出現如下所示,表明成功

      

三、開始使用ES

3.1 文件操作

    3.1.1 索引操作

   建立索引就相當於我們的建立資料庫,建立資料庫就要隨之的建立表結構,插入資料什麼的。這一系列的過程和傳統關係型資料庫是一致的。

      建立索引:Put  http://localhost:9200/users  建立一個名稱為users的索引(資料庫)返回結果如下:

   

   獲取索引資訊:Get  http://localhost:9200/users  輸出結果如下:

       

  3.1.2 設定Mapping (關於Mapping詳細設定參看http://www.baidu.com

    設定Index的Mapping,也就是設定資料的表結構 

    先刪除索引:Delete http://localhost:9200/users

    重新建立索引:Put http://localhost:9200/users 並提交一下引數,content-type:application/json

{
    "mappings": {
        "doc": {
            "properties": {
                "name": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "age": {
                    "type": "long",
                    "index": false
                },
                "gender": {
                    "type": "keyword"
                },
            }
        }
    }
}

    name:text型別,會進行分詞,支援模糊檢索。

   name.keyword : 這相當於是巢狀了一個欄位,keyword型別,只能精確匹配,不支援分詞。超過256字元長度不索引,也就沒法搜尋到。

   age:long型別,支援精確匹配。

   gender:keyword型別,只能精確匹配,不支援分詞。

   3.1.3 插入文件

   插入文件:Put  http://localhost:9200/users/doc/1,其中users代表索引庫名稱,doc代表型別,1代表id,輸出結果如下:

      

     3.1.4 獲取文件

    根據id獲取文件:Get  http://localhost:9200/users/doc/1,和新增一樣,只不過Http方法換成了Get,輸出結果如下: 

     

   3.1.5 刪除文件

  根據id刪除文件 Delete http://localhost:9200/users/doc/1,和新增一樣,只不過Http方法換成了Delete,輸出結果如下:

  

  根據query來刪除文件,向資料庫插入兩條資料如下:

  

     根據年齡刪除資料:Post  http://localhost:9200/users/doc/_delete_by_query ,刪除年齡為28的記錄,提交的資料如下:

  

   

     3.1.6 更新文件

     覆蓋更新(先刪除後新增):Put  http://localhost:9200/users/doc/1,可以看出,ES先刪除了所有的欄位,最後只把age欄位更新了上去,相當於我們之前的文件被刪除了(不知道這種更新有什麼用?)?_?

  

   

     部分更新(不刪除,更新相應欄位)Post  http://localhost:9200/users/doc/2/_update,如下, 先新增一個新文件,然後更新age欄位和gender欄位:這才是我們想要的。

  

  

     結果如下:

  

     根據查詢條件更新:http://localhost:9200/users/doc/_update_by_query,不過提交的資料要按指令碼來更新,目前官方文件沒給出其他例子。

  其中ctx._source指源文件,下邊表示把源文件的age賦值更新為5:

  

  3.1.7 批量獲取

    批量獲取文件(不指定索引庫):http://localhost:9200/_mget,這裡我們沒有在url裡邊指定索引庫,但是在提交的資料裡指定了索引庫和型別:

   

     這裡我們指定了獲取索引庫users下的型別為doc的且id為1的文件,和索引庫為orders型別為order的且id為1的文件,返回值如下:

     

     批量獲取文件(指定索引庫或者型別):http://localhost:9200/users/_mget 或者 http://localhost:9200/users/doc/_mget

  

  可以直接傳ids引數作為id的集合來搜尋:

  

  3.1.8 批處理操作

  ES允許我們在一次請求中做多種操作,比如在一次請求中同時進行增刪改查操作:

  批處理操作:http://localhost:9200/_bulk  下邊進行了一個批處理操作,分別包含新增、刪除、更新操作,

    但是提交的引數必須是一行一行的json,且結尾必須又換行符,要這樣ES才好處理,因為不是標準的json格式,這裡PostMan識別json格式錯誤,但是問題不大。

  

  3.1.9 重建索引

  重新建立索引,相當於資料什麼的都拷貝一份:http://localhost:9200/_reindex

    

     上邊我們把users索引重新索引為users_copy,ES會為我們重新複製一份索引庫。

    

  更多查詢引數和語法請檢視:https://www.elastic.co/guide/en/elasticsearch/reference/6.0/docs.html

3.2 查詢操作

  3.2.1 多索引和多型別查詢

    所有的查詢api都可以用多索引、多型別的查詢,多索引或者多型別之間用逗號隔開,如下:

    Get   /users/teacher,student/_search?q=name:sss   查詢users索引下型別為teacher和student的資料,查詢條件為name=sss。

    Get   /users,managers/teacher/_search?q=name:sss   查詢users索引和managers索引下型別為teacher資料,查詢條件為name=sss。

    Get   /_all/teacher/_search?q=name:sss   查詢所有索引下型別為teacher資料,查詢條件為name=sss。

    Get   /_search?q=name:sss   查詢所有索引下所有型別的資料,查詢條件為name=sss。

   3.2.2 查詢字元傳查詢(URI Search)

   我們可以通過get方式,在url後邊新增查詢字元出的方式查詢,如下:

   http://localhost:9200/bank/account/_search?q=lastname:Mckenzie OR firstname:Amber&sort=account_number:asc,age:desc&from=0&size=5&_source=firstname,lastname,account_number,age

   紅色部分(查詢):表示查詢lastname=Mckenzie或者firstname=Amber的文件,OR表示操作符“或者”,類似的還有AND。

   橙色部分(排序):表示按account_number升序排列,再按age降序排列,多個排序欄位用逗號隔開。

   藍色部分(分頁):分頁獲取。

   黃色部分(投影):可以選擇返回指定的欄位,多個欄位用逗號隔開。

   

  更多查詢引數和語法參看:

  https://www.elastic.co/guide/en/elasticsearch/reference/6.0/search-uri-request.html 

  https://www.elastic.co/guide/en/elasticsearch/reference/6.0/query-dsl-query-string-query.html

   3.2.3 請求體查詢(Request Body Search)

  我們依舊是通過get的方式請求:http://localhost:9200/bank/account/_search,設定content-type:application/json,提交以下資料:

  

   更多查詢引數和語法參看:https://www.elastic.co/guide/en/elasticsearch/reference/6.0/search-request-body.html

 3.3 Query DSL(Domain Specific Language 領域指定查詢語言)

  說白了也就是ES專門設計的查詢語言,ES最關鍵的地方就是查詢,各種千奇百怪奇形怪狀的查詢基本滿足了我們開發中的檢索的所有需求,這是ES中重點,下面我們就來看看。

    

   3.3.1 Query and filter context

   一個查詢語句究竟具有什麼樣的行為和結果,主要取決於它再查詢上下文(Query Context)還是再過濾上下文(Filter Context)兩者的區別具體如下:

   1.Query Context 查詢上下文,執行時會計算文件是否匹配,並且還要計算文件的匹配度有多高,匹配度越高,"_score"分數就越高。

   2.Filter Context 過濾上下文,執行時只關心文件是否匹配,不會計算匹配度(分數)。

   下述查詢中,bool中的must查詢字句的最外層是query,所以它再query context中,而filter中的range查詢是在filter context中,但是整體還是在query context中,查詢結果會顯示分數(”_score“欄位),如下:

   

    

    而當我們去掉了must查詢字句的時候,會出現一下結果,分數都為0,這說明只有filter context 時,不會做分數的評估。

   

   3.3.2 Full  Text Query(全文搜尋)

   這裡的全文檢索會對欄位進行全文簡單,包括模糊查詢、分詞查詢、精確查詢等。

  ES預設會把所有欄位都建成索引,字串欄位會預設被分詞,作為全文檢索,分詞器使用的預設分詞器,中文會一個字一個字的分詞,英文會根據空格分成一個一個單詞,之後會全部轉換成小寫儲存,分詞後就會形成一個一個的term(詞條),後續ES的查詢基本上就是根據每個欄位的term查詢的,term這個東西就很關鍵了,不同的分詞器分成的term不一樣,所以就會影響查詢結果。

  Match Query:全文查詢中最主要的查詢,包括模糊查詢(會把查詢關鍵字按空格隔開作模糊查詢),指定分詞方式(按分詞器拆分成term)查詢。查詢時,會把查詢關鍵字先做分詞處理,然後再匹配欄位分詞的term資料。

  

  Match Phrase Query:phrase是短語的意思,也就是不對關鍵字進行拆分,把關鍵字當成一個整體的短語來匹配,可以理解為把關鍵字作為一個整體進行的match查詢,也可以作為精確查詢使用。匹配的是欄位中的keyword型別,這也是ES儲存字串欄位的時候多存一個keyword型別的用處,用於後來的精確查詢用。

  比如查詢關鍵字為:henan nanyang,那麼查詢的欄位中需要完全包括henan nanyang 這個短語。

  

  Match Phrase Prefix Query:和match_phrase_query差不多,區別就是會將關鍵字的最後一個詞作為字首來使用查詢。

  比如查詢關鍵字為:hello w,那麼hello world,hello work,hello wxxx的都會匹配到。我們就可以利用這個功能來做使用者查詢自動提示相關的查詢結果(autocompleted),比如說推薦搜尋等。

  另外ES可能會匹配所有w開頭的單詞,這樣效能就會很差,我們可以指定只配置十個w開頭的單詞就可以了,引數  "max_expansions" : 10,可以來提高我們的搜素效能。

  

  Multi Match Query:多欄位的match查詢,搜尋match的時候可以指定多個欄位就不說了。

  

  Common Terms Query:暫時還不理解。

  Query String Query:支援複雜lucene query string的語法,對lucene查詢語法較為熟悉的人可以使用,一般不推薦。詳細請看3.2.2的URL Search就是這種查詢。

  Simple Query String Query:簡化版的Query String Query。

  更多詳細引數請檢視:https://www.elastic.co/guide/en/elasticsearch/reference/6.0/full-text-queries.html

  3.3.3 Term Level Query(term級別查詢)

   這個查詢應該是對每個(term)的高階查詢,例如字首查詢、範圍查詢等。term query 相當於全等查詢,必須全部匹配。前邊說過了,ES會把文字型別分詞,分出來的多個結果就叫term。

   Term Query:精確查詢,查詢一個欄位是否完全匹配所給的關鍵詞,和match query不同的是它不會把查詢的關鍵字進行分詞,而是把關鍵詞全部去匹配欄位的term,如果匹配到就算查詢到。

   Terms Query:可以給多個關鍵詞,查詢某個欄位是否在所給的關鍵詞之中,類似in操作。

   Range Query:查詢一個是否在一個範圍值內。

  

   Exists Query:存在欄位查詢,判斷某個欄位是否存在或者是否有值,該查詢會排除沒有price欄位,或者欄位值為null,[ ],[null]的資料,但不會排除為"" 空字串的資料,空字串為有值。

   

   Prefix Query:字首查詢,查詢欄位中是否以給定的關鍵字為字首,類似like 'chi%' ,這裡我們查詢是地址中有china的記錄。

   

   Wildcard Query:萬用字元查詢,用 * 代表一個或者多個字元,用?代表一個或者零個字元,和正規表示式中的萬用字元差不多。當我們只記得關鍵詞的一部分時,可以用這個查詢來,和模糊匹配差不多,估計比那個高階一點。

  

  Regexp Query:正規表示式查詢,顧名思義,就是查詢關鍵詞是正規表示式,如果正則很熟練的話,完全可以只用這一個查詢來替代其他查詢了,不過據說正則查詢效能不是很好,尤其是做模糊匹配的時候。

   

   Fuzzy Query:Fuzzy的意思是模糊的,也算是模糊查詢的一種吧,但是我更願意叫它相似度查詢,因為它和傳統的模糊查詢還不一樣。

  場景:當我們查詢名字Smith時,有些搜尋結果就會找出與之相似的Smithe, Smythe, Smyth, Smitt等。這些結果可能只是在關鍵詞上稍作改動之後很相似的結果,或者可以說把這些結果稍作改動之後就和關鍵詞一致了,所以我叫它相似度查詢。

  關於改動後和關鍵詞一樣:這樣的改動,我們叫它編輯距離,也就是我們編輯多少次就可以和關鍵詞一致,下邊介紹一個新概念:

  Levenshtein Edit Distance: 叫做萊文斯坦編輯距離,是編輯距離的一種。指兩個字串之間,由一個轉成另一個所需的最少編輯操作次數。允許的編輯操作包括將一個字元替換成另一個字元,插入一個字元,刪除一個字元。

  例如:god變成good,只需要增加一個字元o,因此他倆之間的編輯距離為1。下面我還是查詢地址中包含china的資料,假設我們忘記china怎麼拼了,只記得cha,那麼我們設定編輯距離為2,依舊可以查詢出來。

  

   Type Query:按文件的型別來查詢,這個就不用多說了,當你想查詢某個型別的文件時,就用這個吧。

   

   Ids Query:根據id的集合查詢,這個我們在sql中就比較常用了,和in操作差不多。

  

   更多詳細引數請檢視:https://www.elastic.co/guide/en/elasticsearch/reference/6.0/term-level-queries.html

   3.3.4 Compound queries(複合查詢)

  ES的複合查詢能包括上述我們介紹過的很多查詢,當我們用多條件搜尋的時候,我們就要把這好幾個查詢綜合到一起,就形成了複合查詢。

  Constant Score Query:常量分值查詢,用了這個查詢,我們就可以強制指定查詢結果的分數為多少,一般和filter連用,因為filter忽略分數計算,而你手動指定分數,是很合適的。下面指定boost分數為2.5,返回的結果中_score欄位就是2.5。

  

  Bool Query:布林查詢,可以組合多個條件,and、  or、  not等,當組合條件後的結果為true時,就表明是符合條件的記錄。查詢地址中不包括china但是包括henan的brand欄位中開頭為ao的記錄。

  

   Dis Max Query:預設情況下,當多個field匹配到了少量的關鍵詞 會比少個field匹配到多個關鍵詞排在前面,因為ES計算文件分數的時候會將匹配的語句作為數量做一下平均取一個分數,而不是取其中匹配到多個關鍵詞的分數(這個分數可能最高,但是被根據匹配語句數量一計算平均就低了),我們更期望最高分數的匹配在前邊,雖然它被平均計算後低一點,Dis 的意思是Disjunction(分離出,提取出),意思就是提取出最高分的查詢。

   

   Function Score Query:這也是一個能夠手動改變文件分數的查詢,只不過功能比較強大,引數也比較多,暫且就不介紹了。好多改變分數的查詢我們在一般情況下是用不到的,等到我們真的要用的時候還要仔細研究,不然的話就可能出現意想不到的結果。

   Boosting Query:這也是一個改變分數的查詢,它接受一個positive查詢和一個negative查詢。只有匹配了positive查詢的文件才會被包含到結果中,但是同時匹配了negative查詢的文件會降低分數,分數被設定為_score和negative_boost引數進行相乘所得到的新結果,negative_boost的值應當小於1.0。

  

   複合查詢中,感覺我們常用得還是Bool Query,其他關於修改分數都用的不多,如果有需要的話還是要深入研究一下。

  3.3.5 Joining queries

  Nested Query:說的內嵌查詢,我們先看一個傳統的陣列查詢。比如一個文件user,裡邊包含一個orders的陣列[{orderId:xx,price:xxx,count:xx},{orderId:xx,price:xxx,count:xx}],那麼如果當你想查詢訂單數量等於3的使用者,如下:

   

  內嵌查詢的資料結構也是巢狀的陣列或物件,不同的是內嵌查詢會把陣列中的每個元素(nested object)作為一個獨立隱藏文件單獨建索引,因此,我們不能直接查詢它們。取而代之,我們必須使用nested查詢或者nested filter,使用內嵌查詢需要先設定mapping

     

  插入資料:

   

  查詢評論中存在 點贊數在400-450之間的且是男使用者的 文章,結果如下:

  

   

  我們再來看一個傳統的陣列查詢用:查詢評論中 存在praise為200且為男性評論 的文章,結果卻不是我們預期的。

      

   結果中表明,這篇文章的評論中只有一個是男性和一個女性點贊數為200的評論,看起來好像是或者的結果,不符合我們的預期,但是卻被查出來了。至於為什麼,大家可以看這篇文章:

   https://czjxy881.github.io/elasticsearch/%E4%B8%80%E8%B5%B7%E6%9D%A5%E5%AD%A6ES-%E6%B5%85%E8%B0%88Nested%E7%BB%93%E6%9E%84/,這裡邊說明了詳細的原因,這在我們以後的查詢中是需要注意的。

   Has Child Query 、 Has Parent Query、Parent Id Query:這幾個查詢是用來處理一對多得關係的,類似我們傳統資料庫中的連線查詢,不過要首先建立父子的關係才行。ES低版本是用_parent元欄位通過mapping來建立父子關係的,高版本6.0之後使用join型別來建立的,而且父子文件同屬於一個型別(不知道為什麼,官方文件就這麼來,感覺以前挺好的啊,看文件估計是為了提升效能)。

  下面建立父子關係,建立一個blogs的索引庫,其中型別為_doc,有一個欄位叫my_join_field,這個欄位的型別為join,join的關係為question是answer的父親。其中question和answer是join關係中的名稱,以後插入資料的時候好表明關係。

   

  插入父文件,name設定為question:

  

  插入子文件,name設定成answer,parent設定父文件的id:

  

     Has Child Query :

  

  Has Parent Query:

  

  Parent Id Query:

  

  3.3.6 Geo queries

    就是地理位置的查詢,比如我們現在的滴滴,美團定位功能,搜尋附近的單車和酒店啥的,都是用到的這個功能,先把酒店的座標資訊存到資料庫,然後根據定位的座標就可以查詢你附近的酒店啥的。

  地理位置搜尋需要資料型別是geo_point的,所以我們要先來建立一個mapping:

  

  下邊參考了百度地圖上的兩個點,新增了兩個酒店資訊:

  

    

  Geo Bounding Box Query:指定一個矩形區域,查詢落在此區域內的酒店(區域點參考上邊的百度地圖)。

    

     Geo Distance Query :距離查詢,查詢在給定點距離s內的酒店,這就是我們常見的附近的酒店、餐館啥的搜尋功能。(不過感覺es的這個語法有點怪)

  

    Geo Polygon Query:多邊形區域查詢和Geo Bounding Box Query一樣,只不過後者是矩形,前者是不規則多邊形,貌似沒什麼用,先不介紹了。

    GeoShape Query:感覺有點複雜,不想看。

    3.3.7 Specialized queries

    一些特殊的查詢,找了一個比較有用的介紹一下。

  More Like This Query:相似度查詢,可以作為我們常見的推薦、猜你喜歡類似功能的實現。這個還是比較有用的。

  

    min_term_freq:一篇文件中一個詞語至少出現次數,小於這個值的詞將被忽略,預設是2

   min_doc_freq:一個詞語最少在多少篇文件中出現,小於這個值的詞會將被忽略,預設是5

    我這裡只有兩個文件,所以要設定這兩個引數小一點才能查到。

  其他還有少量的查詢暫時就不做介紹了,感覺沒什麼用,估計一會有需求再去看吧,中文資料太少了,搜半天也搜不到一個。

四、總結

         本文介紹了ES最核心的搜尋功能,目的是讓我們先上手使用,能滿足公司基本業務的搜尋,至於其他的個性的配置是什麼,叢集啊,系統api,日誌啊啥以後大家用的更深入的時候可以仔細研究,這篇文章旨在讓大家入個門,具體更深入的功能大家自己探索吧,畢竟官方給的功能很多很多,一時半會也介紹不完,有些很可能我們就用不上。最主要的原因還是英文,對我來說就是亂碼,既然是亂碼了,那就不用看了。

 

參考文章:

https://blog.csdn.net/makang110/article/details/80596017

https://www.cnblogs.com/52fhy/p/10017518.html

https://www.cnblogs.com/yjf512/p/4897294.html

轉載請註明出處,版權所有。

 

   

相關文章