You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ho...@apache.org on 2012/03/21 03:32:48 UTC

svn commit: r1303256 - in /lucene/dev/trunk/solr: ./ core/src/java/org/apache/solr/search/ core/src/test/org/apache/solr/search/

Author: hossman
Date: Wed Mar 21 02:32:48 2012
New Revision: 1303256

URL: http://svn.apache.org/viewvc?rev=1303256&view=rev
Log:
SOLR-2959: edismax now respects the magic fields '_val_' and '_query_'

Modified:
    lucene/dev/trunk/solr/CHANGES.txt
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SolrQueryParser.java
    lucene/dev/trunk/solr/core/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=1303256&r1=1303255&r2=1303256&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Wed Mar 21 02:32:48 2012
@@ -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)

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java?rev=1303256&r1=1303255&r2=1303256&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/ExtendedDismaxQParserPlugin.java Wed Mar 21 02:32:48 2012
@@ -40,6 +40,7 @@ import org.apache.lucene.queries.functio
 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 QPar
     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 QPar
         // 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();

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SolrQueryParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SolrQueryParser.java?rev=1303256&r1=1303255&r2=1303256&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SolrQueryParser.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SolrQueryParser.java Wed Mar 21 02:32:48 2012
@@ -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 Que
   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,13 +152,12 @@ public class SolrQueryParser extends Que
     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);
     if (sf != null) {

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestExtendedDismaxParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestExtendedDismaxParser.java?rev=1303256&r1=1303255&r2=1303256&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestExtendedDismaxParser.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestExtendedDismaxParser.java Wed Mar 21 02:32:48 2012
@@ -54,7 +54,7 @@ public class TestExtendedDismaxParser ex
     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 ex
   
   // 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]";
@@ -227,6 +227,43 @@ public class TestExtendedDismaxParser ex
 
     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