有几种方法可以通过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) { |
短语前缀工作示例:
关键字:“ puerto r”表示“ puerto”是需要在国家名称中输入的确切单词,而“ r”则是“ puerto”之后的任何单词的前缀。这将匹配“puerto”。 |
让我们尝试以下搜索:
curl localhost:8080/users/search?keywords=bahamas |
太好了,这将返回来自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": { |
edge_ngram的工作方式示例:
输入令牌:bahamas |
将自定义分析器与Ngrams一起使用
使用自定义分析器的代码位于master分支上。以下是对先前解决方案的必要更改。
- 创建自定义分析器并设置为“用户”中的“国家/地区”字段
分析器配置:
{ |
用户User类,使用带有@Setting和@Field批注的新配置:
@Document(indexName = "users") |
修改搜索使用查询匹配而不是前缀匹配:
public List<User> search(String keywords) { |
匹配查询工作方式的一个示例:
关键字:“ puerto baham” |
从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应用程序添加了一个很酷的自动完成功能。自己尝试一下,因为该项目可以作为您进行测试和添加其他有趣功能的游乐场。