SOLR-12936: Allow percentiles Stream Evaluator to accept an array of percentiles to calculate

This commit is contained in:
Joel Bernstein 2018-10-29 16:29:04 -04:00
parent e618e831d3
commit ac1925045d
2 changed files with 35 additions and 7 deletions

View File

@ -17,6 +17,7 @@
package org.apache.solr.client.solrj.io.eval;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@ -39,16 +40,26 @@ public class PercentileEvaluator extends RecursiveNumericEvaluator implements Tw
if(null == second){
throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - null found for the second value",toExpression(constructingFactory)));
}
if(!(first instanceof List<?>)){
if(!(first instanceof List<?>)) {
throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - found type %s for the first value, expecting a List",toExpression(constructingFactory), first.getClass().getSimpleName()));
}
if(!(second instanceof Number)){
throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - found type %s for the second value, expecting a Number",toExpression(constructingFactory), first.getClass().getSimpleName()));
if((second instanceof Number)) {
Percentile percentile = new Percentile();
percentile.setData(((List<?>) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray());
return percentile.evaluate(((Number) second).doubleValue());
} else if(second instanceof List){
Percentile percentile = new Percentile();
percentile.setData(((List<?>) first).stream().mapToDouble(value -> ((Number) value).doubleValue()).toArray());
List<Number> values = (List<Number>) second;
List<Number> percentiles = new ArrayList();
for(Number value : values) {
percentiles.add(percentile.evaluate(value.doubleValue()));
}
return percentiles;
} else {
throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - found type %s for the second value, expecting a number or a numeric array",toExpression(constructingFactory), first.getClass().getSimpleName()));
}
Percentile percentile = new Percentile();
percentile.setData(((List<?>)first).stream().mapToDouble(value -> ((Number)value).doubleValue()).toArray());
return percentile.evaluate(((Number)second).doubleValue());
}
}

View File

@ -985,6 +985,23 @@ public class MathExpressionTest extends SolrCloudTestCase {
tuple = tuples.get(0);
p = tuple.getDouble("return-value");
assertEquals(p, 2.4, 0.001);
cexpr = "percentile(array(11,10,3,4,5,6,7,8,9,2,1), array(20, 50))";
paramsLoc = new ModifiableSolrParams();
paramsLoc.set("expr", cexpr);
paramsLoc.set("qt", "/stream");
solrStream = new SolrStream(url, paramsLoc);
context = new StreamContext();
solrStream.setStreamContext(context);
tuples = getTuples(solrStream);
assertTrue(tuples.size() == 1);
tuple = tuples.get(0);
List<Number> percentiles = (List<Number>)tuple.get("return-value");
assertEquals(percentiles.get(0).doubleValue(), 2.4, 0.001);
assertEquals(percentiles.get(1).doubleValue(), 6.0, 0.001);
}
@Test