本帖最后由 不会飞的小凯凯 于 2016-4-15 17:56 编辑
问题导读:
1.排序条件如何定义?
2.有哪些查询方法?
3.怎么样排序动态查询的排序结果?
该文说明了如何使用Spring Data Solr来分类查询结果。具体就是说明如何通过修改示例应用的查询功能以使用id字段的值来降序展示查询结果。 文章可以分为三大块: 第一部分讲解了如何在查询语句中设置排序条件 第二部分说的是使用查询方法时如何排序查询结果 第三部分告诉我们如何进行动态查询结果的排序
咱们继续往下看
定义排序条件查询语句中的排序是通过 Sort 类来实现的。常见的排序方式如下: 下来看看如何创建实现上述条件的Sort对象 首先,创建一个按单字段排序的Sort对象。假设我们想按照Id字段的值来升序排列,实现代码如下: [mw_shl_code=applescript,true]new Sort(Sort.Direction.ASC, "id")[/mw_shl_code] 其次,创建满足场景二中的Sort对象。这里假设我们使用id 和description 为查询字段并将结果以降序排列。实现代码如下: [mw_shl_code=applescript,true]new Sort(Sort.Direction.DESC, "id", "description")[/mw_shl_code] 最后,创建满足场景三的Sort对象。这里假设降序排列description升序排列id 字段的查询结果。实现代码如下: [mw_shl_code=applescript,true]new Sort(Sort.Direction.DESC, "description").and(new Sort(Sort.Direction.ASC, "id"))[/mw_shl_code] 现在知道了如何创建相应的Sort对象,再来看看如何在具体情况中的使用。
查询方法结果排序
当使用查询方法时,可以按以下步骤来排序查询结果: 1. 在方法体中加入Sort参数。用来传递排序设置 2. 在服务层创建一个Sort对象,当调用查询方法时将其作为变量传递过去 下面具体看一下是如何实现的.
修改Repository接口
我们可以通过在查询方法体中添加一个变量来控制将来查询结果的排序情况。下面来看看查询方法的定义
从方法名派生查询语句如果使用了从方法名生成查询语句的策略,那需要在TodoDocumentRepositoryinterface的 findByTitleContainsOrDescriptionContains() 方法中添加Sort参数。源码如下: [mw_shl_code=applescript,true]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);
}[/mw_shl_code]
命名查询语句如果使用命名查询语句的策略,那需要在odoDocumentRepository 的thefindByNamedQuery() 方法中添加Sort参数。源码如下: [mw_shl_code=applescript,true]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);
}[/mw_shl_code]
@Query 注解如果使用@Query注解模式,我们要在theTodoDocumentRepository 接口中的 findByQueryAnnotation() 方法中添加Sort 参数。源码如下: [mw_shl_code=applescript,true]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);
}[/mw_shl_code] 注意: 如果使用的是Spring Data Solr RC1该功能不能正常工作源于 known bug.如此,要么使用snapshot依赖或是使用RC2版本
查询方法通过修改RepositoryIndexService 类中的thesearch() 方法实现修改查询方法体 1. 创建sortByIdDesc()方法实现以文档的id为关键字降序排列结果 2. 通过调用 TodoDocumentRepository接口中定义的查询方法获取查询结果 3. 返回查询结果集 再来看看search()方法的不同实现方式
从方法名称生成查询当我们按照方法名称策略通过查询生成来构造我们的查询时,可以使用TodoDocumentRepository接口的findByTitleContainsOrDescriptionContains() 方法获得查询结果。 RepositoryTodoIndexService 类的相关部分源代码大致如下: [mw_shl_code=applescript,true]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");
}
//其它的方法省略
}[/mw_shl_code]
命名查询当我们用命名查询构建我们的查询时,我们可以利用TodoDocumentRepository接口的findByNamedQuery()方法得到查询结果。 RepositoryTodoIndexService 相关部分的代码如下: [mw_shl_code=applescript,true]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");
}
//其它的方法省略
}[/mw_shl_code]
@Query 注解
当我们使用@Query注解来构建我们的查询时,我们可以使用TodoDocumentRepository接口的findByQueryAnnotation()方法来获取查询结果。 RepositoryTodoIndexService 类的相关部分如下: [mw_shl_code=applescript,true]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
}[/mw_shl_code]
排序动态查询的查询结果
我们可以通过对我们自定义仓储接口的实现进行如下修改来排序动态查询的结果集。 TodoDocumentRepositoryImpl 类的相关方法如下: [mw_shl_code=applescript,true]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
}
[/mw_shl_code]
总结现在我们已经了解了使用Spring Data Solr时,如何对查询结果进行排序。本教程教会我们三件事:
英文原文:Spring Data Solr Tutorial: Sorting
|