mirror of https://github.com/apache/lucene.git
SOLR-1574: simplify specification of builtin functions, add many from java Math
git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@882596 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
451034b2e9
commit
1ac71a2aaf
|
@ -42,6 +42,8 @@ New Features
|
|||
fielded queries, improved proximity boosting, and improved stopword
|
||||
handling. (yonik)
|
||||
|
||||
* SOLR-1574: Add many new functions from java Math (e.g. sin, cos) (yonik)
|
||||
|
||||
Optimizations
|
||||
----------------------
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.solr.search;
|
|||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.queryParser.ParseException;
|
||||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.Searcher;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.schema.DateField;
|
||||
|
@ -47,13 +48,11 @@ import java.util.Map;
|
|||
* Intented usage is to create pluggable, named functions for use in function queries.
|
||||
*/
|
||||
public abstract class ValueSourceParser implements NamedListInitializedPlugin {
|
||||
|
||||
/**
|
||||
* Initialize the plugin.
|
||||
*/
|
||||
public void init(NamedList args) {}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the user input into a ValueSource.
|
||||
*
|
||||
|
@ -72,6 +71,17 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin {
|
|||
return standardValueSourceParsers.put(name, p);
|
||||
}
|
||||
|
||||
/** Adds a new parser for the name and returns any existing one that was overriden.
|
||||
* This is not thread safe.
|
||||
*/
|
||||
public static ValueSourceParser addParser(NamedParser p) {
|
||||
return standardValueSourceParsers.put(p.name(), p);
|
||||
}
|
||||
|
||||
private static void alias(String source, String dest) {
|
||||
standardValueSourceParsers.put(dest, standardValueSourceParsers.get(source));
|
||||
}
|
||||
|
||||
static {
|
||||
addParser("ord", new ValueSourceParser() {
|
||||
public ValueSource parse(FunctionQParser fp) throws ParseException {
|
||||
|
@ -130,13 +140,6 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin {
|
|||
return new TopValueSource(new ScaleFloatFunction(source, min, max));
|
||||
}
|
||||
});
|
||||
addParser("pow", new ValueSourceParser() {
|
||||
public ValueSource parse(FunctionQParser fp) throws ParseException {
|
||||
ValueSource a = fp.parseValueSource();
|
||||
ValueSource b = fp.parseValueSource();
|
||||
return new PowFloatFunction(a, b);
|
||||
}
|
||||
});
|
||||
addParser("div", new ValueSourceParser() {
|
||||
public ValueSource parse(FunctionQParser fp) throws ParseException {
|
||||
ValueSource a = fp.parseValueSource();
|
||||
|
@ -154,34 +157,7 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin {
|
|||
return new RangeMapFloatFunction(source, min, max, target, def);
|
||||
}
|
||||
});
|
||||
addParser("sqrt", new ValueSourceParser() {
|
||||
public ValueSource parse(FunctionQParser fp) throws ParseException {
|
||||
ValueSource source = fp.parseValueSource();
|
||||
return new SimpleFloatFunction(source) {
|
||||
protected String name() {
|
||||
return "sqrt";
|
||||
}
|
||||
|
||||
protected float func(int doc, DocValues vals) {
|
||||
return (float) Math.sqrt(vals.floatVal(doc));
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
addParser("log", new ValueSourceParser() {
|
||||
public ValueSource parse(FunctionQParser fp) throws ParseException {
|
||||
ValueSource source = fp.parseValueSource();
|
||||
return new SimpleFloatFunction(source) {
|
||||
protected String name() {
|
||||
return "log";
|
||||
}
|
||||
|
||||
protected float func(int doc, DocValues vals) {
|
||||
return (float) Math.log10(vals.floatVal(doc));
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
addParser("abs", new ValueSourceParser() {
|
||||
public ValueSource parse(FunctionQParser fp) throws ParseException {
|
||||
ValueSource source = fp.parseValueSource();
|
||||
|
@ -191,7 +167,7 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin {
|
|||
}
|
||||
|
||||
protected float func(int doc, DocValues vals) {
|
||||
return (float) Math.abs(vals.floatVal(doc));
|
||||
return Math.abs(vals.floatVal(doc));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -202,12 +178,16 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin {
|
|||
return new SumFloatFunction(sources.toArray(new ValueSource[sources.size()]));
|
||||
}
|
||||
});
|
||||
alias("sum","add");
|
||||
|
||||
addParser("product", new ValueSourceParser() {
|
||||
public ValueSource parse(FunctionQParser fp) throws ParseException {
|
||||
List<ValueSource> sources = fp.parseValueSourceList();
|
||||
return new ProductFloatFunction(sources.toArray(new ValueSource[sources.size()]));
|
||||
}
|
||||
});
|
||||
alias("product","mul");
|
||||
|
||||
addParser("sub", new ValueSourceParser() {
|
||||
public ValueSource parse(FunctionQParser fp) throws ParseException {
|
||||
ValueSource a = fp.parseValueSource();
|
||||
|
@ -276,16 +256,114 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
addParser("rad", new ValueSourceParser() {
|
||||
public ValueSource parse(FunctionQParser fp) throws ParseException {
|
||||
return new RadianFunction(fp.parseValueSource());
|
||||
addParser(new DoubleParser("rad") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.toRadians(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
|
||||
addParser("deg", new ValueSourceParser() {
|
||||
public ValueSource parse(FunctionQParser fp) throws ParseException {
|
||||
return new DegreeFunction(fp.parseValueSource());
|
||||
addParser(new DoubleParser("deg") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.toDegrees(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("sqrt") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.sqrt(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("cbrt") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.cbrt(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("log") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.log10(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("ln") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.log(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("exp") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.exp(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("sin") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.sin(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("cos") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.cos(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("tan") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.tan(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("asin") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.asin(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("acos") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.acos(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("atan") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.atan(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("sinh") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.sinh(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("cosh") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.cosh(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("tanh") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.tanh(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("ceil") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.ceil(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("floor") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.floor(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new DoubleParser("rint") {
|
||||
public double func(int doc, DocValues vals) {
|
||||
return Math.rint(vals.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new Double2Parser("pow") {
|
||||
public double func(int doc, DocValues a, DocValues b) {
|
||||
return Math.pow(a.doubleVal(doc), b.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new Double2Parser("hypot") {
|
||||
public double func(int doc, DocValues a, DocValues b) {
|
||||
return Math.hypot(a.doubleVal(doc), b.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
addParser(new Double2Parser("atan2") {
|
||||
public double func(int doc, DocValues a, DocValues b) {
|
||||
return Math.atan2(a.doubleVal(doc), b.doubleVal(doc));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -319,9 +397,21 @@ public abstract class ValueSourceParser implements NamedListInitializedPlugin {
|
|||
}
|
||||
});
|
||||
addParser("ms", new DateValueSourceParser());
|
||||
|
||||
|
||||
addParser("pi", new ValueSourceParser() {
|
||||
public ValueSource parse(FunctionQParser fp) throws ParseException {
|
||||
return new DoubleConstValueSource(Math.PI);
|
||||
}
|
||||
});
|
||||
addParser("e", new ValueSourceParser() {
|
||||
public ValueSource parse(FunctionQParser fp) throws ParseException {
|
||||
return new DoubleConstValueSource(Math.E);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void splitSources(int dim, List<ValueSource> sources, List<ValueSource> dest1, List<ValueSource> dest2) {
|
||||
private static void splitSources(int dim, List<ValueSource> sources, List<ValueSource> dest1, List<ValueSource> dest2) {
|
||||
//Get dim value sources for the first vector
|
||||
for (int i = 0; i < dim; i++) {
|
||||
dest1.add(sources.get(i));
|
||||
|
@ -483,3 +573,193 @@ class LongConstValueSource extends ValueSource {
|
|||
return this.constant == other.constant;
|
||||
}
|
||||
}
|
||||
|
||||
// Private for now - we need to revisit how to handle typing in function queries
|
||||
class DoubleConstValueSource extends ValueSource {
|
||||
final double constant;
|
||||
|
||||
public DoubleConstValueSource(double constant) {
|
||||
this.constant = constant;
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return "const(" + constant + ")";
|
||||
}
|
||||
|
||||
public DocValues getValues(Map context, IndexReader reader) throws IOException {
|
||||
return new DocValues() {
|
||||
public float floatVal(int doc) {
|
||||
return (float)constant;
|
||||
}
|
||||
|
||||
public int intVal(int doc) {
|
||||
return (int) constant;
|
||||
}
|
||||
|
||||
public long longVal(int doc) {
|
||||
return (long)constant;
|
||||
}
|
||||
|
||||
public double doubleVal(int doc) {
|
||||
return constant;
|
||||
}
|
||||
|
||||
public String strVal(int doc) {
|
||||
return Double.toString(constant);
|
||||
}
|
||||
|
||||
public String toString(int doc) {
|
||||
return description();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
long bits = Double.doubleToRawLongBits(constant);
|
||||
return (int)(bits ^ (bits >>> 32));
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (DoubleConstValueSource.class != o.getClass()) return false;
|
||||
DoubleConstValueSource other = (DoubleConstValueSource) o;
|
||||
return this.constant == other.constant;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract class NamedParser extends ValueSourceParser {
|
||||
private final String name;
|
||||
public NamedParser(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract class DoubleParser extends NamedParser {
|
||||
public DoubleParser(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public abstract double func(int doc, DocValues vals);
|
||||
|
||||
public ValueSource parse(FunctionQParser fp) throws ParseException {
|
||||
return new Function(fp.parseValueSource());
|
||||
}
|
||||
|
||||
class Function extends SingleFunction {
|
||||
public Function(ValueSource source) {
|
||||
super(source);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return DoubleParser.this.name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DocValues getValues(Map context, IndexReader reader) throws IOException {
|
||||
final DocValues vals = source.getValues(context, reader);
|
||||
return new DocValues() {
|
||||
public float floatVal(int doc) {
|
||||
return (float)doubleVal(doc);
|
||||
}
|
||||
public int intVal(int doc) {
|
||||
return (int)doubleVal(doc);
|
||||
}
|
||||
public long longVal(int doc) {
|
||||
return (long)doubleVal(doc);
|
||||
}
|
||||
public double doubleVal(int doc) {
|
||||
return func(doc, vals);
|
||||
}
|
||||
public String strVal(int doc) {
|
||||
return Double.toString(doubleVal(doc));
|
||||
}
|
||||
public String toString(int doc) {
|
||||
return name() + '(' + vals.toString(doc) + ')';
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
abstract class Double2Parser extends NamedParser {
|
||||
public Double2Parser(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public abstract double func(int doc, DocValues a, DocValues b);
|
||||
|
||||
public ValueSource parse(FunctionQParser fp) throws ParseException {
|
||||
return new Function(fp.parseValueSource(), fp.parseValueSource());
|
||||
}
|
||||
|
||||
class Function extends ValueSource {
|
||||
private final ValueSource a;
|
||||
private final ValueSource b;
|
||||
|
||||
/**
|
||||
* @param a the base.
|
||||
* @param b the exponent.
|
||||
*/
|
||||
public Function(ValueSource a, ValueSource b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return name() + "(" + a.description() + "," + b.description() + ")";
|
||||
}
|
||||
|
||||
public DocValues getValues(Map context, IndexReader reader) throws IOException {
|
||||
final DocValues aVals = a.getValues(context, reader);
|
||||
final DocValues bVals = b.getValues(context, reader);
|
||||
return new DocValues() {
|
||||
public float floatVal(int doc) {
|
||||
return (float)doubleVal(doc);
|
||||
}
|
||||
public int intVal(int doc) {
|
||||
return (int)doubleVal(doc);
|
||||
}
|
||||
public long longVal(int doc) {
|
||||
return (long)doubleVal(doc);
|
||||
}
|
||||
public double doubleVal(int doc) {
|
||||
return func(doc, aVals, bVals);
|
||||
}
|
||||
public String strVal(int doc) {
|
||||
return Double.toString(doubleVal(doc));
|
||||
}
|
||||
public String toString(int doc) {
|
||||
return name() + '(' + aVals.toString(doc) + ',' + bVals.toString(doc) + ')';
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWeight(Map context, Searcher searcher) throws IOException {
|
||||
a.createWeight(context,searcher);
|
||||
b.createWeight(context,searcher);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int h = a.hashCode();
|
||||
h ^= (h << 13) | (h >>> 20);
|
||||
h += b.hashCode();
|
||||
h ^= (h << 23) | (h >>> 10);
|
||||
h += name().hashCode();
|
||||
return h;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this.getClass() != o.getClass()) return false;
|
||||
Function other = (Function)o;
|
||||
return this.a.equals(other.a)
|
||||
&& this.b.equals(other.b);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
package org.apache.solr.search.function;
|
||||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
|
||||
import java.util.Map;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
**/
|
||||
public class DegreeFunction extends ValueSource{
|
||||
protected ValueSource valSource;
|
||||
|
||||
public DegreeFunction(ValueSource valSource) {
|
||||
this.valSource = valSource;
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return "deg(" + valSource.description() + ')';
|
||||
}
|
||||
|
||||
public DocValues getValues(Map context, IndexReader reader) throws IOException {
|
||||
final DocValues dv = valSource.getValues(context, reader);
|
||||
return new DocValues() {
|
||||
public float floatVal(int doc) {
|
||||
return (float) doubleVal(doc);
|
||||
}
|
||||
|
||||
public int intVal(int doc) {
|
||||
return (int) doubleVal(doc);
|
||||
}
|
||||
|
||||
public long longVal(int doc) {
|
||||
return (long) doubleVal(doc);
|
||||
}
|
||||
|
||||
public double doubleVal(int doc) {
|
||||
return Math.toDegrees(dv.doubleVal(doc));
|
||||
}
|
||||
|
||||
public String strVal(int doc) {
|
||||
return Double.toString(doubleVal(doc));
|
||||
}
|
||||
|
||||
public String toString(int doc) {
|
||||
return description() + '=' + floatVal(doc);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o.getClass() != DegreeFunction.class) return false;
|
||||
DegreeFunction other = (DegreeFunction) o;
|
||||
return description().equals(other.description()) && valSource.equals(other.valSource);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return description().hashCode() + valSource.hashCode();
|
||||
};
|
||||
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
package org.apache.solr.search.function;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* Take a ValueSourc and produce convert the number to radians and
|
||||
* return that value
|
||||
*/
|
||||
public class RadianFunction extends ValueSource {
|
||||
protected ValueSource valSource;
|
||||
|
||||
public RadianFunction(ValueSource valSource) {
|
||||
this.valSource = valSource;
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return "rad(" + valSource.description() + ')';
|
||||
}
|
||||
|
||||
public DocValues getValues(Map context, IndexReader reader) throws IOException {
|
||||
final DocValues dv = valSource.getValues(context, reader);
|
||||
return new DocValues() {
|
||||
public float floatVal(int doc) {
|
||||
return (float) doubleVal(doc);
|
||||
}
|
||||
|
||||
public int intVal(int doc) {
|
||||
return (int) doubleVal(doc);
|
||||
}
|
||||
|
||||
public long longVal(int doc) {
|
||||
return (long) doubleVal(doc);
|
||||
}
|
||||
|
||||
public double doubleVal(int doc) {
|
||||
return Math.toRadians(dv.doubleVal(doc));
|
||||
}
|
||||
|
||||
public String strVal(int doc) {
|
||||
return Double.toString(doubleVal(doc));
|
||||
}
|
||||
|
||||
public String toString(int doc) {
|
||||
return description() + '=' + floatVal(doc);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o.getClass() != RadianFunction.class) return false;
|
||||
RadianFunction other = (RadianFunction) o;
|
||||
return description().equals(other.description()) && valSource.equals(other.valSource);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return description().hashCode() + valSource.hashCode();
|
||||
};
|
||||
|
||||
}
|
|
@ -278,7 +278,7 @@ public class TestFunctionQuery extends AbstractSolrTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void testGeneral() {
|
||||
public void testGeneral() throws Exception {
|
||||
assertU(adoc("id","1", "a_tdt","2009-08-31T12:10:10.123Z", "b_tdt","2009-08-31T12:10:10.124Z"));
|
||||
assertU(adoc("id","2"));
|
||||
assertU(commit()); // create more than one segment
|
||||
|
@ -326,9 +326,12 @@ public class TestFunctionQuery extends AbstractSolrTestCase {
|
|||
q ="{!func}sub(div(sum(0.0,product(1,query($qq))),1),0)";
|
||||
assertQ(req("fl","*,score","q", q, "qq","text:batman", "fq",fq), "//float[@name='score']<'1.0'");
|
||||
assertQ(req("fl","*,score","q", q, "qq","text:superman", "fq",fq), "//float[@name='score']>'1.0'");
|
||||
|
||||
doTestDegreeRads();
|
||||
doTestFuncs();
|
||||
}
|
||||
|
||||
public void testDegreeRads() throws Exception {
|
||||
public void doTestDegreeRads() throws Exception {
|
||||
assertU(adoc("id", "1", "x_td", "0", "y_td", "0"));
|
||||
assertU(adoc("id", "2", "x_td", "90", "y_td", String.valueOf(Math.PI / 2)));
|
||||
assertU(adoc("id", "3", "x_td", "45", "y_td", String.valueOf(Math.PI / 4)));
|
||||
|
@ -343,4 +346,47 @@ public class TestFunctionQuery extends AbstractSolrTestCase {
|
|||
assertQ(req("fl", "*,score", "q", "{!func}deg(y_td)", "fq", "id:2"), "//float[@name='score']='90.0'");
|
||||
assertQ(req("fl", "*,score", "q", "{!func}deg(y_td)", "fq", "id:3"), "//float[@name='score']='45.0'");
|
||||
}
|
||||
|
||||
public void dofunc(String func, double val) throws Exception {
|
||||
// String sval = Double.toString(val);
|
||||
String sval = Float.toString((float)val);
|
||||
|
||||
assertQ(req("fl", "*,score", "defType","func", "fq","id:1", "q",func),
|
||||
"//float[@name='score']='" + sval + "'");
|
||||
}
|
||||
|
||||
public void doTestFuncs() throws Exception {
|
||||
assertU(adoc("id", "1", "foo_d", "9"));
|
||||
assertU(commit());
|
||||
|
||||
dofunc("1.0", 1.0);
|
||||
dofunc("e()", Math.E);
|
||||
dofunc("pi()", Math.PI);
|
||||
dofunc("add(2,3)", 2+3);
|
||||
dofunc("mul(2,3)", 2*3);
|
||||
dofunc("rad(45)", Math.toRadians(45));
|
||||
dofunc("deg(.5)", Math.toDegrees(.5));
|
||||
dofunc("sqrt(9)", Math.sqrt(9));
|
||||
dofunc("cbrt(8)", Math.cbrt(8));
|
||||
dofunc("log(100)", Math.log10(100));
|
||||
dofunc("ln(3)", Math.log(3));
|
||||
dofunc("exp(1)", Math.exp(1));
|
||||
dofunc("sin(.5)", Math.sin(.5));
|
||||
dofunc("cos(.5)", Math.cos(.5));
|
||||
dofunc("tan(.5)", Math.tan(.5));
|
||||
dofunc("asin(.5)", Math.asin(.5));
|
||||
dofunc("acos(.5)", Math.acos(.5));
|
||||
dofunc("atan(.5)", Math.atan(.5));
|
||||
dofunc("sinh(.5)", Math.sinh(.5));
|
||||
dofunc("cosh(.5)", Math.cosh(.5));
|
||||
dofunc("tanh(.5)", Math.tanh(.5));
|
||||
dofunc("ceil(2.3)", Math.ceil(2.3));
|
||||
dofunc("floor(2.3)", Math.floor(2.3));
|
||||
dofunc("rint(2.3)", Math.rint(2.3));
|
||||
dofunc("pow(2,0.5)", Math.pow(2,0.5));
|
||||
dofunc("hypot(3,4)", Math.hypot(3,4));
|
||||
dofunc("atan2(.25,.5)", Math.atan2(.25,.5));
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue