當實現一個字符查詢功能時,通常都會以搜索結果的質量高低來降序顯示 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