Solr通常被称为搜索服务器,我们可以在实现全文搜索功能时使用它。 但是,当我们实现从搜索表单获取其输入的搜索功能时,利用Solr的性能通常是明智的。
在这种情况下,执行的搜索查询取决于收到的输入。 这意味着查询参数的数量取决于输入到搜索表单的输入。 换句话说,执行的搜索查询是动态的。
我的Spring Data Solr教程的前一部分教我们如何将自定义方法添加到单个存储库。 现在该使用这些信息并了解如何使用Spring Data Solr创建动态查询。 让我们开始吧。
注意:这些博客条目提供了其他信息,可以帮助我们理解此博客文章中描述的概念:
- 使用Maven运行Solr
- Spring Data Solr教程:Solr简介
- Spring Data Solr教程:配置
- Spring Data Solr教程CRUD(几乎)
- Spring Data Solr教程:将自定义方法添加到单个存储库
创建动态查询
本节描述了如何使用Spring Data Solr创建动态查询。 它分为两个小节,如下所述:
- 第一部分描述了在开始实际搜索功能之前需要了解的基础知识。
- 第二部分描述了如何通过向Spring Data Solr存储库添加自定义方法来实现示例应用程序的搜索功能。
学习基础
在开始实现示例应用程序的搜索功能之前,我们需要知道如何使用Spring Data Solr“手动”创建查询。 我们可以按照以下步骤“手动”创建查询:
- 创建搜索条件。
- 创建查询,其中包含使用的搜索条件。
- 执行创建的查询。
下面将更详细地描述这些步骤。
创建搜索条件
首先,我们必须为查询创建搜索条件。 我们可以使用以下描述的条件类来做到这一点:
- org.springframework.data.solr.core.query.SimpleStringCriteria类是基本条件类,用于通过使用已经格式化的查询字符串来指定执行的查询。 此类中指定的查询字符串按原样执行。 因此,此类不能用于构建动态查询。
- org.springframework.data.solr.core.query.Criteria是用于构建动态查询的条件类。 它具有流畅的API,该API支持多个Criteria对象的链接。
创建执行的查询
其次,我们必须创建执行的查询。 下面介绍Spring Data Solr的查询类:
- org.springframework.data.solr.core.query.SimpleQuery类是一个支持分页和分组的查询类。
- org.springframework.data.solr.core.query.SimpleFacetQuery类是支持多面搜索的查询类。
- org.springframework.data.solr.core.query.SimpleFilterQuery类是支持过滤器查询的查询类。
执行创建的查询
第三,我们必须执行创建的查询。 SolrTemplate类实现了一些可用于此目的的方法。 下面介绍了这些方法:
- long count(最终SolrDataQuery查询)方法返回使用作为方法参数给出的查询找到的文档数。
- UpdateResponse delete(SolrDataQuery query)方法删除与作为方法参数给出的查询匹配的文档,并返回一个UpdateResponse对象。
- T queryForObject(Query query,Class <T> clazz)方法返回与作为方法参数给出的查询匹配的单个文档。
- FacetPage <T> queryForFacetPage(FacetQuery query,Class <T> clazz)方法针对Solr索引执行构面查询,并将查询结果作为FacetPage对象返回。
- Page <T> queryForPage(Query query,Class <T> clazz)方法对Solr索引执行查询,并作为Page接口的实现返回查询结果。
让我们继续实践该理论。
实现搜索功能
我们的搜索功能的要求如下:
- 搜索功能必须返回名称或描述包含给定搜索词的某些单词的所有待办事项。 换句话说,如果搜索词是“ Foo Bar”,则我们的搜索功能必须返回标题或描述包含“ Foo”或“ Bar”的待办事项条目。
- 搜索必须不区分大小写。
因为我们的搜索功能不是静态的,所以我们必须使用动态查询来创建它。 我们可以通过在Spring Data Solr存储库中添加自定义方法来使用Spring Data Solr创建动态查询。 换句话说,我们必须遵循以下步骤:
- 创建一个自定义接口,该接口声明添加的方法。
- 实现创建的接口。
- 修改存储库接口以扩展创建的接口。
下面将更详细地描述这些步骤。
创建自定义界面
首先,我们必须创建一个自定义接口,该接口声明我们的自定义搜索方法。 我们可以按照以下步骤进行操作:
- 创建一个名为CustomTodoDocumentRepository的接口。
- 声明search()方法。 此方法将使用的搜索词作为方法参数,并返回TodoDocument对象的列表。
CustomTodoDocumentRepository接口的源代码如下所示:
public interface CustomTodoDocumentRepository {public List<TodoDocument> search(String searchTerm);//Other methods are omitted.
}
实施创建的接口
其次,我们必须实现我们之前创建的自定义接口。 我们可以按照以下步骤进行操作:
- 创建一个名为TodoDocumentRepositoryImpl的类,并实现CustomTodoDocumentRepository接口。
- 用@Repository批注对类进行批注。
- 将SolrTemplate字段添加到类中,并使用@Resource注释对其进行注释。
- 实现search()方法。
search()方法的实现需要在此给出更详细的描述。 我们可以通过执行以下步骤来实现search()方法:
- 获取搜索词的单词。
- 通过调用私有createSearchConditions()方法并将搜索词的单词作为方法参数来构造使用的搜索条件。 此方法通过使用Criteria类的API创建使用的搜索条件。
- 通过创建新的SimpleQuery对象来创建执行的查询,并将创建的Criteria对象作为构造函数参数传递。
- 通过调用SolrTemplate类的queryForPage()方法获取搜索结果。 将创建的查询和预期结果对象的类型作为方法参数传递。
- 通过调用Page接口的getContent()方法来返回搜索结果。
TodoDocumentRepositoryImpl类的源代码如下所示:
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 {@Resourceprivate SolrTemplate solrTemplate;@Overridepublic 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接口的源代码如下所示:
import org.springframework.data.solr.repository.SolrCrudRepository;public interface TodoDocumentRepository extends CustomTodoDocumentRepository, SolrCrudRepository<TodoDocument, String> {}
现在,我们向Spring Data Solr存储库添加了一个自定义search()方法。 让我们找出如何使用此方法。
使用自定义方法
我们可以通过修改RepositoryTodoIndexService类的search()方法来使用自定义方法。 此方法的新实现非常简单。 它通过调用我们的Spring Data Solr存储库的search()方法获取搜索结果,并返回搜索结果。
RepositoryTodoIndexService类的源代码如下所示:
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.List;@Service
public class RepositoryTodoIndexService implements TodoIndexService {@Resourceprivate TodoDocumentRepository repository;//Other methods are omitted.@Overridepublic List<TodoDocument> search(String searchTerm) {return repository.search(searchTerm);}
}
摘要
现在,我们已经使用Spring Data Solr实现了动态搜索功能。 尽管我们的搜索功能非常简单,但是我们现在也应该能够实现更复杂的查询。
本教程教了我们两件事:
- 我们学习了如何使用Spring Data Solr“手动”创建查询。
- 我们了解到,必须通过向单个存储库添加自定义方法来实现动态搜索方法。
我的Spring Data Solr教程的下一部分描述了如何对查询结果进行排序。
PS此博客文章的示例应用程序可在Github上获得 。
翻译自: https://www.javacodegeeks.com/2013/05/spring-data-solr-tutorial-dynamic-queries.html