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:18:36 UTC
lucene-solr:branch_7x: SOLR-12139: eq() now works on strings and
perhaps anything
Repository: lucene-solr
Updated Branches:
refs/heads/branch_7x 211e0ec84 -> 385449e61
SOLR-12139: eq() now works on strings and perhaps anything
(cherry picked from commit f0aed93)
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/385449e6
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/385449e6
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/385449e6
Branch: refs/heads/branch_7x
Commit: 385449e61731c128700ef9bb532cc182aac01d47
Parents: 211e0ec
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:18:31 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/385449e6/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 83991eb..6c1b857 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -53,6 +53,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/385449e6/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/385449e6/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/385449e6/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 0d1ae70..c2718af 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/385449e6/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*