当实现一个字符查询功能时,一般都会以搜索结果的质量高低来降序显示 relevancy of each search result. 这也正是Solr的做法。 然而,有时也需要采用手工干预的方式来调整展示顺序。其中一个场景就是在之前文中previous part of my Spring Data Solr tutorial.提到的”常规”检索的实现 该文说明了如何使用Spring Data Solr来分类查询结果。具体就是说明如何通过修改示例应用的查询功能以使用id字段的值来降序展示查询结果。 文章可以分为三大块:
咱们继续往下看 | ![]() petert
|
定义排序条件查询语句中的排序是通过 Sort 类来实现的。常见的排序方式如下:
下来看看如何创建实现上述条件的Sort对象 首先,创建一个按单字段排序的Sort对象。假设我们想按照Id字段的值来升序排列,实现代码如下:
| ![]() petert
|
其次,创建满足场景二中的Sort对象。这里假设我们使用id 和description 为查询字段并将结果以降序排列。实现代码如下:
最后,创建满足场景三的Sort对象。这里假设降序排列description升序排列id 字段的查询结果。实现代码如下:
现在知道了如何创建相应的Sort对象,再来看看如何在具体情况中的使用。 | ![]() petert
|
查询方法结果排序当使用查询方法时,可以按以下步骤来排序查询结果: 1. 在方法体中加入Sort参数。用来传递排序设置 2. 在服务层创建一个Sort对象,当调用查询方法时将其作为变量传递过去
下面具体看一下是如何实现的. 修改Repository接口我们可以通过在查询方法体中添加一个变量来控制将来查询结果的排序情况。下面来看看查询方法的定义 | ![]() petert
|
从方法名派生查询语句如果使用了从方法名生成查询语句的策略,那需要在TodoDocumentRepositoryinterface的 findByTitleContainsOrDescriptionContains() 方法中添加Sort参数。源码如下:
命名查询语句如果使用命名查询语句的策略,那需要在odoDocumentRepository 的thefindByNamedQuery() 方法中添加Sort参数。源码如下:
注意: 如果使用的是Spring Data Solr RC1该功能不能正常工作源于 known bug. 如此,要么使用snapshot依赖或是使用RC2版本 | ![]() petert
|
@Query 注解如果使用@Query注解模式,我们要在theTodoDocumentRepository 接口中的 findByQueryAnnotation() 方法中添加Sort 参数。源码如下:
注意: 如果使用的是Spring Data Solr RC1该功能不能正常工作源于known bug.如此,要么使用snapshot依赖或是使用RC2版本 查询方法通过修改RepositoryIndexService 类中的thesearch() 方法实现修改查询方法体 1. 创建sortByIdDesc()方法实现以文档的id为关键字降序排列结果 2. 通过调用 TodoDocumentRepository接口中定义的查询方法获取查询结果 3. 返回查询结果集 再来看看search()方法的不同实现方式
| ![]() petert
|
从方法名称生成查询当我们按照方法名称策略通过查询生成来构造我们的查询时,可以使用TodoDocumentRepository接口的findByTitleContainsOrDescriptionContains() 方法获得查询结果。 RepositoryTodoIndexService 类的相关部分源代码大致如下:
命名查询当我们用命名查询构建我们的查询时,我们可以利用TodoDocumentRepository接口的findByNamedQuery()方法得到查询结果。 RepositoryTodoIndexService 相关部分的代码如下:
| ![]() 赵亮-碧海情天
|
@Query 注解
|
01 | import org.springframework.data.domain.Sort; |
02 | import org.springframework.stereotype.Service; |
03 | import javax.annotation.Resource; |
04 | import java.util.List; |
05 |
06 | @Service |
07 | public class RepositoryTodoIndexService implements TodoIndexService { |
08 |
09 | @Resource |
10 | private TodoDocumentRepository repository; |
11 |
12 | @Override |
13 | public List<TodoDocument> search(String searchTerm) { |
14 | return repository.findByQueryAnnotation(searchTerm, sortByIdDesc()); |
15 | } |
16 |
17 | private Sort sortByIdDesc() { |
18 | return new Sort(Sort.Direction.DESC, "id" ); |
19 | } |
20 | |
21 | //Other methods are omitted |
22 | } |
排序动态查询的查询结果
因为动态查询 是通过 在仓储接口中添加自定义方法实现的, 所以对动态查询的结果进行排序的步骤不会影响到我们的实例应用中的Service层。
我们可以通过对我们自定义仓储接口的实现进行如下修改来排序动态查询的结果集。
-
在TodoDocumentRepositoryImpl类中添加一个 private sortByIdDesc() 方法。这个方法返回一个Sort对象,这个对象指定查询结果集以id降序排列。
-
修改TodoDocumentRepositoryImpl 的search()方法.使用Query 接口的addSort()方法来设置执行查询的排序选项,并且将创建的Sort对象作为参数传递给addSort()。
TodoDocumentRepositoryImpl 类的相关方法如下:
01 | import org.springframework.data.domain.Page; |
02 | import org.springframework.data.domain.Sort; |
03 | import org.springframework.data.solr.core.SolrTemplate; |
04 | import org.springframework.data.solr.core.query.Criteria; |
05 | import org.springframework.data.solr.core.query.SimpleQuery; |
06 | import org.springframework.stereotype.Repository; |
07 |
08 | import javax.annotation.Resource; |
09 | import java.util.List; |
10 |
11 | @Repository |
12 | public class TodoDocumentRepositoryImpl implements CustomTodoDocumentRepository { |
13 |
14 | @Resource |
15 | private SolrTemplate solrTemplate; |
16 |
17 | @Override |
18 | public List<TodoDocument> search(String searchTerm) { |
19 | String[] words = searchTerm.split( " " ); |
20 |
21 | Criteria conditions = createSearchConditions(words); |
22 | SimpleQuery search = new SimpleQuery(conditions); |
23 | |
24 | //SET SORT OPTIONS |
25 | search.addSort(sortByIdDesc()); |
26 |
27 | Page results = solrTemplate.queryForPage(search, TodoDocument. class ); |
28 | return results.getContent(); |
29 | } |
30 |
31 | private Criteria createSearchConditions(String[] words) { |
32 | Criteria conditions = null ; |
33 |
34 | for (String word: words) { |
35 | if (conditions == null ) { |
36 | conditions = new Criteria( "id" ).contains(word) |
37 | .or( new Criteria( "description" ).contains(word)); |
38 | } |
39 | else { |
40 | conditions = conditions.or( new Criteria( "id" ).contains(word)) |
41 | .or( new Criteria( "description" ).contains(word)); |
42 | } |
43 | } |
44 |
45 | return conditions; |
46 | } |
47 |
48 | private Sort sortByIdDesc() { |
49 | return new Sort(Sort.Direction.DESC, "id" ); |
50 | } |
51 |
52 | //Other methods are omitted |
53 | } |

GoodLoser
翻译于 2个月前
0人顶
顶 翻译的不错哦!
@Query注解
|
01 | import org.springframework.data.domain.Sort; |
02 | import org.springframework.stereotype.Service; |
03 | import javax.annotation.Resource; |
04 | import java.util.List; |
05 |
06 | @Service |
07 | public class RepositoryTodoIndexService implements TodoIndexService { |
08 |
09 | @Resource |
10 | private TodoDocumentRepository repository; |
11 |
12 | @Override |
13 | public List<TodoDocument> search(String searchTerm) { |
14 | return repository.findByQueryAnnotation(searchTerm, sortByIdDesc()); |
15 | } |
16 |
17 | private Sort sortByIdDesc() { |
18 | return new Sort(Sort.Direction.DESC, "id" ); |
19 | } |
20 | |
21 | //Other methods are omitted |
22 | } |
对动态查询的查询结果进行排序
由于动态查询是通过给一个repository接口添加自定义方法来创建的,对一个动态查询的结果进行排序所需要的步骤,将不会对我们示例应用中的服务层产生影响。
要给动态查询的结果进行排序,我们可以把我们自定义的repository接口的实现类做如下改变:
-
给TodoDocumentRepositoryImpl类添加一个私有的sortByIdDesc()方法。该方法返回一个Sort对象,用来指定查询结果按照id 字段进行倒序排序。
-
修改TodoDocumentRepositoryImpl类的search() 方法。通过使用Query接口的addSort()方法并传入一个创建好的Sort对象,来设定排序。
TodoDocumentRepositoryImpl类中的相关部分,就像下面这样:
01 | import org.springframework.data.domain.Page; |
02 | import org.springframework.data.domain.Sort; |
03 | import org.springframework.data.solr.core.SolrTemplate; |
04 | import org.springframework.data.solr.core.query.Criteria; |
05 | import org.springframework.data.solr.core.query.SimpleQuery; |
06 | import org.springframework.stereotype.Repository; |
07 |
08 | import javax.annotation.Resource; |
09 | import java.util.List; |
10 |
11 | @Repository |
12 | public class TodoDocumentRepositoryImpl implements CustomTodoDocumentRepository { |
13 |
14 | @Resource |
15 | private SolrTemplate solrTemplate; |
16 |
17 | @Override |
18 | public List<TodoDocument> search(String searchTerm) { |
19 | String[] words = searchTerm.split( " " ); |
20 |
21 | Criteria conditions = createSearchConditions(words); |
22 | SimpleQuery search = new SimpleQuery(conditions); |
23 | |
24 | //SET SORT OPTIONS |
25 | search.addSort(sortByIdDesc()); |
26 |
27 | Page results = solrTemplate.queryForPage(search, TodoDocument. class ); |
28 | return results.getContent(); |
29 | } |
30 |
31 | private Criteria createSearchConditions(String[] words) { |
32 | Criteria conditions = null ; |
33 |
34 | for (String word: words) { |
35 | if (conditions == null ) { |
36 | conditions = new Criteria( "id" ).contains(word) |
37 | .or( new Criteria( "description" ).contains(word)); |
38 | } |
39 | else { |
40 | conditions = conditions.or( new Criteria( "id" ).contains(word)) |
41 | .or( new Criteria( "description" ).contains(word)); |
42 | } |
43 | } |
44 |
45 | return conditions; |
46 | } |
47 |
48 | private Sort sortByIdDesc() { |
49 | return new Sort(Sort.Direction.DESC, "id" ); |
50 | } |
51 |
52 | //Other methods are omitted |
53 | } |

lwei
翻译于 2个月前
0人顶
顶 翻译的不错哦!
总结
|