This is an automated email from the ASF dual-hosted git repository.
jbernste pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new 440d4ba SOLR-14916: Add split parameter to timeseries Streaming
Expression
440d4ba is described below
commit 440d4baab12885c962de75e46e150d2723e20215
Author: Joel Bernstein <[email protected]>
AuthorDate: Wed Apr 7 09:54:39 2021 -0400
SOLR-14916: Add split parameter to timeseries Streaming Expression
---
.../client/solrj/io/stream/TimeSeriesStream.java | 178 +++++++++++---
.../solrj/io/stream/StreamExpressionTest.java | 273 ++++++++++++++++++++-
2 files changed, 412 insertions(+), 39 deletions(-)
diff --git
a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TimeSeriesStream.java
b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TimeSeriesStream.java
index c40c346..0caea17 100644
---
a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TimeSeriesStream.java
+++
b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/TimeSeriesStream.java
@@ -62,6 +62,8 @@ public class TimeSeriesStream extends TupleStream implements
Expressible {
private String gap;
private String field;
private String format;
+ private String split;
+ private String limit;
private DateTimeFormatter formatter;
private Metric[] metrics;
@@ -82,7 +84,7 @@ public class TimeSeriesStream extends TupleStream implements
Expressible {
String end,
String gap,
String format) throws IOException {
- init(collection, params, field, metrics, start, end, gap, format, zkHost);
+ init(collection, params, field, metrics, start, end, gap, format, null,
null, zkHost);
}
public TimeSeriesStream(StreamExpression expression, StreamFactory factory)
throws IOException{
@@ -99,6 +101,8 @@ public class TimeSeriesStream extends TupleStream implements
Expressible {
StreamExpressionNamedParameter fieldExpression =
factory.getNamedOperand(expression, "field");
StreamExpressionNamedParameter gapExpression =
factory.getNamedOperand(expression, "gap");
StreamExpressionNamedParameter formatExpression =
factory.getNamedOperand(expression, "format");
+ StreamExpressionNamedParameter splitExpression =
factory.getNamedOperand(expression, "split");
+ StreamExpressionNamedParameter limitExpression =
factory.getNamedOperand(expression, "limit");
StreamExpressionNamedParameter zkHostExpression =
factory.getNamedOperand(expression, "zkHost");
List<StreamExpression> metricExpressions =
factory.getExpressionOperandsRepresentingTypes(expression, Expressible.class,
Metric.class);
@@ -136,6 +140,21 @@ public class TimeSeriesStream extends TupleStream
implements Expressible {
format =
((StreamExpressionValue)formatExpression.getParameter()).getValue();
}
+ String split = null;
+ if(splitExpression != null) {
+ split =
((StreamExpressionValue)splitExpression.getParameter()).getValue();
+ }
+
+ String limit = "10";
+ if(limitExpression != null) {
+ limit =
((StreamExpressionValue)limitExpression.getParameter()).getValue();
+ try {
+ Integer.parseInt(limit);
+ } catch (Exception e) {
+ throw new IOException(String.format(Locale.ROOT,"invalid limit %s,
integer expected", limit));
+ }
+ }
+
// Collection Name
if(null == collectionName){
throw new IOException(String.format(Locale.ROOT,"invalid expression %s -
collectionName expected as first operand",expression));
@@ -186,13 +205,15 @@ public class TimeSeriesStream extends TupleStream
implements Expressible {
}
// We've got all the required items
- init(collectionName, params, field, metrics, start, end, gap, format,
zkHost);
+ init(collectionName, params, field, metrics, start, end, gap, format,
split, limit, zkHost);
}
public String getCollection() {
return this.collection;
}
+
+
private void init(String collection,
SolrParams params,
String field,
@@ -201,6 +222,8 @@ public class TimeSeriesStream extends TupleStream
implements Expressible {
String end,
String gap,
String format,
+ String split,
+ String limit,
String zkHost) throws IOException {
this.zkHost = zkHost;
this.collection = collection;
@@ -212,6 +235,8 @@ public class TimeSeriesStream extends TupleStream
implements Expressible {
this.metrics = metrics;
this.field = field;
this.params = params;
+ this.split = split;
+ this.limit = limit;
this.end = end;
if(format != null) {
this.format = format;
@@ -355,23 +380,65 @@ public class TimeSeriesStream extends TupleStream
implements Expressible {
buf.append(",\"gap\":\"").append(gap).append('"');
buf.append(",\"facet\":{");
- int metricCount = 0;
- for(Metric metric : _metrics) {
- String identifier = metric.getIdentifier();
- if(!identifier.startsWith("count(")) {
- if(metricCount>0) {
- buf.append(",");
+
+
+ // Add the split here:
+ if(split != null) {
+ buf.append('"');
+ buf.append("split");
+ buf.append('"');
+ buf.append(":{");
+ buf.append("\"type\":\"terms\"");
+ buf.append(",\"field\":\"").append(split.toString()).append('"');
+ buf.append(",\"limit\":").append(limit);
+ buf.append(",\"overrequest\":100");
+ if(_metrics[0].getIdentifier().startsWith("count(")) {
+ buf.append(",\"sort\":\"").append("count").append(" desc\"");
+ } else {
+ buf.append(",\"sort\":\"").append("facet_0").append(" desc\"");
+ }
+ buf.append(",\"facet\":{");
+ //Add the aggregations.
+ int metricCount = 0;
+ for(Metric metric : _metrics) {
+ String identifier = metric.getIdentifier();
+ if(!identifier.startsWith("count(")) {
+ if(metricCount>0) {
+ buf.append(",");
+ }
+ if(identifier.startsWith("per(")) {
+
buf.append("\"facet_").append(metricCount).append("\":\"").append(identifier.replaceFirst("per",
"percentile")).append('"');
+ } else if(identifier.startsWith("std(")) {
+
buf.append("\"facet_").append(metricCount).append("\":\"").append(identifier.replaceFirst("std",
"stddev")).append('"');
+ } else if (identifier.startsWith("countDist(")) {
+
buf.append("\"facet_").append(metricCount).append("\":\"").append(identifier.replaceFirst("countDist",
"unique")).append('"');
+ } else {
+
buf.append("\"facet_").append(metricCount).append("\":\"").append(identifier).append('"');
+ }
+ ++metricCount;
}
- if(identifier.startsWith("per(")) {
-
buf.append("\"facet_").append(metricCount).append("\":\"").append(identifier.replaceFirst("per",
"percentile")).append('"');
- } else if(identifier.startsWith("std(")) {
-
buf.append("\"facet_").append(metricCount).append("\":\"").append(identifier.replaceFirst("std",
"stddev")).append('"');
- } else if (identifier.startsWith("countDist(")) {
-
buf.append("\"facet_").append(metricCount).append("\":\"").append(identifier.replaceFirst("countDist",
"unique")).append('"');
- } else {
-
buf.append("\"facet_").append(metricCount).append("\":\"").append(identifier).append('"');
+ }
+ buf.append("}}");
+ } else {
+ //No split so simply append the aggregations.
+ int metricCount = 0;
+ for(Metric metric : _metrics) {
+ String identifier = metric.getIdentifier();
+ if(!identifier.startsWith("count(")) {
+ if(metricCount>0) {
+ buf.append(",");
+ }
+ if(identifier.startsWith("per(")) {
+
buf.append("\"facet_").append(metricCount).append("\":\"").append(identifier.replaceFirst("per",
"percentile")).append('"');
+ } else if(identifier.startsWith("std(")) {
+
buf.append("\"facet_").append(metricCount).append("\":\"").append(identifier.replaceFirst("std",
"stddev")).append('"');
+ } else if (identifier.startsWith("countDist(")) {
+
buf.append("\"facet_").append(metricCount).append("\":\"").append(identifier.replaceFirst("countDist",
"unique")).append('"');
+ } else {
+
buf.append("\"facet_").append(metricCount).append("\":\"").append(identifier).append('"');
+ }
+ ++metricCount;
}
- ++metricCount;
}
}
buf.append("}}");
@@ -398,42 +465,83 @@ public class TimeSeriesStream extends TupleStream
implements Expressible {
if(nl == null) {
return;
}
-
@SuppressWarnings({"rawtypes"})
List allBuckets = (List)nl.get("buckets");
for(int b=0; b<allBuckets.size(); b++) {
@SuppressWarnings({"rawtypes"})
NamedList bucket = (NamedList)allBuckets.get(b);
Object val = bucket.get("val");
+ Tuple tx = currentTuple.clone();
if(formatter != null) {
LocalDateTime localDateTime =
LocalDateTime.ofInstant(((java.util.Date) val).toInstant(), ZoneOffset.UTC);
val = localDateTime.format(formatter);
}
- Tuple t = currentTuple.clone();
- t.put(field, val);
- int m = 0;
- for(Metric metric : _metrics) {
- String identifier = metric.getIdentifier();
- if(!identifier.startsWith("count(")) {
- if(bucket.get("facet_"+m) != null) {
- Number d = (Number) bucket.get("facet_" + m);
- if (metric.outputLong) {
- t.put(identifier, Math.round(d.doubleValue()));
+ tx.put(field, val);
+
+ if(split != null) {
+ @SuppressWarnings({"rawtypes"})
+ NamedList splitBuckets = (NamedList) bucket.get("split");
+ if(splitBuckets == null) {
+ continue;
+ }
+ @SuppressWarnings({"rawtypes"})
+ List sbuckets = (List)splitBuckets.get("buckets");
+ for (int d = 0; d < sbuckets.size(); d++) {
+ @SuppressWarnings({"rawtypes"})
+ NamedList bucketS = (NamedList) sbuckets.get(d);
+ Object valS = bucketS.get("val");
+ if (valS instanceof Integer) {
+ valS = ((Integer) valS).longValue();
+ }
+ Tuple splitT = tx.clone();
+ splitT.put(split, valS);
+ int m = 0;
+ for(Metric metric : _metrics) {
+ String identifier = metric.getIdentifier();
+ if(!identifier.startsWith("count(")) {
+ if(bucketS.get("facet_"+m) != null) {
+ Number n = (Number) bucketS.get("facet_" + m);
+ if (metric.outputLong) {
+ splitT.put(identifier, Math.round(n.doubleValue()));
+ } else {
+ splitT.put(identifier, n.doubleValue());
+ }
+ } else {
+ splitT.put(identifier, 0);
+ }
+ ++m;
+ } else {
+ long l = ((Number)bucketS.get("count")).longValue();
+ splitT.put("count(*)", l);
+ }
+ }
+ tuples.add(splitT);
+ }
+ } else {
+ int m = 0;
+ for(Metric metric : _metrics) {
+ String identifier = metric.getIdentifier();
+ if(!identifier.startsWith("count(")) {
+ if(bucket.get("facet_"+m) != null) {
+ Number d = (Number) bucket.get("facet_" + m);
+ if (metric.outputLong) {
+ tx.put(identifier, Math.round(d.doubleValue()));
+ } else {
+ tx.put(identifier, d.doubleValue());
+ }
} else {
- t.put(identifier, d.doubleValue());
+ tx.put(identifier, 0);
}
+ ++m;
} else {
- t.put(identifier, 0);
+ long l = ((Number)bucket.get("count")).longValue();
+ tx.put("count(*)", l);
}
- ++m;
- } else {
- long l = ((Number)bucket.get("count")).longValue();
- t.put("count(*)", l);
}
+ tuples.add(tx);
}
- tuples.add(t);
}
}
diff --git
a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionTest.java
b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionTest.java
index fdeb26d..9daa1e7 100644
---
a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionTest.java
+++
b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionTest.java
@@ -2689,25 +2689,47 @@ public class StreamExpressionTest extends
SolrCloudTestCase {
return year+"-"+month+"-"+day+"T00:00:00Z";
}
+ private String getSplit(int seed, int index) {
+ String[] splits = {"one", "two", "three"};
+ int splitIndex =
((Integer.toString(index)+Integer.toString(seed)).hashCode()*index) %
splits.length;
+ return splits[Math.abs(splitIndex)];
+ }
+
+ private void incrementSplit(Map<String, Integer> map, String year, String
split) {
+ String key = year+"_"+split;
+ Integer count = map.get(key);
+ if(count == null) {
+ map.put(key, 1);
+ } else {
+ map.put(key,++count);
+ }
+ }
+
@Test
public void testTimeSeriesStream() throws Exception {
UpdateRequest updateRequest = new UpdateRequest();
+ Map<String, Integer> counts = new HashMap<>();
+
int i=0;
while(i<50) {
- updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2016", "5",
"1"), "price_f", "400.00");
+ updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2016", "5",
"1"), "price_f", "400.00", "split_s", getSplit(7723423, i));
+ incrementSplit(counts,"2016", getSplit(7723423, i));
}
while(i<100) {
- updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2015", "5",
"1"), "price_f", "300.0");
+ updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2015", "5",
"1"), "price_f", "300.0", "split_s", getSplit(123274234, i));
+ incrementSplit(counts,"2015", getSplit(123274234, i));
}
while(i<150) {
- updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2014", "5",
"1"), "price_f", "500.0");
+ updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2014", "5",
"1"), "price_f", "500.0", "split_s", getSplit(1242317, i));
+ incrementSplit(counts,"2014", getSplit(1242317, i));
}
while(i<250) {
- updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2013", "5",
"1"), "price_f", "100.00");
+ updateRequest.add(id, "id_"+(++i),"test_dt", getDateString("2013", "5",
"1"), "price_f", "100.00", "split_s", getSplit(1234233887, i));
+ incrementSplit(counts,"2013", getSplit(1234233887, i));
}
updateRequest.commit(cluster.getSolrClient(), COLLECTIONORALIAS);
@@ -2950,6 +2972,249 @@ public class StreamExpressionTest extends
SolrCloudTestCase {
assertTrue(tuples.get(4).getDouble("avg(price_f)").equals(400D));
assertTrue(tuples.get(4).getDouble("std(price_f)").equals(0D));
assertTrue(tuples.get(4).getDouble("per(price_f,50)").equals(400D));
+
+
+ expr = "timeseries("+COLLECTIONORALIAS+", q=\"*:*\",
start=\"2012-01-01T01:00:00.000Z\", " +
+ "end=\"2016-12-01T01:00:00.000Z\", " +
+ "gap=\"+1YEAR\", " +
+ "field=\"test_dt\", " +
+ "split=\"split_s\", " +
+ "format=\"yyyy\", " +
+ "count(*), sum(price_f), max(price_f), min(price_f), avg(price_f),
std(price_f), per(price_f, 50))";
+ paramsLoc = new ModifiableSolrParams();
+ paramsLoc.set("expr", expr);
+ paramsLoc.set("qt", "/stream");
+
+ solrStream = new SolrStream(url, paramsLoc);
+
+ solrStream.setStreamContext(context);
+ tuples = getTuples(solrStream);
+
+ String year = tuples.get(0).getString("test_dt");
+ String split = tuples.get(0).getString("split_s");
+ long splitCount = counts.get(year+"_"+split);
+ assertEquals(tuples.size(), 12);
+
+ assertTrue(tuples.get(0).get("test_dt").equals("2013"));
+ assertTrue(tuples.get(0).get("split_s").equals("three"));
+ assertTrue(tuples.get(0).getLong("count(*)").equals(splitCount));
+
assertTrue(tuples.get(0).getDouble("sum(price_f)").equals(splitCount*100D));
+ assertTrue(tuples.get(0).getDouble("max(price_f)").equals(100D));
+ assertTrue(tuples.get(0).getDouble("min(price_f)").equals(100D));
+ assertTrue(tuples.get(0).getDouble("avg(price_f)").equals(100D));
+ assertTrue(tuples.get(0).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(0).getDouble("per(price_f,50)").equals(100D));
+
+
+ year = tuples.get(1).getString("test_dt");
+ split = tuples.get(1).getString("split_s");
+ splitCount = counts.get(year+"_"+split);
+
+ assertTrue(tuples.get(1).get("test_dt").equals("2013"));
+ assertTrue(tuples.get(1).get("split_s").equals("two"));
+ assertTrue(tuples.get(1).getLong("count(*)").equals(splitCount));
+
assertTrue(tuples.get(1).getDouble("sum(price_f)").equals(splitCount*100D));
+ assertTrue(tuples.get(1).getDouble("max(price_f)").equals(100D));
+ assertTrue(tuples.get(1).getDouble("min(price_f)").equals(100D));
+ assertTrue(tuples.get(1).getDouble("avg(price_f)").equals(100D));
+ assertTrue(tuples.get(1).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(1).getDouble("per(price_f,50)").equals(100D));
+
+ year = tuples.get(2).getString("test_dt");
+ split = tuples.get(2).getString("split_s");
+ splitCount = counts.get(year+"_"+split);
+ assertTrue(tuples.get(2).get("test_dt").equals("2013"));
+ assertTrue(tuples.get(2).get("split_s").equals("one"));
+ assertTrue(tuples.get(2).getLong("count(*)").equals(splitCount));
+
assertTrue(tuples.get(2).getDouble("sum(price_f)").equals(splitCount*100D));
+ assertTrue(tuples.get(2).getDouble("max(price_f)").equals(100D));
+ assertTrue(tuples.get(2).getDouble("min(price_f)").equals(100D));
+ assertTrue(tuples.get(2).getDouble("avg(price_f)").equals(100D));
+ assertTrue(tuples.get(2).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(2).getDouble("per(price_f,50)").equals(100D));
+
+ year = tuples.get(3).getString("test_dt");
+ split = tuples.get(3).getString("split_s");
+ splitCount = counts.get(year+"_"+split);
+ assertTrue(tuples.get(3).get("test_dt").equals("2014"));
+ assertTrue(tuples.get(3).get("split_s").equals("two"));
+ assertTrue(tuples.get(3).getLong("count(*)").equals(splitCount));
+
assertTrue(tuples.get(3).getDouble("sum(price_f)").equals(splitCount*500D));
+ assertTrue(tuples.get(3).getDouble("max(price_f)").equals(500D));
+ assertTrue(tuples.get(3).getDouble("min(price_f)").equals(500D));
+ assertTrue(tuples.get(3).getDouble("avg(price_f)").equals(500D));
+ assertTrue(tuples.get(3).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(3).getDouble("per(price_f,50)").equals(500D));
+
+
+ year = tuples.get(4).getString("test_dt");
+ split = tuples.get(4).getString("split_s");
+ splitCount = counts.get(year+"_"+split);
+ assertTrue(tuples.get(4).get("test_dt").equals("2014"));
+ assertTrue(tuples.get(4).get("split_s").equals("three") );
+ assertTrue(tuples.get(4).getLong("count(*)").equals(splitCount));
+
assertTrue(tuples.get(4).getDouble("sum(price_f)").equals(splitCount*500D));
+ assertTrue(tuples.get(4).getDouble("max(price_f)").equals(500D));
+ assertTrue(tuples.get(4).getDouble("min(price_f)").equals(500D));
+ assertTrue(tuples.get(4).getDouble("avg(price_f)").equals(500D));
+ assertTrue(tuples.get(4).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(4).getDouble("per(price_f,50)").equals(500D));
+
+ year = tuples.get(5).getString("test_dt");
+ split = tuples.get(5).getString("split_s");
+ splitCount = counts.get(year+"_"+split);
+ assertTrue(tuples.get(5).get("test_dt").equals("2014"));
+ assertTrue(tuples.get(5).get("split_s").equals("one"));
+ assertTrue(tuples.get(5).getLong("count(*)").equals(splitCount));
+
assertTrue(tuples.get(5).getDouble("sum(price_f)").equals(splitCount*500D));
+ assertTrue(tuples.get(5).getDouble("max(price_f)").equals(500D));
+ assertTrue(tuples.get(5).getDouble("min(price_f)").equals(500D));
+ assertTrue(tuples.get(5).getDouble("avg(price_f)").equals(500D));
+ assertTrue(tuples.get(5).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(5).getDouble("per(price_f,50)").equals(500D));
+
+
+ year = tuples.get(6).getString("test_dt");
+ split = tuples.get(6).getString("split_s");
+ splitCount = counts.get(year+"_"+split);
+ assertTrue(tuples.get(6).get("test_dt").equals("2015"));
+ assertTrue(tuples.get(6).get("split_s").equals("three"));
+ assertTrue(tuples.get(6).getLong("count(*)").equals(splitCount));
+
assertTrue(tuples.get(6).getDouble("sum(price_f)").equals(splitCount*300D));
+ assertTrue(tuples.get(6).getDouble("max(price_f)").equals(300D));
+ assertTrue(tuples.get(6).getDouble("min(price_f)").equals(300D));
+ assertTrue(tuples.get(6).getDouble("avg(price_f)").equals(300D));
+ assertTrue(tuples.get(6).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(6).getDouble("per(price_f,50)").equals(300D));
+
+ year = tuples.get(7).getString("test_dt");
+ split = tuples.get(7).getString("split_s");
+ splitCount = counts.get(year+"_"+split);
+ assertTrue(tuples.get(7).get("test_dt").equals("2015"));
+ assertTrue(tuples.get(7).get("split_s").equals("two"));
+ assertTrue(tuples.get(7).getLong("count(*)").equals(splitCount));
+
assertTrue(tuples.get(7).getDouble("sum(price_f)").equals(splitCount*300D));
+ assertTrue(tuples.get(7).getDouble("max(price_f)").equals(300D));
+ assertTrue(tuples.get(7).getDouble("min(price_f)").equals(300D));
+ assertTrue(tuples.get(7).getDouble("avg(price_f)").equals(300D));
+ assertTrue(tuples.get(7).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(7).getDouble("per(price_f,50)").equals(300D));
+
+
+ year = tuples.get(8).getString("test_dt");
+ split = tuples.get(8).getString("split_s");
+ splitCount = counts.get(year+"_"+split);
+ assertTrue(tuples.get(8).get("test_dt").equals("2015"));
+ assertTrue(tuples.get(8).get("split_s").equals("one"));
+ assertTrue(tuples.get(8).getLong("count(*)").equals(splitCount));
+
assertTrue(tuples.get(8).getDouble("sum(price_f)").equals(splitCount*300D));
+ assertTrue(tuples.get(8).getDouble("max(price_f)").equals(300D));
+ assertTrue(tuples.get(8).getDouble("min(price_f)").equals(300D));
+ assertTrue(tuples.get(8).getDouble("avg(price_f)").equals(300D));
+ assertTrue(tuples.get(8).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(8).getDouble("per(price_f,50)").equals(300D));
+
+
+ year = tuples.get(9).getString("test_dt");
+ split = tuples.get(9).getString("split_s");
+ splitCount = counts.get(year+"_"+split);
+ assertTrue(tuples.get(9).get("test_dt").equals("2016"));
+ assertTrue(tuples.get(9).get("split_s").equals("two"));
+ assertTrue(tuples.get(9).getLong("count(*)").equals(splitCount));
+
assertTrue(tuples.get(9).getDouble("sum(price_f)").equals(splitCount*400D));
+ assertTrue(tuples.get(9).getDouble("max(price_f)").equals(400D));
+ assertTrue(tuples.get(9).getDouble("min(price_f)").equals(400D));
+ assertTrue(tuples.get(9).getDouble("avg(price_f)").equals(400D));
+ assertTrue(tuples.get(9).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(9).getDouble("per(price_f,50)").equals(400D));
+
+ year = tuples.get(10).getString("test_dt");
+ split = tuples.get(10).getString("split_s");
+ splitCount = counts.get(year+"_"+split);
+ assertTrue(tuples.get(10).get("test_dt").equals("2016"));
+ assertTrue(tuples.get(10).get("split_s").equals("one"));
+ assertTrue(tuples.get(10).getLong("count(*)").equals(splitCount));
+
assertTrue(tuples.get(10).getDouble("sum(price_f)").equals(splitCount*400D));
+ assertTrue(tuples.get(10).getDouble("max(price_f)").equals(400D));
+ assertTrue(tuples.get(10).getDouble("min(price_f)").equals(400D));
+ assertTrue(tuples.get(10).getDouble("avg(price_f)").equals(400D));
+ assertTrue(tuples.get(10).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(10).getDouble("per(price_f,50)").equals(400D));
+
+ year = tuples.get(11).getString("test_dt");
+ split = tuples.get(11).getString("split_s");
+ splitCount = counts.get(year+"_"+split);
+ assertTrue(tuples.get(11).get("test_dt").equals("2016"));
+ assertTrue(tuples.get(11).get("split_s").equals("three"));
+ assertTrue(tuples.get(11).getLong("count(*)").equals(splitCount));
+
assertTrue(tuples.get(11).getDouble("sum(price_f)").equals(splitCount*400D));
+ assertTrue(tuples.get(11).getDouble("max(price_f)").equals(400D));
+ assertTrue(tuples.get(11).getDouble("min(price_f)").equals(400D));
+ assertTrue(tuples.get(11).getDouble("avg(price_f)").equals(400D));
+ assertTrue(tuples.get(11).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(11).getDouble("per(price_f,50)").equals(400D));
+
+
+ expr = "timeseries("+COLLECTIONORALIAS+", q=\"*:*\",
start=\"2012-01-01T01:00:00.000Z\", " +
+ "end=\"2016-12-01T01:00:00.000Z\", " +
+ "gap=\"+1YEAR\", " +
+ "field=\"test_dt\", " +
+ "split=\"split_s\", " +
+ "limit=\"1\", "+
+ "format=\"yyyy\", " +
+ "count(*), sum(price_f), max(price_f), min(price_f), avg(price_f),
std(price_f), per(price_f, 50))";
+ paramsLoc = new ModifiableSolrParams();
+ paramsLoc.set("expr", expr);
+ paramsLoc.set("qt", "/stream");
+
+ solrStream = new SolrStream(url, paramsLoc);
+
+ solrStream.setStreamContext(context);
+ tuples = getTuples(solrStream);
+ assertEquals(tuples.size(), 4);
+
+ assertTrue(tuples.get(0).get("test_dt").equals("2013"));
+ assertTrue(tuples.get(0).get("split_s").equals("three"));
+ assertTrue(tuples.get(0).getLong("count(*)").equals(37L));
+ assertTrue(tuples.get(0).getDouble("sum(price_f)").equals(3700D));
+ assertTrue(tuples.get(0).getDouble("max(price_f)").equals(100D));
+ assertTrue(tuples.get(0).getDouble("min(price_f)").equals(100D));
+ assertTrue(tuples.get(0).getDouble("avg(price_f)").equals(100D));
+ assertTrue(tuples.get(0).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(0).getDouble("per(price_f,50)").equals(100D));
+
+
+ assertTrue(tuples.get(1).get("test_dt").equals("2014"));
+ assertTrue(tuples.get(1).get("split_s").equals("two"));
+ assertTrue(tuples.get(1).getLong("count(*)").equals(20L));
+ assertTrue(tuples.get(1).getDouble("sum(price_f)").equals(10000D));
+ assertTrue(tuples.get(1).getDouble("max(price_f)").equals(500D));
+ assertTrue(tuples.get(1).getDouble("min(price_f)").equals(500D));
+ assertTrue(tuples.get(1).getDouble("avg(price_f)").equals(500D));
+ assertTrue(tuples.get(1).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(1).getDouble("per(price_f,50)").equals(500D));
+
+
+ assertTrue(tuples.get(2).get("test_dt").equals("2015"));
+ assertTrue(tuples.get(2).get("split_s").equals("three"));
+ assertTrue(tuples.get(2).getLong("count(*)").equals(22L));
+ assertTrue(tuples.get(2).getDouble("sum(price_f)").equals(6600D));
+ assertTrue(tuples.get(2).getDouble("max(price_f)").equals(300D));
+ assertTrue(tuples.get(2).getDouble("min(price_f)").equals(300D));
+ assertTrue(tuples.get(2).getDouble("avg(price_f)").equals(300D));
+ assertTrue(tuples.get(2).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(2).getDouble("per(price_f,50)").equals(300D));
+
+ assertTrue(tuples.get(3).get("test_dt").equals("2016"));
+ assertTrue(tuples.get(3).get("split_s").equals("two"));
+ assertTrue(tuples.get(3).getLong("count(*)").equals(20L));
+ assertTrue(tuples.get(3).getDouble("sum(price_f)").equals(8000D));
+ assertTrue(tuples.get(3).getDouble("max(price_f)").equals(400D));
+ assertTrue(tuples.get(3).getDouble("min(price_f)").equals(400D));
+ assertTrue(tuples.get(3).getDouble("avg(price_f)").equals(400D));
+ assertTrue(tuples.get(3).getDouble("std(price_f)").equals(0D));
+ assertTrue(tuples.get(3).getDouble("per(price_f,50)").equals(400D));
+
}
@Test