SOLR-8321: add a (SolrQueryRequest free) SortSpecParsing.parseSortSpec variant

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1717454 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Christine Poerschke 2015-12-01 16:26:28 +00:00
parent 9181fa67d7
commit ab86b188ea
3 changed files with 63 additions and 21 deletions

View File

@ -200,6 +200,9 @@ Other Changes
* SOLR-8351: Improve HdfsDirectory toString representation * SOLR-8351: Improve HdfsDirectory toString representation
(Mike Drob via Gregory Chanan) (Mike Drob via Gregory Chanan)
* SOLR-8321: add a (SolrQueryRequest free) SortSpecParsing.parseSortSpec variant
(Christine Poerschke)
================== 5.4.0 ================== ================== 5.4.0 ==================
Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release

View File

@ -11,6 +11,7 @@ import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField; import org.apache.lucene.search.SortField;
import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException;
import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.schema.SchemaField; import org.apache.solr.schema.SchemaField;
/* /*
@ -57,6 +58,36 @@ public class SortSpecParsing {
* hardcoded default count & offset values. * hardcoded default count & offset values.
*/ */
public static SortSpec parseSortSpec(String sortSpec, SolrQueryRequest req) { public static SortSpec parseSortSpec(String sortSpec, SolrQueryRequest req) {
return parseSortSpecImpl(sortSpec, req.getSchema(), req);
}
/**
* <p>
* The form of the (function free) sort specification string currently parsed is:
* </p>
* <pre>
* SortSpec ::= SingleSort [, SingleSort]*
* SingleSort ::= &lt;fieldname&gt; SortDirection
* SortDirection ::= top | desc | bottom | asc
* </pre>
* Examples:
* <pre>
* score desc #normal sort by score (will return null)
* weight bottom #sort by weight ascending
* weight desc #sort by weight descending
* height desc,weight desc #sort by height descending, and use weight descending to break any ties
* height desc,weight asc #sort by height descending, using weight ascending as a tiebreaker
* </pre>
* @return a SortSpec object populated with the appropriate Sort (which may be null if
* default score sort is used) and SchemaFields (where applicable) using
* hardcoded default count &amp; offset values.
*/
public static SortSpec parseSortSpec(String sortSpec, IndexSchema schema) {
return parseSortSpecImpl(sortSpec, schema, null);
}
private static SortSpec parseSortSpecImpl(String sortSpec, IndexSchema schema,
SolrQueryRequest optionalReq) {
if (sortSpec == null || sortSpec.length() == 0) return newEmptySortSpec(); if (sortSpec == null || sortSpec.length() == 0) return newEmptySortSpec();
List<SortField> sorts = new ArrayList<>(4); List<SortField> sorts = new ArrayList<>(4);
@ -74,12 +105,12 @@ public class SortSpecParsing {
String field = sp.getId(null); String field = sp.getId(null);
Exception qParserException = null; Exception qParserException = null;
if (field == null || !Character.isWhitespace(sp.peekChar())) { if ((field == null || !Character.isWhitespace(sp.peekChar())) && (optionalReq != null)) {
// let's try it as a function instead // let's try it as a function instead
field = null; field = null;
String funcStr = sp.val.substring(start); String funcStr = sp.val.substring(start);
QParser parser = QParser.getParser(funcStr, FunctionQParserPlugin.NAME, req); QParser parser = QParser.getParser(funcStr, FunctionQParserPlugin.NAME, optionalReq);
Query q = null; Query q = null;
try { try {
if (parser instanceof FunctionQParser) { if (parser instanceof FunctionQParser) {
@ -156,7 +187,7 @@ public class SortSpecParsing {
fields.add(null); fields.add(null);
} else { } else {
// try to find the field // try to find the field
SchemaField sf = req.getSchema().getFieldOrNull(field); SchemaField sf = schema.getFieldOrNull(field);
if (null == sf) { if (null == sf) {
if (null != qParserException) { if (null != qParserException) {
throw new SolrException throw new SolrException

View File

@ -38,28 +38,36 @@ public class SortSpecParsingTest extends SolrTestCaseJ4 {
initCore("solrconfig.xml","schema.xml"); initCore("solrconfig.xml","schema.xml");
} }
private static SortSpec doParseSortSpec(String sortSpec, SolrQueryRequest req) {
if (random().nextBoolean()) {
return SortSpecParsing.parseSortSpec(sortSpec, req.getSchema());
} else {
return SortSpecParsing.parseSortSpec(sortSpec, req);
}
}
@Test @Test
public void testSort() throws Exception { public void testSort() throws Exception {
Sort sort; Sort sort;
SortSpec spec; SortSpec spec;
SolrQueryRequest req = req(); SolrQueryRequest req = req();
sort = SortSpecParsing.parseSortSpec("score desc", req).getSort(); sort = doParseSortSpec("score desc", req).getSort();
assertNull("sort", sort);//only 1 thing in the list, no Sort specified assertNull("sort", sort);//only 1 thing in the list, no Sort specified
spec = SortSpecParsing.parseSortSpec("score desc", req); spec = doParseSortSpec("score desc", req);
assertNotNull("spec", spec); assertNotNull("spec", spec);
assertNull(spec.getSort()); assertNull(spec.getSort());
assertNotNull(spec.getSchemaFields()); assertNotNull(spec.getSchemaFields());
assertEquals(0, spec.getSchemaFields().size()); assertEquals(0, spec.getSchemaFields().size());
// SOLR-4458 - using different case variations of asc and desc // SOLR-4458 - using different case variations of asc and desc
sort = SortSpecParsing.parseSortSpec("score aSc", req).getSort(); sort = doParseSortSpec("score aSc", req).getSort();
SortField[] flds = sort.getSort(); SortField[] flds = sort.getSort();
assertEquals(flds[0].getType(), SortField.Type.SCORE); assertEquals(flds[0].getType(), SortField.Type.SCORE);
assertTrue(flds[0].getReverse()); assertTrue(flds[0].getReverse());
spec = SortSpecParsing.parseSortSpec("score aSc", req); spec = doParseSortSpec("score aSc", req);
flds = spec.getSort().getSort(); flds = spec.getSort().getSort();
assertEquals(1, flds.length); assertEquals(1, flds.length);
assertEquals(flds[0].getType(), SortField.Type.SCORE); assertEquals(flds[0].getType(), SortField.Type.SCORE);
@ -67,13 +75,13 @@ public class SortSpecParsingTest extends SolrTestCaseJ4 {
assertEquals(1, spec.getSchemaFields().size()); assertEquals(1, spec.getSchemaFields().size());
assertNull(spec.getSchemaFields().get(0)); assertNull(spec.getSchemaFields().get(0));
sort = SortSpecParsing.parseSortSpec("weight dEsC", req).getSort(); sort = doParseSortSpec("weight dEsC", req).getSort();
flds = sort.getSort(); flds = sort.getSort();
assertEquals(flds[0].getType(), SortField.Type.FLOAT); assertEquals(flds[0].getType(), SortField.Type.FLOAT);
assertEquals(flds[0].getField(), "weight"); assertEquals(flds[0].getField(), "weight");
assertEquals(flds[0].getReverse(), true); assertEquals(flds[0].getReverse(), true);
spec = SortSpecParsing.parseSortSpec("weight dEsC", req); spec = doParseSortSpec("weight dEsC", req);
flds = spec.getSort().getSort(); flds = spec.getSort().getSort();
assertEquals(1, flds.length); assertEquals(1, flds.length);
assertEquals(flds[0].getType(), SortField.Type.FLOAT); assertEquals(flds[0].getType(), SortField.Type.FLOAT);
@ -83,7 +91,7 @@ public class SortSpecParsingTest extends SolrTestCaseJ4 {
assertNotNull(spec.getSchemaFields().get(0)); assertNotNull(spec.getSchemaFields().get(0));
assertEquals("weight", spec.getSchemaFields().get(0).getName()); assertEquals("weight", spec.getSchemaFields().get(0).getName());
sort = SortSpecParsing.parseSortSpec("weight desc,bday ASC", req).getSort(); sort = doParseSortSpec("weight desc,bday ASC", req).getSort();
flds = sort.getSort(); flds = sort.getSort();
assertEquals(flds[0].getType(), SortField.Type.FLOAT); assertEquals(flds[0].getType(), SortField.Type.FLOAT);
assertEquals(flds[0].getField(), "weight"); assertEquals(flds[0].getField(), "weight");
@ -92,7 +100,7 @@ public class SortSpecParsingTest extends SolrTestCaseJ4 {
assertEquals(flds[1].getField(), "bday"); assertEquals(flds[1].getField(), "bday");
assertEquals(flds[1].getReverse(), false); assertEquals(flds[1].getReverse(), false);
//order aliases //order aliases
sort = SortSpecParsing.parseSortSpec("weight top,bday asc", req).getSort(); sort = doParseSortSpec("weight top,bday asc", req).getSort();
flds = sort.getSort(); flds = sort.getSort();
assertEquals(flds[0].getType(), SortField.Type.FLOAT); assertEquals(flds[0].getType(), SortField.Type.FLOAT);
assertEquals(flds[0].getField(), "weight"); assertEquals(flds[0].getField(), "weight");
@ -100,7 +108,7 @@ public class SortSpecParsingTest extends SolrTestCaseJ4 {
assertEquals(flds[1].getType(), SortField.Type.LONG); assertEquals(flds[1].getType(), SortField.Type.LONG);
assertEquals(flds[1].getField(), "bday"); assertEquals(flds[1].getField(), "bday");
assertEquals(flds[1].getReverse(), false); assertEquals(flds[1].getReverse(), false);
sort = SortSpecParsing.parseSortSpec("weight top,bday bottom", req).getSort(); sort = doParseSortSpec("weight top,bday bottom", req).getSort();
flds = sort.getSort(); flds = sort.getSort();
assertEquals(flds[0].getType(), SortField.Type.FLOAT); assertEquals(flds[0].getType(), SortField.Type.FLOAT);
assertEquals(flds[0].getField(), "weight"); assertEquals(flds[0].getField(), "weight");
@ -110,14 +118,14 @@ public class SortSpecParsingTest extends SolrTestCaseJ4 {
assertEquals(flds[1].getReverse(), false); assertEquals(flds[1].getReverse(), false);
//test weird spacing //test weird spacing
sort = SortSpecParsing.parseSortSpec("weight DESC, bday asc", req).getSort(); sort = doParseSortSpec("weight DESC, bday asc", req).getSort();
flds = sort.getSort(); flds = sort.getSort();
assertEquals(flds[0].getType(), SortField.Type.FLOAT); assertEquals(flds[0].getType(), SortField.Type.FLOAT);
assertEquals(flds[0].getField(), "weight"); assertEquals(flds[0].getField(), "weight");
assertEquals(flds[1].getField(), "bday"); assertEquals(flds[1].getField(), "bday");
assertEquals(flds[1].getType(), SortField.Type.LONG); assertEquals(flds[1].getType(), SortField.Type.LONG);
//handles trailing commas //handles trailing commas
sort = SortSpecParsing.parseSortSpec("weight desc,", req).getSort(); sort = doParseSortSpec("weight desc,", req).getSort();
flds = sort.getSort(); flds = sort.getSort();
assertEquals(flds[0].getType(), SortField.Type.FLOAT); assertEquals(flds[0].getType(), SortField.Type.FLOAT);
assertEquals(flds[0].getField(), "weight"); assertEquals(flds[0].getField(), "weight");
@ -167,7 +175,7 @@ public class SortSpecParsingTest extends SolrTestCaseJ4 {
assertEquals("bday", schemaFlds.get(2).getName()); assertEquals("bday", schemaFlds.get(2).getName());
//handles trailing commas //handles trailing commas
sort = SortSpecParsing.parseSortSpec("weight desc,", req).getSort(); sort = doParseSortSpec("weight desc,", req).getSort();
flds = sort.getSort(); flds = sort.getSort();
assertEquals(flds[0].getType(), SortField.Type.FLOAT); assertEquals(flds[0].getType(), SortField.Type.FLOAT);
assertEquals(flds[0].getField(), "weight"); assertEquals(flds[0].getField(), "weight");
@ -179,10 +187,10 @@ public class SortSpecParsingTest extends SolrTestCaseJ4 {
//the value sources get wrapped, so the out field is different than the input //the value sources get wrapped, so the out field is different than the input
assertEquals(flds[0].getField(), "strdist(str(foo_s1),literal(junk), dist=org.apache.lucene.search.spell.JaroWinklerDistance)"); assertEquals(flds[0].getField(), "strdist(str(foo_s1),literal(junk), dist=org.apache.lucene.search.spell.JaroWinklerDistance)");
sort = SortSpecParsing.parseSortSpec("", req).getSort(); sort = doParseSortSpec("", req).getSort();
assertNull(sort); assertNull(sort);
spec = SortSpecParsing.parseSortSpec("", req); spec = doParseSortSpec("", req);
assertNotNull(spec); assertNotNull(spec);
assertNull(spec.getSort()); assertNull(spec.getSort());
@ -196,19 +204,19 @@ public class SortSpecParsingTest extends SolrTestCaseJ4 {
//test some bad vals //test some bad vals
try { try {
sort = SortSpecParsing.parseSortSpec("weight, desc", req).getSort(); sort = doParseSortSpec("weight, desc", req).getSort();
assertTrue(false); assertTrue(false);
} catch (SolrException e) { } catch (SolrException e) {
//expected //expected
} }
try { try {
sort = SortSpecParsing.parseSortSpec("w", req).getSort(); sort = doParseSortSpec("w", req).getSort();
assertTrue(false); assertTrue(false);
} catch (SolrException e) { } catch (SolrException e) {
//expected //expected
} }
try { try {
sort = SortSpecParsing.parseSortSpec("weight desc, bday", req).getSort(); sort = doParseSortSpec("weight desc, bday", req).getSort();
assertTrue(false); assertTrue(false);
} catch (SolrException e) { } catch (SolrException e) {
} }