mirror of https://github.com/apache/lucene.git
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:
parent
9181fa67d7
commit
ab86b188ea
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -52,11 +53,41 @@ public class SortSpecParsing {
|
||||||
* height desc,weight desc #sort by height descending, and use weight descending to break any ties
|
* 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
|
* height desc,weight asc #sort by height descending, using weight ascending as a tiebreaker
|
||||||
* </pre>
|
* </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 & offset values.
|
||||||
|
*/
|
||||||
|
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 ::= <fieldname> 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
|
* @return a SortSpec object populated with the appropriate Sort (which may be null if
|
||||||
* default score sort is used) and SchemaFields (where applicable) using
|
* default score sort is used) and SchemaFields (where applicable) using
|
||||||
* hardcoded default count & offset values.
|
* hardcoded default count & offset values.
|
||||||
*/
|
*/
|
||||||
public static SortSpec parseSortSpec(String sortSpec, SolrQueryRequest req) {
|
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
|
||||||
|
|
|
@ -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) {
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue