You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by yo...@apache.org on 2011/04/16 18:51:12 UTC
svn commit: r1094014 - in /lucene/dev/trunk/solr: CHANGES.txt
src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java
src/test/org/apache/solr/search/TestExtendedDismaxParser.java
Author: yonik
Date: Sat Apr 16 16:51:11 2011
New Revision: 1094014
URL: http://svn.apache.org/viewvc?rev=1094014&view=rev
Log:
SOLR-2409: edismax: treat invalid fieldnames as a literal
Modified:
lucene/dev/trunk/solr/CHANGES.txt
lucene/dev/trunk/solr/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java
lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestExtendedDismaxParser.java
Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1094014&r1=1094013&r2=1094014&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Sat Apr 16 16:51:11 2011
@@ -266,6 +266,10 @@ Bug Fixes
of the configured maxRetries, due to HttpClient having it's own retry mechanism
by default. The retryCount of HttpClient is now set to 0, and SolrJ does
the retry. (yonik)
+
+* SOLR-2409: edismax parser - treat the text of a fielded query as a literal if the
+ fieldname does not exist. For example Mission: Impossible should not search on
+ the "Mission" field unless it's a valid field in the schema. (Ryan McKinley, yonik)
Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java?rev=1094014&r1=1094013&r2=1094014&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java Sat Apr 16 16:51:11 2011
@@ -238,6 +238,7 @@ class ExtendedDismaxQParser extends QPar
try {
up.setRemoveStopFilter(!stopwords);
+ up.exceptions = true;
parsedUserQuery = up.parse(mainUserQuery);
if (stopwords && isEmpty(parsedUserQuery)) {
@@ -247,6 +248,7 @@ class ExtendedDismaxQParser extends QPar
}
} catch (Exception e) {
// ignore failure and reparse later after escaping reserved chars
+ up.exceptions = false;
}
if (parsedUserQuery != null && doMinMatched) {
@@ -785,12 +787,19 @@ class ExtendedDismaxQParser extends QPar
RANGE
}
+
+ static final RuntimeException unknownField = new RuntimeException("UnknownField");
+ static {
+ unknownField.fillInStackTrace();
+ }
+
/**
* A subclass of SolrQueryParser that supports aliasing fields for
* constructing DisjunctionMaxQueries.
*/
class ExtendedSolrQueryParser extends SolrQueryParser {
+
/** A simple container for storing alias info
*/
protected class Alias {
@@ -803,6 +812,7 @@ class ExtendedDismaxQParser extends QPar
boolean allowWildcard=true;
int minClauseSize = 0; // minimum number of clauses per phrase query...
// used when constructing boosting part of query via sloppy phrases
+ boolean exceptions; // allow exceptions to be thrown (for example on a missing field)
ExtendedAnalyzer analyzer;
@@ -982,6 +992,15 @@ class ExtendedDismaxQParser extends QPar
return q;
}
} else {
+
+ // verify that a fielded query is actually on a field that exists... if not,
+ // then throw an exception to get us out of here, and we'll treat it like a
+ // literal when we try the escape+re-parse.
+ if (exceptions) {
+ FieldType ft = schema.getFieldTypeNoEx(field);
+ if (ft == null) throw unknownField;
+ }
+
return getQuery();
}
}
Modified: lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestExtendedDismaxParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestExtendedDismaxParser.java?rev=1094014&r1=1094013&r2=1094014&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestExtendedDismaxParser.java (original)
+++ lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestExtendedDismaxParser.java Sat Apr 16 16:51:11 2011
@@ -49,8 +49,13 @@ public class TestExtendedDismaxParser ex
"name", "The Zapper"));
assertU(adoc("id", "45", "trait_ss", "Chauvinist",
"title", "25 star General"));
- assertU(adoc("id", "46", "trait_ss", "Obnoxious",
- "subject", "Defeated the pacifists op the Gandhi nebula"));
+ assertU(adoc("id", "46",
+ "trait_ss", "Obnoxious",
+ "subject", "Defeated the pacifists op the Gandhi nebula",
+ "t_special", "literal:colon value",
+ "movies_t", "first is Mission: Impossible, second is Terminator 2: Judgement Day. Terminator:3 ok...",
+ "foo_i", "8"
+ ));
assertU(adoc("id", "47", "trait_ss", "Pig",
"text", "line up and fly directly at the enemy death cannons, clogging them with wreckage!"));
assertU(adoc("id", "48", "text_sw", "this has gigabyte potential", "foo_i","100"));
@@ -64,6 +69,11 @@ public class TestExtendedDismaxParser ex
String twor = "*[count(//doc)=2]";
String nor = "*[count(//doc)=0]";
+ assertQ("expected doc is missing (using un-escaped edismax w/qf)",
+ req("q", "literal:colon",
+ "qf", "t_special",
+ "defType", "edismax"),
+ "//doc[1]/str[@name='id'][.='46']");
assertQ("standard request handler returns all matches",
req(allq),
@@ -164,6 +174,58 @@ public class TestExtendedDismaxParser ex
"q","the big"), oner
);
+ // searching for a literal colon value when clearly not used for a field
+ assertQ("expected doc is missing (using standard)",
+ req("q", "t_special:literal\\:colon"),
+ "//doc[1]/str[@name='id'][.='46']");
+ assertQ("expected doc is missing (using escaped edismax w/field)",
+ req("q", "t_special:literal\\:colon",
+ "defType", "edismax"),
+ "//doc[1]/str[@name='id'][.='46']");
+ assertQ("expected doc is missing (using un-escaped edismax w/field)",
+ req("q", "t_special:literal:colon",
+ "defType", "edismax"),
+ "//doc[1]/str[@name='id'][.='46']");
+ assertQ("expected doc is missing (using escaped edismax w/qf)",
+ req("q", "literal\\:colon",
+ "qf", "t_special",
+ "defType", "edismax"),
+ "//doc[1]/str[@name='id'][.='46']");
+ assertQ("expected doc is missing (using un-escaped edismax w/qf)",
+ req("q", "literal:colon",
+ "qf", "t_special",
+ "defType", "edismax"),
+ "//doc[1]/str[@name='id'][.='46']");
+
+ assertQ(req("defType","edismax", "mm","100%", "q","terminator:3", "qf","movies_t"),
+ oner);
+ assertQ(req("defType","edismax", "mm","100%", "q","Mission:Impossible", "qf","movies_t"),
+ oner);
+ assertQ(req("defType","edismax", "mm","100%", "q","Mission : Impossible", "qf","movies_t"),
+ oner);
+ assertQ(req("defType","edismax", "mm","100%", "q","Mission: Impossible", "qf","movies_t"),
+ oner);
+ assertQ(req("defType","edismax", "mm","100%", "q","Terminator 2: Judgement Day", "qf","movies_t"),
+ oner);
+
+ // make sure the clause wasn't eliminated
+ assertQ(req("defType","edismax", "mm","100%", "q","Terminator 10: Judgement Day", "qf","movies_t"),
+ nor);
+
+ // throw in a numeric field
+ assertQ(req("defType","edismax", "mm","0", "q","Terminator: 100", "qf","movies_t foo_i"),
+ twor);
+
+ assertQ(req("defType","edismax", "mm","100%", "q","Terminator: 100", "qf","movies_t foo_i"),
+ nor);
+
+ assertQ(req("defType","edismax", "mm","100%", "q","Terminator: 8", "qf","movies_t foo_i"),
+ oner);
+
+ assertQ(req("defType","edismax", "mm","0", "q","movies_t:Terminator 100", "qf","movies_t foo_i"),
+ twor);
+
+
/** stopword removal in conjunction with multi-word synonyms at query time
* break this test.
// multi-word synonyms