天天看點

Elasticsearch用例:全文搜尋

在本系列有關Elasticsearch用例的最後一篇文章中,我們介紹了Elasticsearch提供的用于存儲甚至大量文檔的功能 。 在這篇文章中,我們将研究其另一個核心功能:搜尋。 我正在利用上一篇文章中的某些資訊,是以,如果您還沒有閱讀過,則應該立即閱讀。

如我們所見,我們可以使用Elasticsearch存儲甚至可以分布在多台機器上的JSON文檔。 索引用于對文檔進行分組,并且每個文檔都使用某種類型存儲。 分片用于在多個節點之間配置設定索引的一部分,副本是分片的副本,用于配置設定負載和容錯。

全文搜尋

每個人都使用全文搜尋。 僅通過導航和類别就無法通路大量資訊。 Google是提供大量資訊即時關鍵詞搜尋的最傑出的例子。

Elasticsearch用例:全文搜尋

檢視Google的功能,我們已經可以看到全文搜尋的一些常見功能。 使用者僅提供關鍵字,并期望搜尋引擎提供良​​好的結果。 預計文檔的相關性很好,并且使用者希望在第一頁上獲得所需的結果。 文檔的相關性可能受不同因素的影響,例如查詢的術語存在于文檔中。 除了獲得最佳結果外,使用者還希望在搜尋過程中得到支援。 建議和結果摘錄中的突出顯示等功能可以幫助實作這一目标。

搜尋非常重要的另一個領域是電子商務,其中亞馬遜是主要參與者。

Elasticsearch用例:全文搜尋

該界面看起來類似于Google的界面。 使用者可以輸入然後搜尋的關鍵字。 但是也有細微的差異。 亞馬遜提供的建議更為進階,還暗示可能在其中找到術語的類别。結果顯示也有所不同,包括結構化的視圖。 所搜尋文檔的結構還用于确定左側的構面,這些構面可用于基于某些條件過濾目前結果,例如,所有結果的成本在10到20歐元之間。 最後,當涉及到諸如線上商店之類的内容時,相關性可能意味着完全不同的東西。 通常,結果清單的順序會受到供應商的影響,或者使用者可以按價格或釋出日期等标準對結果進行排序。

盡管Google和Amazon均未使用Elasticsearch,但您可以使用它來建構類似的解決方案。

在Elasticsearch中搜尋

與其他所有内容一樣,可以使用HTTP搜尋Elasticsearch。 在最簡單的情況下,可以将_search端點附加到URL并添加一個參數 :

curl -XGET "http://localhost:9200/conferences/talk/_search?q=elasticsearch⪯tty=true"

。 然後,Elasticsearch将按照相關性對結果進行響應。

{
  "took" : 81,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.067124054,
    "hits" : [ {
      "_index" : "conferences",
      "_type" : "talk",
      "_id" : "iqxb7rDoTj64aiJg55KEvA",
      "_score" : 0.067124054,
      "_source":{
    "title" : "Anwendungsfälle für Elasticsearch",
    "speaker" : "Florian Hopf",
    "date" : "2014-07-17T15:35:00.000Z",
    "tags" : ["Java", "Lucene"],                                  
    "conference" : {
        "name" : "Java Forum Stuttgart",
        "city" : "Stuttgart"
    }
}

    } ]
  }
}
           

盡管我們已經搜尋了某種類型,但是您也可以搜尋多種類型或多種索引。

添加參數很容易,但是搜尋請求可能變得更加複雜。 我們可能會要求根據标準突出顯示或過濾文檔。 Elasticsearch并沒有為所有内容使用參數,而是提供了所謂的Query DSL ,這是在請求正文中傳遞并使用JSON表示的搜尋API。

該查詢可能是使用者嘗試搜尋elasticsearch但卻誤輸入了一部分的結果。 結果經過過濾,是以僅傳回斯圖加特市的會議讨論。

curl -XPOST "http://localhost:9200/conferences/_search " -d'
{
    "query": {
        "match": {
            "title" : {
               "query": "elasticsaerch",
               "fuzziness": 2
            }
        }
    },
    "filter": {
        "term": {
           "conference.city": "stuttgart"
        }
    }
}'
           

這次我們正在索引會議中查詢所有類型的所有文檔。 查詢對象請求一個常見查詢,即文檔标題字段上的比對查詢 。 查詢屬性包含使用者将傳遞的搜尋詞。 模糊屬性要求我們還應該查找包含與所請求術語相似的術語的文檔。 這将照顧到拼寫錯誤的術語,并傳回包含elasticsearch的結果。 篩選器對象要求應根據會議所在的城市篩選所有結果。 應盡可能使用過濾器,因為它們可以被緩存,并且不計算相關性,這會使它們更快。

規範化文字

随着搜尋無處不在,使用者對它應該如何工作也抱有一些期望。 他們可能會使用僅與文檔中的術語相似的術語,而不是釋出完全比對的關鍵字。 例如,使用者可能正在查詢術語

curl -XGET "http://localhost:9200/conferences/talk/_search?q=title:anwendungsfall⪯tty=true"

,該術語是所包含術語

curl -XGET "http://localhost:9200/conferences/talk/_search?q=title:anwendungsfall⪯tty=true"

的單數形式,這意味着用例在德語中:

curl -XGET "http://localhost:9200/conferences/talk/_search?q=title:anwendungsfall⪯tty=true"

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 0,
    "max_score" : null,
    "hits" : [ ]
  }
}
           

沒有結果。 我們可以嘗試使用上面已經看到的模糊搜尋來解決這個問題,但是有更好的方法。 我們可以在索引編制過程中對文本進行規範化,以便兩個關鍵字都指向文檔中的同一術語。

Lucene,Elasticsearch中的庫搜尋和存儲是通過提供用于搜尋的基礎資料結構,即反向索引來實作的。 術語會映射到它們所包含的文檔中。稱為分析的過程用于拆分傳入的文本并添加,删除或修改術語。

Elasticsearch用例:全文搜尋

在左側,我們可以看到兩個已建立索引的文檔,在右側,我們可以看到将術語映射到包含它們的文檔的反向索引。在分析過程中,文檔的内容按照特定于應用程式的方式進行拆分和轉換是以可以将其放入索引中。 在這裡,文本首先在空格或标點符号上分割。 然後所有字元都小寫。 在最後一步中,采用依賴于語言的詞幹來嘗試找到術語的基本形式。 這就是将我們的Anwendungsfälle轉變為Anwendungsfall的原因。

在分析期間執行哪種邏輯取決于您的應用程式資料。 分析過程是确定搜尋品質的主要因素之一,您可以花很多時間進行搜尋。 有關更多詳細資訊,您可能需要看一下我關于索引資料的絕對基礎的文章。

在Elasticsearch中,如何分析字段取決于類型的映射。 上周,我們看到我們可以在Elasticsearch中索引不同結構的文檔,但是正如我們現在所看到的,Elasticsearch并非完全沒有架構。 某個領域的分析過程隻能确定一次,并且不容易更改。 您可以添加其他字段,但通常不更改現有字段的存儲方式。

如果您不提供映射,Elasticsearch将對您索引的文檔進行一些有根據的猜測。 它将檢視在索引編制過程中看到的任何新字段,并盡其所能。 就我們的标題而言,它使用StandardAnalyzer,因為它是一個字元串。 Elasticsearch不知道我們的字元串使用哪種語言,是以它不會進行任何詞幹處理,這是一個很好的預設設定。

要告訴Elasticsearch使用GermanAnalyzer代替,我們需要添加一個自定義映射。 我們首先删除索引,然後再次建立它:

curl -XDELETE "http://localhost:9200/conferences/"

curl -XPUT "http://localhost:9200/conferences/“
           

然後,我們可以使用PUT映射API傳入我們類型的映射。

curl -XPUT "http://localhost:9200/conferences/talk/_mapping" -d'
{
    "properties": {
       "tags": {
          "type": "string",
          "index": "not_analyzed"
       },
       "title": {
          "type": "string",
          "analyzer": "german"
       }
    }
}'
           

我們僅提供了兩個字段的自定義映射。 Elasticsearch将再次猜測其餘字段。 建立生産應用程式時,您很可能會預先映射所有字段,但不相關的字段也可以自動映射。 現在,如果我們再次為文檔建立索引并搜尋單數,将找到該文檔。

進階搜尋

除了我們在這裡看到的功能外,Elasticsearch還提供了更多功能。 您可以使用聚合自動收集結果方面,我們将在以後的文章中介紹這些聚合。 建議者可用于為使用者執行自動建議,可突出顯示術語,可根據字段對結果進行排序,您可以對每個請求進行分頁……。 随着Elasticsearch在Lucene的基礎上發展,建構進階搜尋應用程式的所有優勢均已存在。

結論

搜尋是Elasticsearch的核心部分,可以與其分布式存儲功能結合使用。 您可以使用DSL查詢來建構表達性查詢。 分析是搜尋的核心部分,可以通過為類型添加自定義映射來影響分析。 Lucene和Elasticsearch提供了許多進階功能,可将搜尋添加到您的應用程式中。

當然,由于Elasticsearch的搜尋功能和分布特性,有很多使用者正在使用Elasticsearch。 GitHub使用它來讓使用者搜尋存儲庫 , StackOverflow在Elasticsearch中索引其所有問題和答案 , SoundCloud則在歌曲的中繼資料中進行搜尋。

在下一篇文章中,我們将研究Elasticsearch的另一方面:使用它來索引地理資料,這使您可以按位置和距離對結果進行過濾和排序。

翻譯自: https://www.javacodegeeks.com/2014/07/use-cases-for-elasticsearch-full-text-search.html