Статьи

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

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

  • Функция поиска должна возвращать все записи todo, заголовок или описание которых содержит заданный критерий поиска.
  • Поиск должен быть без учета регистра.

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

  1. Создайте метод запроса.
  2. Используйте метод созданного запроса.

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

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

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

Методы запроса — это методы, которые

  1. добавлен в интерфейс хранилища.
  2. используется для указания поискового запроса, который выполняется при вызове метода запроса.
  3. используется для создания статических запросов (запросов, которые всегда имеют одинаковое количество параметров запроса).

Мы можем создавать методы запросов с помощью Spring Data Solr, используя следующие методы:

  • Генерация запроса из имени метода
  • Именованные запросы
  • @Query аннотация

Эти методы описаны более подробно в следующих подразделах.

Генерация запроса из имени метода

Генерация запроса по имени метода — это стратегия генерации запроса, в которой выполненный запрос анализируется по имени метода запроса.

  1. Имя метода запроса должно начинаться со специального префикса, который идентифицирует метод запроса. Эти префиксы: найти, найти, получить, получить, читать и читать . Этот префикс удаляется из имени метода при разборе выполненного запроса.
  2. Выражения свойств используются для ссылки на свойства нашего класса документов.
  3. Специальные ключевые слова используются вместе с выражениями свойств для указания операторов, используемых в созданном запросе. Эти ключевые слова добавляются к имени метода запроса после выражения свойства.
  4. Мы можем объединить выражения свойств, добавив между ними ключевое слово And или Or .
  5. Количество параметров метода запроса должно быть равно количеству выражений свойств, используемых в его имени.

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

Как мы помним, наша функция поиска должна возвращать все записи дел, заголовок или описание которых содержит заданный поисковый термин. Кроме того, наш класс документа имеет два свойства, которые мы используем в этом запросе. Эти свойства называются заголовок и описание . Мы можем создать имя метода, которое удовлетворяет требованиям нашей функции поиска, выполнив следующие действия:

  1. Добавьте префикс findBy в начало имени метода.
  2. Добавьте выражение свойства свойства title после префикса.
  3. Добавьте ключевое слово Contains после выражения свойства.
  4. Добавьте ключевое слово Or к имени метода.
  5. Добавьте выражение свойства для свойства description после ключевого слова Or .
  6. Добавьте ключевое слово Contains к имени метода.
  7. Добавьте два параметра метода в наш метод запроса. Первый параметр сопоставлен со свойством title, а второй — со свойством description .

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

1
2
3
4
5
6
7
import org.springframework.data.solr.repository.SolrCrudRepository;
import java.util.List;
 
public interface TodoDocumentRepository extends SolrCrudRepository<TodoDocument, String> {
 
    public List<TodoDocument> findByTitleContainsOrDescriptionContains(String title, String description);
}

Примечание. Этот метод запроса не будет работать, если поисковый термин содержит более одного слова.

Именованные Запросы

Именованные запросы — это запросы, которые объявлены в отдельном файле свойств и связаны с правильным методом запроса. Правила, касающиеся файла свойств, используемого для объявления именованных запросов, описаны ниже:

  • Расположение файла свойств по умолчанию — META-INF / solr-named-queries.properties, но мы можем настроить его, используя свойство namedQueriesLocation аннотации @EnableSolrRepositories .
  • Ключ каждого именованного запроса создается по следующей формуле: [Имя класса документа]. [Имя именованного запроса] .

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

  • Имя метода запроса, который выполняет именованный запрос, должно совпадать с именем именованного запроса.
  • Если имя метода запроса не совпадает с именем именованного запроса, метод запроса должен быть аннотирован аннотацией @Query, а имя именованного запроса должно быть настроено с помощью свойства name аннотации @Query. ,

Мы можем реализовать метод запроса с именованными запросами, выполнив следующие шаги:

  1. Укажите именованный запрос.
  2. Создайте метод запроса.

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

Указание именованного запроса

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

  1. Создайте файл свойств, который содержит именованные запросы.
  2. Создайте ключ для именованного запроса, используя формулу, описанную ранее. Поскольку имя нашего класса документов — TodoDocument , ключ нашего именованного запроса — TodoDocument.findByNamedQuery .
  3. Создайте именованный запрос, используя синтаксис синтаксического анализатора запросов Lucene . Поскольку наш запрос должен возвращать документы, заголовок или описание которых содержит заданный поисковый термин, наш запрос выглядит следующим образом: title: *? 0 * ИЛИ описание: *? 0 * (значение ? 0 заменяется значением первого параметра метода запроса).

Содержимое файла META-INF / solr-named-query.properties выглядит следующим образом:

1
TodoDocument.findByNamedQuery=title:*?0* OR description:*?0*

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

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

  1. Добавьте метод findByNamedQuery () в интерфейс TodoDocumentRepository . Этот метод возвращает список объектов TodoDocument и принимает единственный параметр String с именем searchTerm .
  2. Аннотируйте метод с помощью аннотации @Query и установите для его свойства name значение TodoDocument.findByNamedQuery. Этот шаг не является обязательным, поскольку имя метода запроса совпадает с именем именованного запроса, но я хотел продемонстрировать здесь использование аннотации @Query .

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

01
02
03
04
05
06
07
08
09
10
import org.springframework.data.solr.repository.Query;
import org.springframework.data.solr.repository.SolrCrudRepository;
 
import java.util.List;
 
public interface TodoDocumentRepository extends SolrCrudRepository<TodoDocument, String> {
 
    @Query(name = "TodoDocument.findByNamedQuery")
    public List<TodoDocument> findByNamedQuery(String searchTerm);
}

@Query Annotation

Аннотация @Query может использоваться для указания запроса, который выполняется при вызове метода запроса. Мы можем создать метод запроса, который удовлетворяет требованиям нашей функции поиска, выполнив следующие действия:

  1. Добавьте метод findByQueryAnnotation () в интерфейс TodoDocumentRepository . Этот метод возвращает список объектов TodoDocument, и у него есть единственный параметр String с именем searchTerm .
  2. Аннотируйте метод с помощью аннотации @Query .
  3. Установите выполненный запрос как значение аннотации @Query . Мы можем создать запрос, используя синтаксический анализатор запросов Lucene . Поскольку наш запрос должен возвращать документы, заголовок или описание которых содержит заданный поисковый термин, правильный запрос: title: *? 0 * ИЛИ описание: *? 0 * (вместо ? 0 подставляется значение первого параметра метода запроса) ,

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

01
02
03
04
05
06
07
08
09
10
import org.springframework.data.solr.repository.Query;
import org.springframework.data.solr.repository.SolrCrudRepository;
 
import java.util.List;
 
public interface TodoDocumentRepository extends SolrCrudRepository<TodoDocument, String> {
 
    @Query("title:*?0* OR description:*?0*")
    public List<TodoDocument> findByQueryAnnotation(String searchTerm);
}

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

Мы можем использовать метод созданного запроса, выполнив следующие действия:

  1. Объявите метод search () в интерфейсе TodoIndexService .
  2. Добавьте реализацию метода search () в класс RepositoryTodoIndexService .

Эти шаги описаны более подробно в следующих подразделах.

Объявление метода поиска

Наш первый шаг — объявить метод поиска в интерфейсе TodoIndexService . Соответствующая часть интерфейса TodoIndexService выглядит следующим образом:

1
2
3
4
5
6
import java.util.List;
 
public interface TodoIndexService {
 
    public List<TodoDocument> search(String searchTerm);
}

Реализация метода поиска

Наш второй шаг — реализовать метод search () . Наша реализация довольно проста. Он получает список объектов TodoDocument , вызывая правильный метод интерфейса TodoDocumentRepository, и возвращает этот список.

Имя метода запроса зависит от метода, использованного для создания метода запроса. Различные реализации описаны ниже.

Генерация запроса из имени метода

Когда мы генерируем запрос по имени метода запроса, наша реализация получает список объектов TodoDocument , вызывая метод findByTitleContainsOrDescriptionContains () интерфейса TodoDocumentRepository и возвращает этот список.

Соответствующая часть класса RepositoryTodoIndexService выглядит следующим образом:

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

Именованные Запросы

Если мы используем именованные запросы, наша реализация получает список объектов TodoDocument , вызывая метод findByNamedQuery () интерфейса TodoDocumentRepository и возвращает этот список.

Соответствующая часть класса RepositoryTodoIndexService выглядит следующим образом:

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

@Query Annotation

Когда мы используем аннотацию @Query , наша реализация получает список объектов TodoDocument , вызывая метод findByQueryAnnotation () интерфейса TodoDocumentRepository и возвращает этот список.

Соответствующая часть класса RepositoryTodoIndexService выглядит следующим образом:

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

Выбор правильного метода создания запроса

Очевидный вопрос:

Как лучше всего добавить методы запросов в наши репозитории Spring Data Solr?

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

  • Если созданный запрос очень прост, генерация запроса по имени метода часто является лучшим выбором. Проблема этого подхода заключается в том, что реализация «сложных» запросов с помощью этого подхода приводит к длинным и безобразным именам методов.
  • Это хорошая идея, чтобы держать наши запросы рядом с нашими методами запросов. Преимущество использования аннотации @Query заключается в том, что мы можем увидеть выполненный запрос и наш метод запроса, прочитав исходный код нашего интерфейса репозитория.
  • Если мы хотим отделить выполненные запросы от нашего интерфейса репозитория, мы должны использовать именованные запросы. Проблема этого подхода заключается в том, что мы должны проверять выполненный запрос из файла свойств, что довольно громоздко.

Резюме

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

  • Мы знаем, что такое методы методов запросов и как мы можем их создавать.
  • Мы знакомы с различными методами создания запросов и знаем, когда их использовать.

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