mirror of https://github.com/apache/lucene.git
SOLR-2959: edismax now respects the magic fields '_val_' and '_query_'
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1303256 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3d73a3014e
commit
85bba7eed7
|
@ -698,6 +698,9 @@ Bug Fixes
|
|||
* SOLR-3260: DataImportHandler: ScriptTransformer gives better error messages when
|
||||
problems arise on initalization (no Script Engine, invalid script, etc). (James Dyer)
|
||||
|
||||
* SOLR-2959: edismax now respects the magic fields '_val_' and '_query_'
|
||||
(Michael Watts, hossman)
|
||||
|
||||
Other Changes
|
||||
----------------------
|
||||
* SOLR-2922: Upgrade commons-io and commons-lang to 2.1 and 2.6, respectively. (koji)
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.apache.lucene.queries.function.valuesource.QueryValueSource;
|
|||
import org.apache.lucene.queryparser.classic.ParseException;
|
||||
import org.apache.lucene.queryparser.classic.QueryParser;
|
||||
import org.apache.lucene.search.*;
|
||||
import org.apache.solr.search.SolrQueryParser.MagicFieldName;
|
||||
import org.apache.solr.common.params.DisMaxParams;
|
||||
import org.apache.solr.common.params.SolrParams;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
|
@ -792,8 +793,9 @@ class ExtendedDismaxQParser extends QParser {
|
|||
String fname = s.substring(pos, p);
|
||||
boolean isInSchema = getReq().getSchema().getFieldTypeNoEx(fname) != null;
|
||||
boolean isAlias = solrParams.get("f."+fname+".qf") != null;
|
||||
boolean isMagic = (null != MagicFieldName.get(fname));
|
||||
|
||||
return (isInSchema || isAlias) ? fname : null;
|
||||
return (isInSchema || isAlias || isMagic) ? fname : null;
|
||||
}
|
||||
|
||||
public static List<String> split(String s, boolean ignoreQuote) {
|
||||
|
@ -1082,7 +1084,9 @@ class ExtendedDismaxQParser extends QParser {
|
|||
// literal when we try the escape+re-parse.
|
||||
if (exceptions) {
|
||||
FieldType ft = schema.getFieldTypeNoEx(field);
|
||||
if (ft == null) throw unknownField;
|
||||
if (ft == null && null == MagicFieldName.get(field)) {
|
||||
throw unknownField;
|
||||
}
|
||||
}
|
||||
|
||||
return getQuery();
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.apache.solr.search;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
@ -59,6 +60,33 @@ public class SolrQueryParser extends QueryParser {
|
|||
protected final QParser parser;
|
||||
protected final String defaultField;
|
||||
|
||||
/**
|
||||
* Identifies the list of all known "magic fields" that trigger
|
||||
* special parsing behavior
|
||||
*/
|
||||
public static enum MagicFieldName {
|
||||
VAL("_val_", "func"), QUERY("_query_", null);
|
||||
|
||||
public final String field;
|
||||
public final String subParser;
|
||||
MagicFieldName(final String field, final String subParser) {
|
||||
this.field = field;
|
||||
this.subParser = subParser;
|
||||
}
|
||||
public String toString() {
|
||||
return field;
|
||||
}
|
||||
private final static Map<String,MagicFieldName> lookup
|
||||
= new HashMap<String,MagicFieldName>();
|
||||
static {
|
||||
for(MagicFieldName s : EnumSet.allOf(MagicFieldName.class))
|
||||
lookup.put(s.toString(), s);
|
||||
}
|
||||
public static MagicFieldName get(final String field) {
|
||||
return lookup.get(field);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation detail - caching ReversedWildcardFilterFactory based on type
|
||||
private Map<FieldType, ReversedWildcardFilterFactory> leadingWildcards;
|
||||
|
||||
|
@ -124,12 +152,11 @@ public class SolrQueryParser extends QueryParser {
|
|||
checkNullField(field);
|
||||
// intercept magic field name of "_" to use as a hook for our
|
||||
// own functions.
|
||||
if (field.charAt(0) == '_') {
|
||||
if ("_val_".equals(field)) {
|
||||
QParser nested = parser.subQuery(queryText, "func");
|
||||
if (field.charAt(0) == '_' && parser != null) {
|
||||
MagicFieldName magic = MagicFieldName.get(field);
|
||||
if (null != magic) {
|
||||
QParser nested = parser.subQuery(queryText, magic.subParser);
|
||||
return nested.getQuery();
|
||||
} else if ("_query_".equals(field) && parser != null) {
|
||||
return parser.subQuery(queryText, null).getQuery();
|
||||
}
|
||||
}
|
||||
SchemaField sf = schema.getFieldOrNull(field);
|
||||
|
|
|
@ -54,7 +54,7 @@ public class TestExtendedDismaxParser extends AbstractSolrTestCase {
|
|||
assertU(adoc("id", "48", "text_sw", "this has gigabyte potential", "foo_i","100"));
|
||||
assertU(adoc("id", "49", "text_sw", "start the big apple end", "foo_i","-100"));
|
||||
assertU(adoc("id", "50", "text_sw", "start new big city end"));
|
||||
|
||||
assertU(adoc("id", "51", "store", "12.34,-56.78"));
|
||||
assertU(commit());
|
||||
}
|
||||
@Override
|
||||
|
@ -66,8 +66,8 @@ public class TestExtendedDismaxParser extends AbstractSolrTestCase {
|
|||
|
||||
// test the edismax query parser based on the dismax parser
|
||||
public void testFocusQueryParser() {
|
||||
String allq = "id:[42 TO 50]";
|
||||
String allr = "*[count(//doc)=9]";
|
||||
String allq = "id:[42 TO 51]";
|
||||
String allr = "*[count(//doc)=10]";
|
||||
String oner = "*[count(//doc)=1]";
|
||||
String twor = "*[count(//doc)=2]";
|
||||
String nor = "*[count(//doc)=0]";
|
||||
|
@ -228,6 +228,43 @@ public class TestExtendedDismaxParser extends AbstractSolrTestCase {
|
|||
assertQ(req("defType","edismax", "mm","0", "q","movies_t:Terminator 100", "qf","movies_t foo_i"),
|
||||
twor);
|
||||
|
||||
// special psuedo-fields like _query_ and _val_
|
||||
|
||||
// special fields (and real field id) should be included by default
|
||||
assertQ(req("defType", "edismax",
|
||||
"mm", "100%",
|
||||
"fq", "id:51",
|
||||
"q", "_query_:\"{!geofilt d=20 sfield=store pt=12.34,-56.78}\""),
|
||||
oner);
|
||||
// should also work when explicitly allowed
|
||||
assertQ(req("defType", "edismax",
|
||||
"mm", "100%",
|
||||
"fq", "id:51",
|
||||
"uf", "id _query_",
|
||||
"q", "_query_:\"{!geofilt d=20 sfield=store pt=12.34,-56.78}\""),
|
||||
oner);
|
||||
assertQ(req("defType", "edismax",
|
||||
"mm", "100%",
|
||||
"fq", "id:51",
|
||||
"uf", "id",
|
||||
"uf", "_query_",
|
||||
"q", "_query_:\"{!geofilt d=20 sfield=store pt=12.34,-56.78}\""),
|
||||
oner);
|
||||
|
||||
// should fail when prohibited
|
||||
assertQ(req("defType", "edismax",
|
||||
"mm", "100%",
|
||||
"fq", "id:51",
|
||||
"uf", "* -_query_", // explicitly excluded
|
||||
"q", "_query_:\"{!geofilt d=20 sfield=store pt=12.34,-56.78}\""),
|
||||
nor);
|
||||
assertQ(req("defType", "edismax",
|
||||
"mm", "100%",
|
||||
"fq", "id:51",
|
||||
"uf", "id", // excluded by ommision
|
||||
"q", "_query_:\"{!geofilt d=20 sfield=store pt=12.34,-56.78}\""),
|
||||
nor);
|
||||
|
||||
|
||||
/** stopword removal in conjunction with multi-word synonyms at query time
|
||||
* break this test.
|
||||
|
|
Loading…
Reference in New Issue