使用 Lucene 搜索你的 beans — Suggest

0 阅读1分钟

作者:来自 Elastic David Pilato

到目前为止,我们已经看到如何针对你映射的任意 field 运行 search query。任何熟悉 search engine 的人都知道下一步是什么: autocomplete ,这样 index 就可以帮助你找到正确的 query。

Autocomplete 有自己的 artifact:

`

1.  <dependency>
2.    <groupId>org.apache.lucene</groupId>
3.    <artifactId>lucene-suggest</artifactId>
4.    <version>10.5.1</version>
5.  </dependency>

`AI写代码

第二个 Directory

AnalyzingInfixSuggester 并不是针对 track index 的IndexSearcher。它是一个拥有自己 Directory的 dictionary。使用与之前相同的 analyzer,这样 prefixes 才能匹配 titles 的 tokenization 方式:

`

1.  Directory suggestionDirectory = new ByteBuffersDirectory();
2.  AnalyzingInfixSuggester suggester = new AnalyzingInfixSuggester(
3.          suggestionDirectory, analyzer);
4.  suggester.build(new TrackSuggestionInputIterator(tracks.values()));

`AI写代码

将它放在 track writer 旁边,在 rebuild / upsert 时使用相同的 write lock。对 infix suggester 执行增量 delete 比较麻烦;对于几千个 beans,可以在每次 mutation 后重建 dictionary。

输入 “club”

输入 prefix club。将鼠标悬停在某一行上,可以看到lookup()→highlightKey、field、FILTER chip。

`

1.  List<Lookup.LookupResult> matches =
2.          suggester.lookup("club", Set.of(), 10, true, true);
3.  Lookup.LookupResult match = matches.get(0);
4.  String text = match.key.toString();              
5.  // "Club House"
6.  String field = match.payload.utf8ToString();     
7.  // "genre"
8.  String highlight = match.highlightKey.toString(); 
9.  // "<b>Club</b> House"

`AI写代码

这意味着第一个 suggestion 是来自genrefield 的Club House,可以向用户呈现为:

Club House。

使用 suggestion 进行过滤

选择Club House(field = "genre")后,可以调用你的后端 search API:/tracks?genre=Club House,并更新 UI 以反映所选的 filter chip。

如果你希望 suggestions 遵循当前的 filter set,请修改调用:

`

1.  List<Track> scoped = search.filter(corpus, "", filters, mustNots);
2.  List<TrackSuggestion> hits = index.suggest(prefix, scoped);

`AI写代码

filter(..., "", filters, mustNots)会应用当前已经启用的 chips,并使用一个空的 query string。然后,suggest(prefix, scoped)只会在这个子集内查找,因此club不会推荐那些已被这些 chips 排除的 genre。

完整 demo 位于 GitHub:lucene-search-tracks。

原文:Search your beans with Lucene — Suggest | David Pilato