Статьи

Учебник по Spring Data Solr: динамические запросы

Solr часто называют поисковым сервером, который мы можем использовать при реализации функций полнотекстового поиска. Тем не менее, часто целесообразно использовать производительность Solr, когда мы реализуем функцию поиска, которая берет свои данные из формы поиска.

В этом случае выполненный поисковый запрос зависит от полученного ввода. Это означает, что количество параметров запроса зависит от ввода, введенного в форму поиска. Другими словами, выполненный поисковый запрос является динамическим.

Предыдущая часть моего учебника по Spring Data Solr рассказала нам, как мы можем добавить пользовательские методы в один репозиторий. Настало время использовать эту информацию и выяснить, как мы можем создавать динамические запросы с помощью Spring Data Solr. Давайте начнем.

Примечание. Эти записи блога предоставляют дополнительную информацию, которая помогает нам понять концепции, описанные в этом сообщении:

Создание динамических запросов

В этом разделе описывается, как мы можем создавать динамические запросы с помощью Spring Data Solr. Он состоит из двух подразделов, которые описаны ниже:

  • В первом подразделе описываются основы, которые нам необходимо знать, прежде чем мы сможем начать работу с реальной функцией поиска.
  • Во втором подразделе описывается, как мы можем реализовать функцию поиска нашего примера приложения, добавив пользовательский метод в наш репозиторий Spring Data Solr.

Изучение Основ

Прежде чем мы сможем приступить к реализации функции поиска нашего примера приложения, нам нужно знать, как мы можем создавать запросы «вручную» с помощью Spring Data Solr. Мы можем создать запрос «вручную», выполнив следующие действия:

  1. Создайте критерии поиска.
  2. Создайте запрос, который содержит используемые критерии поиска.
  3. Выполните созданный запрос.

Эти шаги описаны более подробно ниже.

Создание критериев поиска

Сначала мы должны создать критерии поиска для нашего запроса. Мы можем сделать это, используя классы критериев, которые описаны ниже:

  • Класс org.springframework.data.solr.core.query.SimpleStringCriteria является базовым классом критериев, который используется для указания выполненного запроса с использованием уже отформатированной строки запроса. Строка запроса, указанная в этом классе, выполняется как есть. Таким образом, этот класс нельзя использовать для построения динамических запросов.
  • Org.springframework.data.solr.core.query.Criteria является классом критериев, который используется для построения динамических запросов. Он имеет свободный API, который поддерживает связывание нескольких объектов Criteria .

Создание выполненного запроса

Во-вторых, мы должны создать выполненный запрос. Классы запросов Spring Data Solr описаны ниже:

Выполнение созданного запроса

В-третьих, мы должны выполнить созданный запрос. Класс SolrTemplate реализует несколько методов, которые мы можем использовать для этой цели. Эти методы описаны ниже:

  • Метод long count (окончательный запрос SolrDataQuery) возвращает количество документов, найденных по запросу, заданному в качестве параметра метода.
  • Метод UpdateResponse delete (запрос SolrDataQuery) удаляет документы, которые соответствуют запросу, заданному в качестве параметра метода, и возвращает объект UpdateResponse .
  • Метод T queryForObject (Query query, Class <T> clazz) возвращает один документ, который соответствует запросу, заданному в качестве параметра метода.
  • Метод FacetPage <T> queryForFacetPage (запрос FacetQuery, Class <T> clazz) выполняет фасетный запрос к индексу Solr и возвращает результаты запроса в виде объекта FacetPage .
  • Метод Page <T> queryForPage (Query query, Class <T> clazz) выполняет запрос к индексу Solr и возвращает результаты запроса как реализацию интерфейса Page .

Давайте двигаться дальше и применять эту теорию на практике.

Реализация функции поиска

Требования нашей функции поиска следующие:

  • Функция поиска должна возвращать все записи todo, имя или описание которых содержит какое-либо слово данного поискового термина. Другими словами, если поисковым термином является «Foo Bar», наша функция поиска должна возвращать записи, в заголовке или описании которых содержится «Foo» или «Bar».
  • Поиск должен быть без учета регистра.

Поскольку наша функция поиска не является статичной, мы должны создать ее с помощью динамического запроса. Мы можем создавать динамические запросы с помощью Spring Data Solr, добавив пользовательский метод в наш репозиторий Spring Data Solr. Другими словами, мы должны выполнить следующие шаги:

  1. Создайте пользовательский интерфейс, который объявляет добавленный метод.
  2. Реализуйте созданный интерфейс.
  3. Измените интерфейс репозитория, чтобы расширить созданный интерфейс.

Эти шаги описаны более подробно ниже.

Создание пользовательского интерфейса

Сначала мы должны создать пользовательский интерфейс, который объявляет наш пользовательский метод поиска. Мы можем сделать это, выполнив следующие действия:

  1. Создайте интерфейс под названием CustomTodoDocumentRepository .
  2. Объявите метод search () . Этот метод принимает используемый поисковый термин в качестве параметра метода и возвращает список объектов TodoDocument .

Исходный код интерфейса CustomTodoDocumentRepository выглядит следующим образом:

1
2
3
4
5
6
public interface CustomTodoDocumentRepository {
 
    public List<TodoDocument> search(String searchTerm);
 
    //Other methods are omitted.
}

Реализация созданного интерфейса

Во-вторых, мы должны реализовать пользовательский интерфейс, который мы создали ранее. Мы можем сделать это, выполнив следующие действия:

  1. Создайте класс с именем TodoDocumentRepositoryImpl и реализуйте интерфейс CustomTodoDocumentRepository .
  2. Аннотируйте класс с помощью аннотации @Repository .
  3. Добавьте поле SolrTemplate в класс и аннотируйте его аннотацией @Resource .
  4. Реализуйте метод search () .

Реализация метода search () требует более подробного описания, которое приведено здесь. Мы можем реализовать метод search () , выполнив следующие действия:

  1. Получить слова из условия поиска.
  2. Создайте используемые критерии поиска, вызвав закрытый метод createSearchConditions () и передав слова поиска в качестве параметра метода. Этот метод создает используемые критерии поиска с помощью API класса Criteria .
  3. Создайте выполненный запрос, создав новый объект SimpleQuery, и передайте созданный объект Criteria в качестве параметра конструктора.
  4. Получите результаты поиска, вызвав метод queryForPage () класса SolrTemplate . Передайте созданный запрос и тип ожидаемых объектов результата в качестве параметров метода.
  5. Верните результаты поиска, вызвав метод getContent () интерфейса Page .

Исходный код класса TodoDocumentRepositoryImpl выглядит следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import org.springframework.data.domain.Page;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.stereotype.Repository;
 
import javax.annotation.Resource;
 
@Repository
public class TodoDocumentRepositoryImpl implements CustomTodoDocumentRepository {
 
    @Resource
    private SolrTemplate solrTemplate;
 
    @Override
    public List<TodoDocument> search(String searchTerm) {
        String[] words = searchTerm.split(" ");
 
        Criteria conditions = createSearchConditions(words);
        SimpleQuery search = new SimpleQuery(conditions);
 
        Page results = solrTemplate.queryForPage(search, TodoDocument.class);
        return results.getContent();
    }
 
    private Criteria createSearchConditions(String[] words) {
        Criteria conditions = null;
 
        for (String word: words) {
            if (conditions == null) {
                conditions = new Criteria(“title”).contains(word)
                        .or(new Criteria(“description”).contains(word));
            }
            else {
                conditions = conditions.or(new Criteria(“title”).contains(word))
                        .or(new Criteria(“description”).contains(word));
            }
        }
 
        return conditions;
    }
 
    //Other methods are omitted
}

Модификация интерфейса репозитория

В-третьих, мы должны сделать наш пользовательский метод search () видимым для пользователей нашего репозитория. Мы можем сделать это, расширив интерфейс CustomTodoDocumentRepository . Исходный код интерфейса TodoDocumentRepository выглядит следующим образом:

1
2
3
4
5
import org.springframework.data.solr.repository.SolrCrudRepository;
 
public interface TodoDocumentRepository extends CustomTodoDocumentRepository, SolrCrudRepository<TodoDocument, String> {
 
}

Теперь мы добавили пользовательский метод search () в наш репозиторий Spring Data Solr. Давайте выясним, как мы можем использовать этот метод.

Использование пользовательского метода

Мы можем использовать пользовательский метод, изменив метод search () класса RepositoryTodoIndexService . Новая реализация этого метода очень проста. Он получает результаты поиска, вызывая метод search () нашего репозитория Spring Data Solr и возвращает результаты поиска.

Исходный код класса RepositoryTodoIndexService выглядит следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
import org.springframework.stereotype.Service;
 
import javax.annotation.Resource;
import java.util.List;
 
@Service
public class RepositoryTodoIndexService implements TodoIndexService {
 
    @Resource
    private TodoDocumentRepository repository;
 
    //Other methods are omitted.
 
    @Override
    public List<TodoDocument> search(String searchTerm) {
        return repository.search(searchTerm);
    }
}

Резюме

Теперь мы реализовали функцию динамического поиска с помощью Spring Data Solr. Хотя наша функция поиска была довольно простой, теперь мы должны иметь возможность реализовывать и более сложные запросы.

Этот урок научил нас двум вещам:

  • Мы узнали, как мы можем создавать запросы «вручную» с помощью Spring Data Solr.
  • Мы узнали, что мы должны реализовать динамические методы поиска, добавив пользовательский метод в один репозиторий.

Следующая часть моего учебника Spring Data Solr описывает, как мы можем сортировать результаты наших запросов.

PS Пример приложения этого блога доступен на Github .

Ссылка: руководство по Spring Data Solr: динамические запросы от нашего партнера JCG