Использование поиска в UI
Визуальные компоненты
Дополнение Search предоставляет два UI-компонента: SearchField и FullTextFilter.
Эти компоненты доступны в палитре Add Component в Дизайнере экранов Jmix Studio сразу после установки дополнения в ваш проект.
Если вы не используете дизайнер экранов, объявите пространство имен search в XML-дескрипторе вашего экрана вручную:
<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:
-
settingsButtonVisible- показывает/скрывает кнопку настроек. Значение по умолчанию:true. -
searchButtonVisible- показывает/скрывает кнопку поиска. Значение по умолчанию:true. -
searchStrategy- определяет применяемую стратегию поиска. Если стратегия не указана, используется стратегия по умолчанию. -
entities- определяет сущности для поиска. Несколько сущностей могут быть перечислены в виде последовательности, разделенной запятыми:<search:searchField id="searchField" entities="Customer, Order_"/>
Конфигурация во время выполнения
Компонент SearchField включает кнопку настроек для динамической конфигурации. Пользователи могут динамически настраивать:
-
Стратегию поиска
-
Размер поиска (количество результатов)
-
Целевые сущности
По умолчанию searchField открывает встроенный SearchResultsView. Этот экран управляет процессом выполнения запроса к поисковому движку и отображает список результатов в контейнере навигации или в новом диалоговом окне, в зависимости от атрибута openMode компонента searchField.
Если вы хотите изменить эту функциональность, вы можете настроить 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компонентFullTextFilterавтоматически применяется кDataLoaderпри изменении своего значения.
FullTextFilter работает следующим образом: он находит идентификаторы сущностей через полнотекстовый поиск и затем добавляет условие, содержащее эти идентификаторы, в загрузчик данных. Следовательно, когда DataGrid связан с этим загрузчиком данных, он будет отображать только те записи, которые соответствуют критериям полнотекстового поиска, в сочетании с другими фильтрами, если они есть.
Стратегии поиска
Стратегия поиска определяет, как обрабатывается поисковый термин. По сути, она конфигурирует поисковый запрос с определенным запросом.
Компоненты SearchField и FullTextFilter поддерживают следующие встроенные стратегии поиска:
-
startsWithЭта стратегия доступна только когда @ExtendedSearch включен хотя бы для одного определения индекса. Выполняет поиск на основе префикса, используя предварительно индексированные подполя Edge N-Gram:
-
Генерирует все префиксы от jmix.search.min-prefix-length (по умолчанию:
3) до jmix.search.max-prefix-length (по умолчанию:8). -
Обеспечивает значительно более высокую производительность по сравнению с запросами по шаблону (wildcard).
-
Когда введенный термин превышает максимальную длину префикса, выполняется резервный запрос по шаблону, если jmix.search.wildcard-prefix-query-enabled =
true(значение по умолчанию).Для терминов короче, чем jmix.search.min-prefix-length, поиск всегда возвращает пустой результат.
-
-
phraseВыполняет поиск точной фразы:
-
Документы должны содержать все поисковые термины в точном порядке в рамках одного поля.
-
Эквивалентно традиционному фразовому запросу в поисковых системах.
-
Идеально подходит для поиска по именам, названиям или точным формулировкам.
-
-
anyTermAnyFieldВыполняет дизъюнктивное сопоставление терминов по всем полям:
-
Возвращаются документы, соответствующие любому из введенных терминов в любом индексированном поле.
-
Термины комбинируются с логикой ИЛИ.
-
Стратегия по умолчанию для обратной совместимости.
Эта стратегия установлена по умолчанию.
-
allTermsAnyField и allTermsSingleField объявлены устаревшими и скрыты из пользовательского интерфейса, но при необходимости могут быть повторно реализованы.
|
Вы можете установить нужную стратегию, используя атрибут searchStrategy, например:
<search:fullTextFilter dataLoader="ordersDl"
autoApply="true"
searchStrategy="anyTermAnyField"/>
Чтобы переопределить стратегию по умолчанию, добавьте следующее свойство в ваш файл application.properties:
jmix.search.default-search-strategy = phrase
Пользовательские стратегии поиска
Дополнительно вы можете создать пользовательскую стратегию поиска. Для этой цели вам нужно создать новый Spring-бин, реализующий один из специфичных для платформы интерфейсов:
-
OpenSearchSearchStrategy- если вы используете OpenSearch. -
ElasticsearchSearchStrategy- если вы используете Elasticsearch.
Затем вам нужно реализовать 2 метода:
-
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
Когда дополнение Search добавлено в проект, в диалоговом окне Add condition компонента GenericFilter появляется новое условие:

В диалоговом окне Full-text filter condition editor вы можете определить надпись для полнотекстового фильтра и выбрать стратегию поиска. Если стратегия поиска не выбрана, то используется стратегия по умолчанию.

Впоследствии записи в компоненте списка, связанном с фильтром, будут фильтроваться на основе результата полнотекстового поиска.
Использование Search API в экранах
Вы можете использовать Search 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 используется для извлечения сущностей из результата поиска. |