You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ds...@apache.org on 2018/04/09 16:17:56 UTC

lucene-solr:master: SOLR-12139: eq() now works on strings and perhaps anything

Repository: lucene-solr
Updated Branches:
  refs/heads/master e30264b31 -> f0aed933a


SOLR-12139: eq() now works on strings and perhaps anything


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/f0aed933
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/f0aed933
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/f0aed933

Branch: refs/heads/master
Commit: f0aed933a6674dadf7a563973c6d46e99901c5e6
Parents: e30264b
Author: David Smiley <ds...@apache.org>
Authored: Mon Apr 9 12:17:48 2018 -0400
Committer: David Smiley <ds...@apache.org>
Committed: Mon Apr 9 12:17:48 2018 -0400

----------------------------------------------------------------------
 solr/CHANGES.txt                                |  3 +
 .../apache/solr/search/ValueSourceParser.java   |  3 +-
 .../solr/search/function/EqualFunction.java     | 61 +++++++++++++++
 .../solr/search/function/TestFunctionQuery.java | 78 ++++++++++++++++++++
 solr/solr-ref-guide/src/function-queries.adoc   |  3 +-
 5 files changed, 146 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0aed933/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 9b99055..72ea677 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -78,6 +78,9 @@ New Features
 * SOLR-7887: Upgrade Solr to use Log4J 2.11
   (Tim Potter, Keith Laban, Shawn Heisey, Ralph Goers, Erick Erickson, Varun Thacker)
 
+* SOLR-12139: The "eq" (equals) function query now works with string fields, string literals, and perhaps anything.
+  (Andrey Kudryavtsev, David Smiley)
+
 Bug Fixes
 ----------------------
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0aed933/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java b/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java
index 450d95a..0e26bf8 100644
--- a/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java
+++ b/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java
@@ -67,6 +67,7 @@ import org.apache.solr.search.facet.UniqueAgg;
 import org.apache.solr.search.facet.VarianceAgg;
 import org.apache.solr.search.function.CollapseScoreFunction;
 import org.apache.solr.search.function.ConcatStringFunction;
+import org.apache.solr.search.function.EqualFunction;
 import org.apache.solr.search.function.OrdFieldSource;
 import org.apache.solr.search.function.ReverseOrdFieldSource;
 import org.apache.solr.search.function.SolrComparisonBoolFunction;
@@ -922,7 +923,7 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin {
         ValueSource lhsValSource = fp.parseValueSource();
         ValueSource rhsValSource = fp.parseValueSource();
 
-        return new SolrComparisonBoolFunction(lhsValSource, rhsValSource, "eq", (cmp) -> cmp == 0);
+        return new EqualFunction(lhsValSource, rhsValSource, "eq");
       }
     });
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0aed933/solr/core/src/java/org/apache/solr/search/function/EqualFunction.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/search/function/EqualFunction.java b/solr/core/src/java/org/apache/solr/search/function/EqualFunction.java
new file mode 100644
index 0000000..411511e
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/search/function/EqualFunction.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.search.function;
+
+import java.io.IOException;
+import java.util.Objects;
+
+import org.apache.lucene.queries.function.FunctionValues;
+import org.apache.lucene.queries.function.ValueSource;
+import org.apache.lucene.queries.function.valuesource.ComparisonBoolFunction;
+
+/**
+ * Compares two values for equality.
+ * It should work on not only numbers but strings and custom things.
+ *
+ * @since 7.4
+ */
+public class EqualFunction extends ComparisonBoolFunction {
+
+  public EqualFunction(ValueSource lhs, ValueSource rhs, String name) {
+    super(lhs, rhs, name);
+  }
+
+  @Override
+  public boolean compare(int doc, FunctionValues lhs, FunctionValues rhs) throws IOException {
+    Object objL = lhs.objectVal(doc);
+    Object objR = rhs.objectVal(doc);
+    if (isNumeric(objL) && isNumeric(objR)) {
+      if (isInteger(objL) && isInteger(objR)) {
+        return Long.compare(((Number)objL).longValue(), ((Number)objR).longValue()) == 0;
+      } else {
+        return Double.compare(((Number)objL).doubleValue(), ((Number)objR).doubleValue()) == 0;
+      }
+    } else {
+      return Objects.equals(objL, objR);
+    }
+  }
+
+  private static boolean isInteger(Object obj) {
+    return obj instanceof Integer || obj instanceof Long;
+  }
+
+  private static boolean isNumeric(Object obj) {
+    return obj instanceof Number;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0aed933/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java b/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java
index 32f603a..cc448b3 100644
--- a/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java
+++ b/solr/core/src/test/org/apache/solr/search/function/TestFunctionQuery.java
@@ -988,4 +988,82 @@ public class TestFunctionQuery extends SolrTestCaseJ4 {
                /*id*/2, /*score*/5,
                /*id*/1, /*score*/2);
   }
+
+  @Test
+  public void testEqualFunction() {
+    clearIndex();
+    assertU(adoc("id", "1", "field1_s", "value1", "field2_s", "value1",
+        "field1_s_dv", "value1", "field2_s_dv", "value2", "field_b", "true"));
+    assertU(adoc("id", "2", "field1_s", "value1", "field2_s", "value2",
+        "field1_s_dv", "value1", "field2_s_dv", "value1", "field_b", "false"));
+    assertU(commit());
+
+    singleTest("field1_s", "if(eq(field1_s,field2_s),5,2)",
+        /*id*/1, /*score*/5,
+        /*id*/2, /*score*/2);
+    singleTest("field1_s_dv", "if(eq(field1_s_dv,field2_s_dv),5,2)",
+        /*id*/2, /*score*/5,
+        /*id*/1, /*score*/2);
+    singleTest("field1_s", "if(eq(field1_s,field1_s_dv),5,2)",
+        /*id*/1, /*score*/5,
+        /*id*/2, /*score*/5);
+    singleTest("field2_s", "if(eq(field2_s,field2_s_dv),5,2)",
+        /*id*/1, /*score*/2,
+        /*id*/2, /*score*/2);
+    singleTest("field2_s", "if(eq(field2_s,'value1'),5,2)",
+        /*id*/1, /*score*/5,
+        /*id*/2, /*score*/2);
+    singleTest("field1_s", "if(eq('value1','value1'),5,2)",
+        /*id*/1, /*score*/5,
+        /*id*/2, /*score*/5);
+    singleTest("field_b", "if(eq(if(field_b,'value1','value2'),'value1'),5,2)",
+        /*id*/1, /*score*/5,
+        /*id*/2, /*score*/2);
+  }
+
+  @Test
+  public void testEqualNumericComparisons() {
+    clearIndex();
+    assertU(adoc("id", "1", "field_d", "5.0", "field_i", "5"));
+    assertU(adoc("id", "2",  "field_d", "3.0", "field_i", "3"));
+    assertU(commit());
+    singleTest("field_d", "if(eq(field_d,5),5,2)",
+        /*id*/1, /*score*/5,
+        /*id*/2, /*score*/2);
+    singleTest("field_d", "if(eq(field_d,5.0),5,2)",
+        /*id*/1, /*score*/5,
+        /*id*/2, /*score*/2);
+    singleTest("field_d", "if(eq(5,def(field_d,5)),5,2)",
+        /*id*/1, /*score*/5,
+        /*id*/2, /*score*/2);
+    singleTest("field_i", "if(eq(5.0,def(field_i,5)),5,2)",
+        /*id*/1, /*score*/5,
+        /*id*/2, /*score*/2);
+    singleTest("field_not_existed_i", "if(def(field_not_existed_i,5.0),5,2)",
+        /*id*/1, /*score*/5,
+        /*id*/2, /*score*/5);
+    singleTest("field_not_existed_i", "if(def(field_not_existed_i,5),5,2)",
+        /*id*/1, /*score*/5,
+        /*id*/2, /*score*/5);
+  }
+
+  @Test
+  public void testDifferentTypesComparisons() {
+    clearIndex();
+    assertU(adoc("id", "1", "field_s", "value"));
+    assertU(adoc("id", "2"));
+    assertU(commit());
+    singleTest("field_s", "if(eq(field_s,'value'),5,2)",
+        /*id*/1, /*score*/5,
+        /*id*/2, /*score*/2);
+    singleTest("field_s", "if(eq(def(field_s,5),5),5,2)",
+        /*id*/2, /*score*/5,
+        /*id*/1, /*score*/2);
+    singleTest("field_s", "if(eq(def(field_s,5),5.0),5,2)",
+        /*id*/2, /*score*/5,
+        /*id*/1, /*score*/2);
+    singleTest("field_s", "if(eq(def(field_s,'5'),5),5,2)",
+        /*id*/1, /*score*/2,
+        /*id*/2, /*score*/2);
+  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f0aed933/solr/solr-ref-guide/src/function-queries.adoc
----------------------------------------------------------------------
diff --git a/solr/solr-ref-guide/src/function-queries.adoc b/solr/solr-ref-guide/src/function-queries.adoc
index 32991b3..e9e63de 100644
--- a/solr/solr-ref-guide/src/function-queries.adoc
+++ b/solr/solr-ref-guide/src/function-queries.adoc
@@ -496,7 +496,8 @@ Returns `true` if any member of the field exists.
 === Comparison Functions
 `gt`, `gte`, `lt`, `lte`, `eq`
 
-5 comparison functions: Greater Than, Greater Than or Equal, Less Than, Less Than or Equal, Equal
+5 comparison functions: Greater Than, Greater Than or Equal, Less Than, Less Than or Equal, Equal.
+`eq` works on not just numbers but essentially any value like a string field.
 
 *Syntax Example*