mirror of https://github.com/apache/lucene.git
SOLR-170 -- adding a 'sort' parameter that works for both dismax and standard request handlers. The ';' is still suported (if the 'sort' parameter is not in the query). This also adds a new test class for StandardRequestHandler.
git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@533566 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d273f54151
commit
aa93003946
|
@ -158,6 +158,10 @@ New Features
|
|||
<requestDispatcher handleSelect="true" > to your solrconfig.xml
|
||||
See the example solrconfig.xml for details. (ryan)
|
||||
|
||||
26. SOLR-170: StandardRequestHandler now supports a "sort" parameter.
|
||||
Using the ';' syntax is still supported, but it is recommended to
|
||||
transition to the new syntax. (ryan)
|
||||
|
||||
Changes in runtime behavior
|
||||
1. Highlighting using DisMax will only pick up terms from the main
|
||||
user query, not boost or filter queries (klaas).
|
||||
|
|
|
@ -37,6 +37,8 @@ public abstract class SolrParams {
|
|||
public static final String WT ="wt";
|
||||
/** query string */
|
||||
public static final String Q ="q";
|
||||
/** sort order */
|
||||
public static final String SORT ="sort";
|
||||
/** Lucene query string(s) for filtering the results without affecting scoring */
|
||||
public static final String FQ ="fq";
|
||||
/** zero based offset of matching documents to retrieve */
|
||||
|
@ -364,3 +366,5 @@ public abstract class SolrParams {
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ public class StandardRequestHandler extends RequestHandlerBase {
|
|||
{
|
||||
|
||||
SolrParams p = req.getParams();
|
||||
String sreq = p.get(Q);
|
||||
String qstr = p.required().get(Q);
|
||||
|
||||
String defaultField = p.get(DF);
|
||||
|
||||
|
@ -78,24 +78,36 @@ public class StandardRequestHandler extends RequestHandlerBase {
|
|||
flags |= U.setReturnFields(fl, rsp);
|
||||
}
|
||||
|
||||
if (sreq==null) throw new SolrException(400,"Missing queryString");
|
||||
List<String> commands = StrUtils.splitSmart(sreq,';');
|
||||
String sortStr = p.get(SORT);
|
||||
if( sortStr == null ) {
|
||||
// TODO? should we disable the ';' syntax with config?
|
||||
// legacy mode, where sreq is query;sort
|
||||
List<String> commands = StrUtils.splitSmart(qstr,';');
|
||||
if( commands.size() == 2 ) {
|
||||
// TODO? add a deprication warning to the response header
|
||||
qstr = commands.get( 0 );
|
||||
sortStr = commands.get( 1 );
|
||||
}
|
||||
else if( commands.size() == 1 ) {
|
||||
// This is need to support the case where someone sends: "q=query;"
|
||||
qstr = commands.get( 0 );
|
||||
}
|
||||
else if( commands.size() > 2 ) {
|
||||
throw new SolrException( 400, "If you want to use multiple ';' in the query, use the 'sort' param." );
|
||||
}
|
||||
}
|
||||
|
||||
String qs = commands.size() >= 1 ? commands.get(0) : "";
|
||||
Query query = QueryParsing.parseQuery(qs, defaultField, p, req.getSchema());
|
||||
|
||||
// If the first non-query, non-filter command is a simple sort on an indexed field, then
|
||||
// we can use the Lucene sort ability.
|
||||
Sort sort = null;
|
||||
if (commands.size() >= 2) {
|
||||
QueryParsing.SortSpec sortSpec = QueryParsing.parseSort(commands.get(1), req.getSchema());
|
||||
if( sortStr != null ) {
|
||||
QueryParsing.SortSpec sortSpec = QueryParsing.parseSort(sortStr, req.getSchema());
|
||||
if (sortSpec != null) {
|
||||
sort = sortSpec.getSort();
|
||||
// ignore the count for now... it's currently only controlled by start & limit on req
|
||||
// count = sortSpec.getCount();
|
||||
}
|
||||
}
|
||||
|
||||
// parse the query from the 'q' parameter (sort has been striped)
|
||||
Query query = QueryParsing.parseQuery(qstr, defaultField, p, req.getSchema());
|
||||
|
||||
DocListAndSet results = new DocListAndSet();
|
||||
NamedList facetInfo = null;
|
||||
List<Query> filters = U.parseFilterQueries(req);
|
||||
|
@ -120,7 +132,7 @@ public class StandardRequestHandler extends RequestHandlerBase {
|
|||
if (null != facetInfo) rsp.add("facet_counts", facetInfo);
|
||||
|
||||
try {
|
||||
NamedList dbg = U.doStandardDebug(req, qs, query, results.docList);
|
||||
NamedList dbg = U.doStandardDebug(req, qstr, query, results.docList);
|
||||
if (null != dbg) {
|
||||
if (null != filters) {
|
||||
dbg.add("filter_queries",req.getParams().getParams(FQ));
|
||||
|
@ -188,3 +200,5 @@ public class StandardRequestHandler extends RequestHandlerBase {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -785,7 +785,7 @@ public class SolrPluginUtils {
|
|||
*/
|
||||
public static Sort getSort(SolrQueryRequest req) {
|
||||
|
||||
String sort = req.getParam("sort");
|
||||
String sort = req.getParam(SolrParams.SORT);
|
||||
if (null == sort || sort.equals("")) {
|
||||
return null;
|
||||
}
|
||||
|
@ -866,3 +866,5 @@ public class SolrPluginUtils {
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -261,7 +261,7 @@ curl http://localhost:8983/solr/update --data-binary '<commit/>'
|
|||
<li><a href="http://localhost:8983/solr/select/?indent=on&q=video&fl=name,id">q=video&fl=name,id</a> (return only name and id fields) </li>
|
||||
<li><a href="http://localhost:8983/solr/select/?indent=on&q=video&fl=name,id,score">q=video&fl=name,id,score</a> (return relevancy score as well) </li>
|
||||
<li><a href="http://localhost:8983/solr/select/?indent=on&q=video&fl=*,score">q=video&fl=*,score</a> (return all stored fields, as well as relevancy score) </li>
|
||||
<li><a href="http://localhost:8983/solr/select/?indent=on&q=video;price desc&fl=name,id">q=video;price desc&fl=name,id</a> (add sort specification: sort by price descending) </li>
|
||||
<li><a href="http://localhost:8983/solr/select/?indent=on&q=video;price desc&fl=name,id">q=video&sort=price desc&fl=name,id</a> (add sort specification: sort by price descending) </li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
|
@ -273,21 +273,21 @@ curl http://localhost:8983/solr/update --data-binary '<commit/>'
|
|||
<title>Sorting</title>
|
||||
|
||||
<p>
|
||||
Solr provides a simple extension to the Lucene QueryParser syntax for specifying sort options. After your search, add a semi-colon followed by a list of "field direction" pairs...
|
||||
Solr provides a simple extension to the Lucene QueryParser syntax for specifying sort options. Use the 'sort' parameter to specify "field direction" pairs...
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="http://localhost:8983/solr/select/?indent=on&q=video;price+desc">video; price desc</a></li>
|
||||
<li><a href="http://localhost:8983/solr/select/?indent=on&q=video;price+asc">video; price asc</a></li>
|
||||
<li><a href="http://localhost:8983/solr/select/?indent=on&q=video;inStock+asc+price+desc">video; inStock asc, price desc</a></li>
|
||||
<li><a href="http://localhost:8983/solr/select/?indent=on&q=video&sort=price+desc">video; price desc</a></li>
|
||||
<li><a href="http://localhost:8983/solr/select/?indent=on&q=video&sort=price+asc">video; price asc</a></li>
|
||||
<li><a href="http://localhost:8983/solr/select/?indent=on&q=video&sort=inStock+asc+price+desc">video; inStock asc, price desc</a></li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
"score" can also be used as a field name when specifying a sort...
|
||||
</p>
|
||||
<ul>
|
||||
<li><a href="http://localhost:8983/solr/select/?indent=on&q=video;score+desc">video; score desc</a></li>
|
||||
<li><a href="http://localhost:8983/solr/select/?indent=on&q=video;inStock+asc,score+desc">video; inStock asc, score desc</a></li>
|
||||
<li><a href="http://localhost:8983/solr/select/?indent=on&q=video&sort=score+desc">video; score desc</a></li>
|
||||
<li><a href="http://localhost:8983/solr/select/?indent=on&q=video&sort=inStock+asc,score+desc">video; inStock asc, score desc</a></li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
|
|
|
@ -583,7 +583,6 @@ public class BasicFunctionalityTest extends AbstractSolrTestCase {
|
|||
,"facet.mincount","0"
|
||||
,"facet.offset","0"
|
||||
,"facet.limit","3"
|
||||
,"sort","true"
|
||||
)
|
||||
,"*[count(//lst[@name='trait_s']/int)=3]"
|
||||
,"//lst[@name='trait_s']/int[@name='Tool'][.='2']"
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.solr.handler;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.solr.core.SolrCore;
|
||||
import org.apache.solr.request.LocalSolrQueryRequest;
|
||||
import org.apache.solr.request.MapSolrParams;
|
||||
import org.apache.solr.request.SolrParams;
|
||||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.util.AbstractSolrTestCase;
|
||||
|
||||
/**
|
||||
* Most of the tests for StandardRequestHandler are in ConvertedLegacyTest
|
||||
*
|
||||
*/
|
||||
public class StandardRequestHandlerTest extends AbstractSolrTestCase {
|
||||
|
||||
@Override public String getSchemaFile() { return "schema.xml"; }
|
||||
@Override public String getSolrConfigFile() { return "solrconfig.xml"; }
|
||||
@Override public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
lrf = h.getRequestFactory("standard", 0, 20 );
|
||||
}
|
||||
|
||||
public void testSorting() throws Exception {
|
||||
assertU(adoc("id", "10", "title", "test", "val_s", "aaa"));
|
||||
assertU(adoc("id", "11", "title", "test", "val_s", "bbb"));
|
||||
assertU(adoc("id", "12", "title", "test", "val_s", "ccc"));
|
||||
assertU(commit());
|
||||
|
||||
Map<String,String> args = new HashMap<String, String>();
|
||||
args.put( SolrParams.Q, "title:test" );
|
||||
args.put( "indent", "true" );
|
||||
SolrQueryRequest req = new LocalSolrQueryRequest( SolrCore.getSolrCore(), new MapSolrParams( args) );
|
||||
|
||||
|
||||
assertQ("Make sure they got in", req
|
||||
,"//*[@numFound='3']"
|
||||
);
|
||||
|
||||
args.put( SolrParams.SORT, "val_s asc" );
|
||||
assertQ("with sort param [asc]", req
|
||||
,"//*[@numFound='3']"
|
||||
,"//result/doc[1]/int[@name='id'][.='10']"
|
||||
,"//result/doc[2]/int[@name='id'][.='11']"
|
||||
,"//result/doc[3]/int[@name='id'][.='12']"
|
||||
);
|
||||
|
||||
args.put( SolrParams.SORT, "val_s desc" );
|
||||
assertQ("with sort param [desc]", req
|
||||
,"//*[@numFound='3']"
|
||||
,"//result/doc[1]/int[@name='id'][.='12']"
|
||||
,"//result/doc[2]/int[@name='id'][.='11']"
|
||||
,"//result/doc[3]/int[@name='id'][.='10']"
|
||||
);
|
||||
|
||||
// Using legacy ';' param
|
||||
args.remove( SolrParams.SORT );
|
||||
args.put( SolrParams.Q, "title:test; val_s desc" );
|
||||
assertQ("with sort param [desc]", req
|
||||
,"//*[@numFound='3']"
|
||||
,"//result/doc[1]/int[@name='id'][.='12']"
|
||||
,"//result/doc[2]/int[@name='id'][.='11']"
|
||||
,"//result/doc[3]/int[@name='id'][.='10']"
|
||||
);
|
||||
|
||||
args.put( SolrParams.Q, "title:test; val_s asc" );
|
||||
assertQ("with sort param [desc]", req
|
||||
,"//*[@numFound='3']"
|
||||
,"//result/doc[1]/int[@name='id'][.='10']"
|
||||
,"//result/doc[2]/int[@name='id'][.='11']"
|
||||
,"//result/doc[3]/int[@name='id'][.='12']"
|
||||
);
|
||||
}
|
||||
}
|
|
@ -298,7 +298,7 @@
|
|||
|
||||
|
||||
<fields>
|
||||
<field name="id" type="integer" indexed="true" stored="true"/>
|
||||
<field name="id" type="integer" indexed="true" stored="true" multiValued="false"/>
|
||||
<field name="name" type="nametext" indexed="true" stored="true"/>
|
||||
<field name="text" type="text" indexed="true" stored="false"/>
|
||||
<field name="subject" type="text" indexed="true" stored="true"/>
|
||||
|
|
Loading…
Reference in New Issue