使用 UI 中的搜索

可视化组件

搜索扩展组件提供两个 UI 组件:SearchFieldFullTextFilter

搜索策略

搜索策略定义如何处理搜索词。基本上是使用一些查询语句配置搜索请求。

SearchFieldFullTextFilter 组件支持下列内置的搜索策略:

  • startsWith

    该策略 仅当 在至少一个索引定义上启用了 @ExtendedSearch 时才可用。

    对预索引的 Edge N-Gram 子字段执行基于前缀的搜索:

  • phrase

    执行精确短语匹配:

    • 文档必须将所有搜索词按 准确顺序 包含在同一字段内。

    • 相当于搜索引擎中的传统词组查询。

    • 非常适合姓名、头衔或准确词语的搜索。

  • anyTermAnyField

    对所有字段执行析取式词项匹配:

    • 返回在 任何 索引字段中匹配 任意 输入词项的文档。

    • 词项之间使用 OR 逻辑组合。

    • 向后兼容的默认策略。

    默认情况下设置此策略。

allTermsAnyFieldallTermsSingleField 已弃用并在 UI 中隐藏,但如有需要可以重新实现。

可以使用 searchStrategy 属性设置合适的搜索策略,示例:

<search:fullTextFilter dataLoader="ordersDl"
                       autoApply="true"
                       searchStrategy="anyTermAnyField"/>

如需覆盖默认策略,在 application.properties 文件添加下列应用程序属性:

jmix.search.default-search-strategy = phrase

自定义搜索策略

另外,也可以创建自己的搜索策略。创建一个 Spring bean,继承自平台中的下列特定基类:

  • AbstractOpenSearchStrategy - 如果使用 OpenSearch。

  • AbstractElasticSearchStrategy - 如果使用 Elasticsearch。

实现 getName()configureRequest(SearchRequestContext)

@Component
public class CustomOpenSearchSearchStrategy extends AbstractOpenSearchStrategy {

    public CustomOpenSearchSearchStrategy(OpenSearchQueryConfigurer queryConfigurer) {
        super(queryConfigurer); (1)
    }

    @Override
    public String getName() {
        return "CustomStrategy"; (2)
    }

    @Override
    public void configureRequest(SearchRequestContext<SearchRequest.Builder> requestContext) { (3)
        queryConfigurer.configureRequest( (4)
                requestContext,
                (queryBuilder, scope) -> (5)
                        queryBuilder.multiMatch(multiMatchQueryBuilder ->
                                multiMatchQueryBuilder
                                        .fields(scope.getFieldList()) (6)
                                        .query(requestContext.getSearchContext().getEscapedSearchText())
                                        .operator(Operator.Or)
                        )
        );
    }
}
1 基类使用平台特定的查询配置器(OpenSearchQueryConfigurerElasticSearchQueryConfigurer)进行初始化,通过 queryConfigurer 字段使用。
2 getName() 返回策略的唯一名称。
3 configureRequest(SearchRequestContext) 是搜索引擎为该策略调用的方法,实现该方法以构建搜索请求。
4 通过 queryConfigurer.configureRequest() 构建查询。配置器会解析搜索范围(包括目标索引以及当前用户允许读取的字段)并使用安全策略。
5 lambda 方法接收平台的特定查询构建器和已解析的 IndexSearchRequestScope
6 使用 scope.getFieldList() 仅搜索有权限读取的字段。

构建查询时,请务必使用 queryConfigurer。如果直接配置请求 builder(例如使用 fields("*")),则不会解析搜索范围,并且不会应用 属性策略,可能导致搜索返回空结果。

然后,可以在 SearchFieldFullTextFilter 组件使用策略名称设置策略。

过滤器组件中的全文搜索条件

当项目中添加了搜索扩展组件后,GenericFilter 组件的 Add condition(添加条件) 弹窗会出现一个新的条件:

add condition

Full-text filter condition editor(全文过滤条件编辑) 对话框中,你可以为全文过滤器设置标题并选择一个搜索策略。如果未设置,则使用默认策略。

condition editor

与过滤器关联的列表组件中的记录会基于全文搜索结果过滤。

视图中使用搜索 API

视图控制器中可以使用搜索 API,示例:

@Autowired
private EntitySearcher entitySearcher;

@Autowired
private SearchResultProcessor searchResultProcessor;

@Subscribe(id = "searchBtn", subject = "clickListener") (1)
public void onSearchBtnClick(final ClickEvent<JmixButton> event) {
    SearchContext searchContext = new SearchContext("silver") (2)
            .setSize(20) (3)
            .setEntities("Order_"); (4)
    SearchResult searchResult = entitySearcher.search(searchContext); (5)
    Collection<Object> instances =
            searchResultProcessor.loadEntityInstances(searchResult); (6)
    // ...
}
1 点击按钮时,从视图控制器调用 API。
2 定义搜索字符串,这一步是必须的,会搜索所有的索引字段,并找出其中是否包含 "silver"
3 设置返回结果集中包含的记录数量。默认值为 10
4 设置搜索的实体。默认会搜素全部的索引实体。
5 使用 EntitySearcher 服务启动搜索。
6 使用 SearchResultProcessor 从搜索结果中获取实体。