使用 UI 中的搜索
可视化组件
搜索扩展组件提供两个 UI 组件:SearchField
和 FullTextFilter
。
在为项目添加了搜索扩展组件后,这两个 UI 组件可以通过 Studio 视图设计器 的 Add Component 工具箱添加。
如果不使用视图设计器,也可以在视图的 XML 中手动声明 search
命名空间:
<view xmlns="http://jmix.io/schema/flowui/view"
xmlns:search="http://jmix.io/schema/search/ui"
title="msg://searchView.title">
SearchField
SearchField
组件提供一个文本框和一个执行搜索的按钮。
视图中使用 SearchField
的示例:
<view xmlns="http://jmix.io/schema/flowui/view"
xmlns:search="http://jmix.io/schema/search/ui"
title="msg://searchView.title">
<layout>
<search:searchField id="searchField"/>
</layout>
</view>
SearchField
组件的属性:
-
searchStrategy
- 定义使用的搜索策略。如未定义,则使用默认策略。 -
entities
- 设置在指定的实体内进行搜索。多个实体可用逗号分隔:<search:searchField id="searchField" entities="Customer, Order_"/>
默认情况下,searchField
打开内置的 SearchResultsView
视图。该视图会对搜索引擎进行查询,并根据 searchField
配置的 openMode
的不同在导航页面或对话框内展示搜索结果。
如需自定义该行为,可以按如下设置 SearchCompletedHandler
:
@Autowired
private DialogWindows dialogWindows;
@ViewComponent
private SearchField searchField;
@Install(to = "searchField", subject = "searchCompletedHandler")
private void searchFieldSearchCompletedHandler(
final SearchField.SearchCompletedEvent event) {
SearchResult searchResult = event.getSearchResult();
DialogWindow<SearchResultsView> searchResultsDialog =
dialogWindows.view(UiComponentUtils.getView(this),
SearchResultsView.class)
.build();
SearchResultsView view = searchResultsDialog.getView();
view.initView(new SearchFieldContext(searchField));
searchResultsDialog.open();
}
另外,也可以使用组件的 setSearchCompletedHandler()
方法设置。
FullTextFilter
FullTextFilter
组件的功能与 propertyFilter 属性过滤器 类似。
视图中使用 fullTextFilter
的示例:
<data>
<collection id="ordersDc"
class="com.company.demo.entity.Order">
<loader id="ordersDl"
readOnly="true">
<query>
<![CDATA[select e from Order_ e]]>
</query>
</loader>
<fetchPlan extends="_base">
<property name="customer"
fetchPlan="_base"/>
</fetchPlan>
</collection>
</data>
<layout>
<search:fullTextFilter dataLoader="ordersDl"
autoApply="true"/>
<dataGrid id="ordersDataGrid"
width="100%"
dataContainer="ordersDc">
<columns>
<column property="number"/>
<column property="date"/>
<column property="amount"/>
<column property="product"/>
</columns>
</dataGrid>
</layout>
FullTextFilter
组件的属性:
-
dataLoader
- 设置需要过滤的DataLoader
。 -
searchStrategy
- 搜索策略。如未定义,则使用默认策略。 -
autoApply
- 如果设置为true
,则在组件值发生变更时,组件自动对DataLoader
使用过滤。
FullTextFilter
的工作流程:首先使用全文搜索找到实体的 id,然后在数据加载器中添加带这些 ID 的过滤条件。接下来,关联至该加载器的 DataGrid
只展示符合全文搜索条件的记录,如果 DataGrid
组件有其他过滤器,也会生效。
搜索策略
搜索策略定义如何处理搜索词。基本上是使用一些查询语句配置搜索请求。
SearchField
和 FullTextFilter
组件支持下列内置的搜索策略:
-
anyTermAnyField
- 文档的任何索引字段匹配至少一个输入词。 -
allTermsAnyField
- 文档的任何索引字段以任何顺序匹配上所有的输入词。这是默认策略。 -
allTermsSingleField
- 文档至少有一个字段包含任意顺序的所有输入词。 -
phrase
- 文档至少有一个字段包含输入顺序的所有输入词。
可以使用 strategy
属性设置合适的搜索策略,示例:
<search:fullTextFilter dataLoader="ordersDl"
autoApply="true"
searchStrategy="anyTermAnyField"/>
如需覆盖默认策略,在 application.properties
文件添加下列应用程序属性:
jmix.search.default-search-strategy = allTermsSingleField
自定义搜索策略
另外,也可以创建自己的搜索策略。为此,首先创建一个实现下列接口之一的 Spring bean:
-
OpenSearchSearchStrategy
- 如果使用 OpenSearch。 -
ElasticsearchSearchStrategy
- 如果使用 Elasticsearch。
然后需要实现两个方法:
-
String getName()
- 返回策略的唯一名称。 -
void configureRequest(SearchRequest.Builder requestBuilder, SearchContext searchContext)
- 根据需要使用传入的 builder 配置所需的搜索请求。
@Component
public class CustomOpenSearchSearchStrategy implements OpenSearchSearchStrategy {
@Override
public String getName() {
return "CustomStrategy";
}
@Override
public void configureRequest(SearchRequest.Builder requestBuilder, SearchContext searchContext) {
//configure your request
requestBuilder.query(queryBuilder ->
queryBuilder.multiMatch(multiMatchQueryBuilder ->
multiMatchQueryBuilder.fields("*")
.query(searchContext.getSearchText())
)
);
}
}
然后,可以在 SearchField
或 FullTextFilter
组件使用策略名称设置策略。
过滤器组件中的全文搜索条件
当项目中添加了搜索扩展组件后,GenericFilter 组件的 Add condition(添加条件) 弹窗会出现一个新的条件:
在 Full-text filter 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 从搜索结果中获取实体。 |