我们使用Solr查询数据时,有时候难免需要获得经过排序之后的数据。在页面上 使用Solr查询的时候,如下图:
我们只要直接再上图的sort框中,输入
要排序的字段+排序方式(即desc/asc)
然后查询就可以得到排序后的结果。但是这毕竟是Solr自动做的排序,如果我们想要在代码层次上面使用solr排序的话,那要怎么样呢?
以下是一个Sort使用的实例(是项目中用到的一部分代码,所以需要各位看官自己剔除一些不必要的代码段)。
public List<String> companyResultsCId(String tiaojian) {
String cursormark = "";
List<String> resultMap = new ArrayList<>();
while (true) {
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery(tiaojian);
solrQuery.setRows(1000);
if (StringUtils.isEmpty(cursormark)) {
solrQuery.set(CursorMarkParams.CURSOR_MARK_PARAM, CursorMarkParams.CURSOR_MARK_START);
} else {
solrQuery.set(CursorMarkParams.CURSOR_MARK_PARAM, cursormark);
}
// 根据id排序且用游标完成分页
solrQuery.setSort("id", SolrQuery.ORDER.desc);
try {
QueryResponse response = solrClient.query(solrQuery, SolrRequest.METHOD.POST);
SolrDocumentList results = response.getResults();
if (results != null && results.size() > 0) {
for (SolrDocument doc : results) {
if (doc.containsKey("id")) {
resultMap.add(doc.get("id").toString());
}
}
} else {
break;
}
if (results.size() == results.getNumFound() || cursormark.equals(response.getNextCursorMark())) {
break;
} else {
cursormark = response.getNextCursorMark();
}
} catch (SolrServerException | IOException e) {
log.error("跑数据异常,{}", e);
}
}
return resultMap;
}
接手这个项目也有几天时间了,我发现这个项目中,似乎都是用的是id去做排序。今天正好遇到一个需要用updatetime做排序的需求。所以我就在上文这个代码的基础上面,加了一些改动,想增加一下代码的可复用性。如下:
/**
* 排序功能
* @param tiaojian
* @param sort
* @return
*/
public List<String> companyResultsCId(String tiaojian,String sort) {
String cursormark = "";
List<String> resultMap = new ArrayList<>();
while (true) {
SolrQuery solrQuery = new SolrQuery();
solrQuery.setQuery(tiaojian);
solrQuery.setRows(1000);
if (StringUtils.isEmpty(cursormark)) {
solrQuery.set(CursorMarkParams.CURSOR_MARK_PARAM, CursorMarkParams.CURSOR_MARK_START);
} else {
solrQuery.set(CursorMarkParams.CURSOR_MARK_PARAM, cursormark);
}
// 排序。
solrQuery.setSort(sort, SolrQuery.ORDER.asc);
try {
QueryResponse response = solrClient.query(solrQuery, SolrRequest.METHOD.POST);
SolrDocumentList results = response.getResults();
if (results != null && results.size() > 0) {
for (SolrDocument doc : results) {
if (doc.containsKey("id")) {
resultMap.add(doc.get("id").toString());
}
}
} else {
break;
}
if (results.size() == results.getNumFound() || cursormark.equals(response.getNextCursorMark())) {
break;
} else {
cursormark = response.getNextCursorMark();
}
} catch (SolrServerException | IOException e) {
log.error("跑数据异常,{}", e);
}
}
return resultMap;
}
看上去好像没有什么问题,但是运行起来确实会报错。
报错如下:
debug一下发现是游标分页的问题。
上网搜了一下,用游标做深度分页说是只能用主键排序。
那我要是想用时间排序怎么办?我上网没有搜到相关的回答。索性就自己找了找方法。
后来发现可以set两次,如果是用时间排序,那么我就先时间再id,如下:
至于是用desc还是用asc,这个倒是没有什么关系,大家不要看到代码被误导了。按照自己的需求来就可以。