使用Elasticsearch實現Spring Boot的自動完成功能 -Milos Biljanovic
有幾種方法可以通過Elasticsearch將自動完成功能新增到您的Spring Boot應用程式中:
- 使用萬用字元搜尋
- 將自定義分析器與ngrams一起使用
- Elasticsearch完成建議器
我們將專注於使用ngrams的自定義分析器。聽起來有點複雜,但實際上並非如此。讓我們開始吧!
內容列表:
- 需求用例
- 使用SpringData與Elasticsearch的基本設定SpringBoot
- Elasticsearch和自定義分析器
- 將自定義分析器與Ngrams一起使用
- 結論
需求用例
我們想要建立一個簡單的REST API,以搜尋儲存在Elasticsearch中的使用者列表。將有一個GET端點,我們可以在其中傳送有關正在尋找誰的搜尋輸入。假設我們有興趣按國家/地區搜尋使用者。
我們希望我們的搜尋支援以下查詢:
- 完整的單詞:Bahamas/bahamas尋找來自Bahamas的使用者。
- 分詞:baham,bah從Bahamas尋找使用者。
- 多個完整的單詞:bahamas belize從Bahamas或belize尋找使用者。
- 多個不完整詞:baham beliz從Bahamas或belize尋找使用者。
- 部分和完整單詞的混合單詞:trin和toba從Trinidad 和Tobago尋找使用者。
基本設定:帶有Elasticsearch的SpringBoot
首先,我們需要啟動Elasticsearch,其次,我們需要使用Spring Boot應用程式來實現搜尋。
檢查SpringData Elasticsearch版本支援當前6.8.4是SpringBoot 2.2.x支援的最新Elasticsearch"
啟動Spring Boot應用程式
Clone或下載此git repo(簽出分支master-prefix-phrase-match),然後在您喜歡的IDE中開啟專案。首次啟動應用程式時,樣本資料中的使用者將被新增到Elasticsearch中。
您可以檢查使用此命令新增的使用者列表:
curl localhost:8080/users
現在讓我們搜尋。以下是我們使用片語字首查詢進行搜尋的邏輯核心。
public List<User> search(String keywords) { MatchPhrasePrefixQueryBuilder searchByCountries = QueryBuilders.matchPhrasePrefixQuery("country", keywords); return this.userRepository.search(searchByCountries); } |
短語字首工作示例:
關鍵字:“ puerto r”表示“ puerto”是需要在國家名稱中輸入的確切單詞,而“ r”則是“ puerto”之後的任何單詞的字首。這將匹配“puerto”。 |
讓我們嘗試以下搜尋:
curl localhost:8080/users/search?keywords=bahamas curl localhost:8080/users/search?keywords=baham |
太好了,這將返回來自Bahamas的使用者。我們的第一個實現了1.和2.需求,但是由於我們使用Elasticsearch的方式以及字首短語匹配的工作方式,因此其餘所有方法都失敗了。
我們可以使用萬用字元搜尋來解決此問題,但這將對效能產生影響,我們避免使用Elasticsearch的核心,即它的反向索引。因此,在下一節中,我們將介紹Elasticsearch如何進行索引和搜尋,以及如何在Spring Boot應用程式中使用它來進行更靈活的搜尋。
Elasticsearch和自定義分析器
分析器用於新增到Elasticsearch的資料,也可以用於在Elasticsearch中用於查詢資料的搜尋輸入。
分析器分為三個部分:
- 字元過濾器:我們可以剝離,刪除或更改輸入資料。基本示例是使用html_strip過濾器,該過濾器將刪除html標籤。
- 分詞;我們可以打破輸入資料的簡單標記。預設情況下,使用標準標記器。示例:輸入資料:“fox in a forest”令牌:[fox,in,a,forest]
- 令牌過濾器:我們可以新增,修改或刪除上一步中擁有的令牌。基本示例是小寫令牌過濾器,它將所有令牌都轉換為小寫。
對於我們的自動完成功能,我們將建立使用edge_ngram令牌過濾器的自定義分析器,以便建立與我們的關鍵字匹配的其他令牌。將資料新增到Elasticsearch(索引時間)時,將使用此分析器。
"autocomplete_filter": { "type": "edge_ngram", "min_gram": 1, "max_gram": 20 } |
edge_ngram的工作方式示例:
輸入令牌:bahamas 輸出令牌:[b,ba,bah,baha,baham,bahama,bahamas] 它建立指定了最小和最大長度的字首。 |
將自定義分析器與Ngrams一起使用
使用自定義分析器的程式碼位於master分支上。以下是對先前解決方案的必要更改。
- 建立自定義分析器並設定為“使用者”中的“國家/地區”欄位
分析器配置:
{ "analysis": { "filter": { "autocomplete_filter": { "type": "edge_ngram", "min_gram": 1, "max_gram": 20 } }, "analyzer": { "autocomplete_search": { "type": "custom", "tokenizer": "standard", "filter": [ "lowercase" ] }, "autocomplete_index": { "type": "custom", "tokenizer": "standard", "filter": [ "lowercase", "autocomplete_filter" ] } } } |
使用者User類,使用帶有@Setting和@Field批註的新配置:
@Document(indexName = "users") @Setting(settingPath = "es-config/elastic-analyzer.json") @Getter @Setter public class User { @Id private String id; private String firstName; private String lastName; @Field(type = FieldType.Text, analyzer = "autocomplete_index", searchAnalyzer = "autocomplete_search") private String country; } |
修改搜尋使用查詢匹配而不是字首匹配:
public List<User> search(String keywords) { MatchQueryBuilder searchByCountries = QueryBuilders.matchQuery("country", keywords); return this.userRepository.search(searchByCountries); } |
匹配查詢工作方式的一個示例:
關鍵字:“ puerto baham” 它將查詢名稱中帶有“ puerto”或“ baham”的國家,因此它將返回恰好想要的來自Puerto Rico 和 Bahamas的使用者。 |
從Elasticsearch中刪除舊索引:
curl -X DELETE localhost:9200/users |
現在,我們可以啟動Spring Boot應用程式並測試我們的新搜尋:
curl localhost:8080/users/search?keywords=trin%20and%20toba |
太好了,現在返回了來自Trinidad 和Tobago的使用者。
多個國家/地區的另一個示例:
curl localhost:8080/users/search?keywords=bel%20bahamas |
它返回 Belize和Bahamas的使用者。這樣,我們滿足了所有用例要求。
結論
僅用幾行程式碼,我們就使用Elasticsearch Spring Data向Spring Boot應用程式新增了一個很酷的自動完成功能。自己嘗試一下,因為該專案可以作為您進行測試和新增其他有趣功能的遊樂場。
相關文章
- 使用Spring Boot實現檔案上傳功能Spring Boot
- 使用Spring Boot和Elasticsearch教程Spring BootElasticsearch
- Spring Boot 整合 Elasticsearch 實戰Spring BootElasticsearch
- Spring Boot 基礎: 使用 `@ConfigurationProperties` 實現自定義屬性的自動裝配Spring Boot
- 程式設計實戰篇——Spring Boot 自動配置實現程式設計Spring Boot
- 使用Spring Boot實現的GraphQL示例Spring Boot
- Spring Boot自動配置原理、實戰Spring Boot
- Spring Boot入門系列(十六)使用pagehelper實現分頁功能Spring Boot
- 使用Spring Boot實現動態健康檢查HealthChecksSpring Boot
- 使用 Spring Boot 3.2 和 CRaC 實現更快啟動Spring Boot
- Spring Boot功能實戰Spring Boot
- 深度剖析Spring Boot自動裝配機制實現原理Spring Boot
- Spring Boot 教程 - ElasticsearchSpring BootElasticsearch
- Spring Boot 整合 elasticsearchSpring BootElasticsearch
- 在微服務領域Spring Boot自動伸縮如何實現微服務Spring Boot
- 使用Spring Boot實現模組化Spring Boot
- 使用Spring Boot實現事務管理Spring Boot
- 在 Spring Boot 中使用搜尋引擎 ElasticsearchSpring BootElasticsearch
- Spring Boot自動配置原理與實踐(一)Spring Boot
- Spring Boot自動配置原理與實踐(二)Spring Boot
- Spring Boot 自動配置原理Spring Boot
- Jenkins自動部署spring bootJenkinsSpring Boot
- ElasticSearch與Spring Boot整合ElasticsearchSpring Boot
- Spring Boot 自動配置的原理、核心註解以及利用自動配置實現了自定義 Starter 元件Spring Boot元件
- Spring AOP 實現《自動自動填充Entity》Spring
- 使用Spring Boot和Kafka Streams實現CQRSSpring BootKafka
- 使用Spring Boot實現訊息佇列Spring Boot佇列
- 使用Spring Boot實現分散式事務Spring Boot分散式
- 使用Spring Boot實現Redis事務 | VinsguruSpring BootRedis
- 《Elasticsearch技術解析與實戰》Chapter 1.4 Spring Boot整合ElasticsearchElasticsearchAPTSpring Boot
- springboot整合ElasticSearch使用completion實現補全功能Spring BootElasticsearch
- Nasruddin/elasticsearch-spring-boot-spring-data:使用Spring Data將Elasticsearch儲存庫與Springboot結合使用的入門示例ElasticsearchSpring Boot
- Spring Boot核心原理-自動配置Spring Boot
- Spring Boot 自動配置之@EnableAutoConfigurationSpring Boot
- Spring Boot 自動裝配原理Spring Boot
- Spring Boot 2 實戰:利用Redis的Geo功能實現查詢附近的位置Spring BootRedis
- 使用Spring Boot, Istio和Cert Manager實現Kubernetes的HTTPSSpring BootHTTP
- 使用Vue+Spring Boot實現Excel上傳VueSpring BootExcel