当实现一个字符查询功能时,通常都会以搜索结果的质量高低来降序显示 relevancy of each search result。 这也正是Solr的作法。
然而,有时也须要采用手工干预的方式来调整展现顺序。其中一个场景就是在以前文中 previous part of my Spring Data Solr tutorial。 提到的”常规”检索的实现
该文说明了如何使用 Spring Data Solr 来分类查询结果。具体就是说明如何经过修改示例应用的查询功能以使用id字段的值来降序展现查询结果。
文章能够分为三大块:html
我们继续往下看java
查询语句中的排序是经过 Sort 类来实现的。常见的排序方式以下:git
下来看看如何建立实现上述条件的Sort对象
首先,建立一个按单字段排序的Sort对象。假设咱们想按照Id字段的值来升序排列,实现代码以下:github
new Sort(Sort.Direction.ASC, "id")
其次,建立知足场景二中的Sort对象。这里假设咱们使用id 和description 为查询字段并将结果以降序排列。实现代码以下:spring
new Sort(Sort.Direction.DESC, "id", "description")
最后,建立知足场景三的Sort对象。这里假设降序排列description升序排列id 字段的查询结果。实现代码以下:apache
new Sort(Sort.Direction.DESC, "description").and(new Sort(Sort.Direction.ASC, "id"))
如今知道了如何建立相应的Sort对象,再来看看如何在具体状况中的使用。api
当使用查询方法时,能够按如下步骤来排序查询结果:dom
下面具体看一下是如何实现的.ide
咱们能够经过在查询方法体中添加一个变量来控制未来查询结果的排序状况。下面来看看查询方法的定义:学习
若是使用了从方法名生成查询语句的策略,那须要在TodoDocumentRepositoryinterface的
findByTitleContainsOrDescriptionContains() 方法中添加Sort参数。源码以下:
import org.springframework.data.domain.Sort; import org.springframework.data.solr.repository.Query; import org.springframework.data.solr.repository.SolrCrudRepository; import java.util.List; public interface TodoDocumentRepository extends PartialUpdateRepository, SolrCrudRepository<TodoDocument, String> { public List<TodoDocument> findByTitleContainsOrDescriptionContains(String title, String description, Sort sort); }
若是使用命名查询语句的策略,那须要在odoDocumentRepository 的thefindByNamedQuery() 方法中添加Sort参数。源码以下:
import org.springframework.data.domain.Sort; import org.springframework.data.solr.repository.Query; import org.springframework.data.solr.repository.SolrCrudRepository; import java.util.List; public interface TodoDocumentRepository extends PartialUpdateRepository, SolrCrudRepository<TodoDocument, String> { @Query(name = "TodoDocument.findByNamedQuery") public List<TodoDocument> findByNamedQuery(String searchTerm, Sort sort); }
注意: 若是使用的是Spring Data Solr RC1该功能不能正常工做源于 known bug.
如此,要么使用snapshot依赖或是使用RC2版本。
若是使用@Query注解模式,咱们要在theTodoDocumentRepository 接口中的 findByQueryAnnotation() 方法中添加Sort 参数。源码以下:
import org.springframework.data.domain.Sort; import org.springframework.data.solr.repository.Query; import org.springframework.data.solr.repository.SolrCrudRepository; import java.util.List; public interface TodoDocumentRepository extends PartialUpdateRepository, SolrCrudRepository<TodoDocument, String> { @Query("title:*?0* OR description:*?0*") public List<TodoDocument> findByQueryAnnotation(String searchTerm, Sort sort); }
注意: 若是使用的是Spring Data Solr RC1该功能不能正常工做源于 known bug。如此,要么使用snapshot依赖或是使用RC2版本。
经过修改RepositoryIndexService 类中的thesearch() 方法实现修改查询方法体
再来看看search()方法的不一样实现方式。
当咱们按照方法名称策略经过查询生成来构造咱们的查询时,可使用TodoDocumentRepository接口的findByTitleContainsOrDescriptionContains() 方法得到查询结果。
RepositoryTodoIndexService 类的相关部分源代码大体以下:
import org.springframework.data.domain.Sort; 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, sortByIdDesc()); } private Sort sortByIdDesc() { return new Sort(Sort.Direction.DESC, "id"); } //Other methods are omitted }
命名查询
当咱们用命名查询构建咱们的查询时,咱们能够利用TodoDocumentRepository接口的findByNamedQuery()方法获得查询结果。
RepositoryTodoIndexService 相关部分的代码以下:
import org.springframework.data.domain.Sort; 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, sortByIdDesc()); } private Sort sortByIdDesc() { return new Sort(Sort.Direction.DESC, "id"); } //Other methods are omitted }
@Query 注解
当咱们使用@Query注解来构建咱们的查询时,咱们可使用TodoDocumentRepository接口的findByQueryAnnotation()方法来获取查询结果。
RepositoryTodoIndexService 类的相关部分以下:
import org.springframework.data.domain.Sort; 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, sortByIdDesc()); } private Sort sortByIdDesc() { return new Sort(Sort.Direction.DESC, "id"); } //Other methods are omitted }
由于 动态查询 是经过 在仓储接口中添加自定义方法实现的, 因此对动态查询的结果进行排序的步骤不会影响到咱们的实例应用中的Service层。
咱们能够经过对咱们自定义仓储接口的实现进行以下修改来排序动态查询的结果集。
TodoDocumentRepositoryImpl 类的相关方法以下:
import org.springframework.data.domain.Page; import org.springframework.data.domain.Sort; 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; import java.util.List; @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); //SET SORT OPTIONS search.addSort(sortByIdDesc()); 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("id").contains(word) .or(new Criteria("description").contains(word)); } else { conditions = conditions.or(new Criteria("id").contains(word)) .or(new Criteria("description").contains(word)); } } return conditions; } private Sort sortByIdDesc() { return new Sort(Sort.Direction.DESC, "id"); } //Other methods are omitted }
如今咱们已经了解了使用Spring Data Solr时,如何对查询结果进行排序。本教程教会咱们三件事:
下一次,个人Spring Data Solr教程会描述如何对咱们的查询结果进行分页。
P.S. 本博客文章中的样例程序已经发布到Github (query方法和动态查询)。
原文: Spring Data Solr Tutorial: Sorting
转载自:开源中国 - petert, lwei, 赵亮-碧海情天, GoodLoser, HTCKF