You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by da...@apache.org on 2018/11/12 11:55:14 UTC
[05/50] [abbrv] lucene-solr:jira/http2: SOLR-12795: Introduce 'rows'
and 'offset' parameter in FacetStream
SOLR-12795: Introduce 'rows' and 'offset' parameter in FacetStream
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/3d942131
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/3d942131
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/3d942131
Branch: refs/heads/jira/http2
Commit: 3d942131104a38a470b21020bfeb4a12c2dcd99b
Parents: 0ddbc4b
Author: Joel Bernstein <jb...@apache.org>
Authored: Tue Nov 6 11:22:51 2018 -0500
Committer: Joel Bernstein <jb...@apache.org>
Committed: Tue Nov 6 11:23:40 2018 -0500
----------------------------------------------------------------------
.../client/solrj/io/stream/FacetStream.java | 351 ++++++++++++++++---
.../solrj/io/stream/StreamExpressionTest.java | 141 ++++++++
.../stream/StreamExpressionToExpessionTest.java | 203 ++++++++++-
3 files changed, 631 insertions(+), 64 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3d942131/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FacetStream.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FacetStream.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FacetStream.java
index 4564ba0..6923a3b 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FacetStream.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/stream/FacetStream.java
@@ -64,13 +64,21 @@ public class FacetStream extends TupleStream implements Expressible {
private Bucket[] buckets;
private Metric[] metrics;
+ private int rows;
+ private int offset;
+ private int overfetch;
private int bucketSizeLimit;
+ private boolean refine;
+ private String method;
private FieldComparator[] bucketSorts;
private List<Tuple> tuples = new ArrayList<Tuple>();
private int index;
private String zkHost;
private ModifiableSolrParams params;
private String collection;
+ private boolean resortNeeded;
+ private boolean serializeBucketSizeLimit;
+
protected transient SolrClientCache cache;
protected transient CloudSolrClient cloudSolrClient;
@@ -81,7 +89,11 @@ public class FacetStream extends TupleStream implements Expressible {
Metric[] metrics,
FieldComparator[] bucketSorts,
int bucketSizeLimit) throws IOException {
- init(collection, params, buckets, bucketSorts, metrics, bucketSizeLimit, zkHost);
+
+ if(bucketSizeLimit == -1) {
+ bucketSizeLimit = Integer.MAX_VALUE;
+ }
+ init(collection, params, buckets, bucketSorts, metrics, bucketSizeLimit,0, bucketSizeLimit, false, null, true, 0, zkHost);
}
public FacetStream(StreamExpression expression, StreamFactory factory) throws IOException{
@@ -91,9 +103,14 @@ public class FacetStream extends TupleStream implements Expressible {
StreamExpressionNamedParameter bucketExpression = factory.getNamedOperand(expression, "buckets");
StreamExpressionNamedParameter bucketSortExpression = factory.getNamedOperand(expression, "bucketSorts");
List<StreamExpression> metricExpressions = factory.getExpressionOperandsRepresentingTypes(expression, Expressible.class, Metric.class);
- StreamExpressionNamedParameter limitExpression = factory.getNamedOperand(expression, "bucketSizeLimit");
+ StreamExpressionNamedParameter bucketLimitExpression = factory.getNamedOperand(expression, "bucketSizeLimit");
StreamExpressionNamedParameter zkHostExpression = factory.getNamedOperand(expression, "zkHost");
-
+ StreamExpressionNamedParameter rowsExpression = factory.getNamedOperand(expression, "rows");
+ StreamExpressionNamedParameter offsetExpression = factory.getNamedOperand(expression, "offset");
+ StreamExpressionNamedParameter overfetchExpression = factory.getNamedOperand(expression, "overfetch");
+ StreamExpressionNamedParameter refineExpression = factory.getNamedOperand(expression, "refine");
+ StreamExpressionNamedParameter methodExpression = factory.getNamedOperand(expression, "method");
+
// Validate there are no unknown parameters
if(expression.getParameters().size() != 1 + namedParams.size() + metricExpressions.size()){
throw new IOException(String.format(Locale.ROOT,"invalid expression %s - unknown operands found",expression));
@@ -112,7 +129,15 @@ public class FacetStream extends TupleStream implements Expressible {
// pull out known named params
ModifiableSolrParams params = new ModifiableSolrParams();
for(StreamExpressionNamedParameter namedParam : namedParams){
- if(!namedParam.getName().equals("zkHost") && !namedParam.getName().equals("buckets") && !namedParam.getName().equals("bucketSorts") && !namedParam.getName().equals("limit")){
+ if(!namedParam.getName().equals("zkHost") &&
+ !namedParam.getName().equals("buckets") &&
+ !namedParam.getName().equals("bucketSorts") &&
+ !namedParam.getName().equals("bucketSizeLimit") &&
+ !namedParam.getName().equals("method") &&
+ !namedParam.getName().equals("offset") &&
+ !namedParam.getName().equals("rows") &&
+ !namedParam.getName().equals("refine") &&
+ !namedParam.getName().equals("overfetch")){
params.add(namedParam.getName(), namedParam.getParameter().toString().trim());
}
}
@@ -130,45 +155,121 @@ public class FacetStream extends TupleStream implements Expressible {
}
}
}
+
if(null == buckets){
throw new IOException(String.format(Locale.ROOT,"invalid expression %s - at least one bucket expected. eg. 'buckets=\"name\"'",expression,collectionName));
}
-
- // bucketSorts, required
- FieldComparator[] bucketSorts = null;
- if(null != bucketSortExpression){
- if(bucketSortExpression.getParameter() instanceof StreamExpressionValue){
- bucketSorts = parseBucketSorts(((StreamExpressionValue)bucketSortExpression.getParameter()).getValue());
- }
+
+ String bucketSortString = null;
+
+ if(bucketSortExpression == null) {
+ bucketSortString = "count(*) desc";
+ } else {
+ bucketSortString = ((StreamExpressionValue)bucketSortExpression.getParameter()).getValue();
}
- if(null == bucketSorts || 0 == bucketSorts.length){
+
+ FieldComparator[] bucketSorts = parseBucketSorts(bucketSortString, buckets);
+
+ if(null == bucketSorts || 0 == bucketSorts.length) {
throw new IOException(String.format(Locale.ROOT,"invalid expression %s - at least one bucket sort expected. eg. 'bucketSorts=\"name asc\"'",expression,collectionName));
}
-
+
// Construct the metrics
Metric[] metrics = new Metric[metricExpressions.size()];
- for(int idx = 0; idx < metricExpressions.size(); ++idx){
+ for(int idx = 0; idx < metricExpressions.size(); ++idx) {
metrics[idx] = factory.constructMetric(metricExpressions.get(idx));
}
- if(0 == metrics.length){
+
+ if(0 == metrics.length) {
throw new IOException(String.format(Locale.ROOT,"invalid expression %s - at least one metric expected.",expression,collectionName));
}
-
- if(null == limitExpression || null == limitExpression.getParameter() || !(limitExpression.getParameter() instanceof StreamExpressionValue)){
- throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - expecting a single 'limit' parameter of type positive integer but didn't find one",expression));
- }
- String limitStr = ((StreamExpressionValue)limitExpression.getParameter()).getValue();
- int limitInt = 0;
- try{
- limitInt = Integer.parseInt(limitStr);
- if(limitInt <= 0 && limitInt != -1){
- throw new IOException(String.format(Locale.ROOT,"invalid expression %s - limit '%s' must be greater than 0 or -1.",expression, limitStr));
+
+ boolean refine = false;
+
+ if(refineExpression != null) {
+ String refineStr = ((StreamExpressionValue) refineExpression.getParameter()).getValue();
+ if (refineStr != null) {
+ refine = Boolean.parseBoolean(refineStr);
}
}
- catch(NumberFormatException e){
- throw new IOException(String.format(Locale.ROOT,"invalid expression %s - limit '%s' is not a valid integer.",expression, limitStr));
+
+ if(bucketLimitExpression != null && (rowsExpression != null ||
+ offsetExpression != null ||
+ overfetchExpression != null)) {
+ throw new IOException("bucketSizeLimit is incompatible with rows, offset and overfetch.");
}
-
+
+ String methodStr = null;
+ if(methodExpression != null) {
+ methodStr = ((StreamExpressionValue) methodExpression.getParameter()).getValue();
+ }
+
+ int overfetchInt = 150;
+ if(overfetchExpression != null) {
+ String overfetchStr = ((StreamExpressionValue) overfetchExpression.getParameter()).getValue();
+ overfetchInt = Integer.parseInt(overfetchStr);
+ }
+
+ int offsetInt = 0;
+ if(offsetExpression != null) {
+ String offsetStr = ((StreamExpressionValue) offsetExpression.getParameter()).getValue();
+ offsetInt = Integer.parseInt(offsetStr);
+ }
+
+ int rowsInt = Integer.MIN_VALUE;
+ int bucketLimit = Integer.MIN_VALUE;
+ boolean bucketLimitSet = false;
+
+ if(null != rowsExpression) {
+ String rowsStr = ((StreamExpressionValue)rowsExpression.getParameter()).getValue();
+ try {
+ rowsInt = Integer.parseInt(rowsStr);
+ if (rowsInt <= 0 && rowsInt != -1) {
+ throw new IOException(String.format(Locale.ROOT, "invalid expression %s - limit '%s' must be greater than 0 or -1.", expression, rowsStr));
+ }
+ //Rows is set so configure the bucketLimitSize
+ if(rowsInt == -1) {
+ bucketLimit = rowsInt = Integer.MAX_VALUE;
+ } else if(overfetchInt == -1) {
+ bucketLimit = Integer.MAX_VALUE;
+ }else{
+ bucketLimit = offsetInt+overfetchInt+rowsInt;
+ }
+ } catch (NumberFormatException e) {
+ throw new IOException(String.format(Locale.ROOT, "invalid expression %s - limit '%s' is not a valid integer.", expression, rowsStr));
+ }
+ }
+
+ if(bucketLimitExpression != null) {
+ String bucketLimitStr = ((StreamExpressionValue) bucketLimitExpression.getParameter()).getValue();
+ try {
+ bucketLimit = Integer.parseInt(bucketLimitStr);
+ bucketLimitSet = true;
+
+ if (bucketLimit <= 0 && bucketLimit != -1) {
+ throw new IOException(String.format(Locale.ROOT, "invalid expression %s - bucketSizeLimit '%s' must be greater than 0 or -1.", expression, bucketLimitStr));
+ }
+
+ // Bucket limit is set. So set rows.
+ if(bucketLimit == -1) {
+ rowsInt = bucketLimit = Integer.MAX_VALUE;
+ } else {
+ rowsInt = bucketLimit;
+ }
+ } catch (NumberFormatException e) {
+ throw new IOException(String.format(Locale.ROOT, "invalid expression %s - bucketSizeLimit '%s' is not a valid integer.", expression, bucketLimitStr));
+ }
+ }
+
+ if(rowsExpression == null && bucketLimitExpression == null) {
+ rowsInt = 10;
+ if(overfetchInt == -1) {
+ bucketLimit = Integer.MAX_VALUE;
+ }else{
+ bucketLimit = offsetInt+overfetchInt+rowsInt;
+ }
+ }
+
// zkHost, optional - if not provided then will look into factory list to get
String zkHost = null;
if(null == zkHostExpression){
@@ -176,16 +277,44 @@ public class FacetStream extends TupleStream implements Expressible {
if(zkHost == null) {
zkHost = factory.getDefaultZkHost();
}
- }
- else if(zkHostExpression.getParameter() instanceof StreamExpressionValue){
+ } else if(zkHostExpression.getParameter() instanceof StreamExpressionValue) {
zkHost = ((StreamExpressionValue)zkHostExpression.getParameter()).getValue();
}
+
if(null == zkHost){
throw new IOException(String.format(Locale.ROOT,"invalid expression %s - zkHost not found for collection '%s'",expression,collectionName));
}
// We've got all the required items
- init(collectionName, params, buckets, bucketSorts, metrics, limitInt, zkHost);
+ init(collectionName,
+ params,
+ buckets,
+ bucketSorts,
+ metrics,
+ rowsInt,
+ offsetInt,
+ bucketLimit,
+ refine,
+ methodStr,
+ bucketLimitSet,
+ overfetchInt,
+ zkHost);
+ }
+
+ public int getBucketSizeLimit() {
+ return this.bucketSizeLimit;
+ }
+
+ public int getRows() {
+ return this.rows;
+ }
+
+ public int getOffset() {
+ return this.offset;
+ }
+
+ public int getOverfetch() {
+ return this.overfetch;
}
public Bucket[] getBuckets() {
@@ -196,7 +325,7 @@ public class FacetStream extends TupleStream implements Expressible {
return this.collection;
}
- private FieldComparator[] parseBucketSorts(String bucketSortString) throws IOException {
+ private FieldComparator[] parseBucketSorts(String bucketSortString, Bucket[] buckets) throws IOException {
String[] sorts = bucketSortString.split(",");
FieldComparator[] comps = new FieldComparator[sorts.length];
@@ -217,17 +346,20 @@ public class FacetStream extends TupleStream implements Expressible {
return comps;
}
- private void init(String collection, SolrParams params, Bucket[] buckets, FieldComparator[] bucketSorts, Metric[] metrics, int bucketSizeLimit, String zkHost) throws IOException {
+ private void init(String collection, SolrParams params, Bucket[] buckets, FieldComparator[] bucketSorts, Metric[] metrics, int rows, int offset, int bucketSizeLimit, boolean refine, String method, boolean serializeBucketSizeLimit, int overfetch, String zkHost) throws IOException {
this.zkHost = zkHost;
this.params = new ModifiableSolrParams(params);
this.buckets = buckets;
this.metrics = metrics;
+ this.rows = rows;
+ this.offset = offset;
+ this.refine = refine;
this.bucketSizeLimit = bucketSizeLimit;
- if (this.bucketSizeLimit == -1) {
- this.bucketSizeLimit = Integer.MAX_VALUE;
- }
this.collection = collection;
this.bucketSorts = bucketSorts;
+ this.method = method;
+ this.serializeBucketSizeLimit = serializeBucketSizeLimit;
+ this.overfetch = overfetch;
// In a facet world it only makes sense to have the same field name in all of the sorters
// Because FieldComparator allows for left and right field names we will need to validate
@@ -280,8 +412,31 @@ public class FacetStream extends TupleStream implements Expressible {
expression.addParameter(metric.toExpression(factory));
}
- // limit
- expression.addParameter(new StreamExpressionNamedParameter("bucketSizeLimit", Integer.toString(bucketSizeLimit)));
+ if(serializeBucketSizeLimit) {
+ if(bucketSizeLimit == Integer.MAX_VALUE) {
+ expression.addParameter(new StreamExpressionNamedParameter("bucketSizeLimit", Integer.toString(-1)));
+ } else {
+ expression.addParameter(new StreamExpressionNamedParameter("bucketSizeLimit", Integer.toString(bucketSizeLimit)));
+ }
+ } else {
+ if (rows == Integer.MAX_VALUE) {
+ expression.addParameter(new StreamExpressionNamedParameter("rows", Integer.toString(-1)));
+ } else{
+ expression.addParameter(new StreamExpressionNamedParameter("rows", Integer.toString(rows)));
+ }
+
+ expression.addParameter(new StreamExpressionNamedParameter("offset", Integer.toString(offset)));
+
+ if(overfetch == Integer.MAX_VALUE) {
+ expression.addParameter(new StreamExpressionNamedParameter("overfetch", Integer.toString(-1)));
+ } else {
+ expression.addParameter(new StreamExpressionNamedParameter("overfetch", Integer.toString(overfetch)));
+ }
+ }
+
+ if(method != null) {
+ expression.addParameter(new StreamExpressionNamedParameter("method", this.method));
+ }
// zkHost
expression.addParameter(new StreamExpressionNamedParameter("zkHost", zkHost));
@@ -333,8 +488,10 @@ public class FacetStream extends TupleStream implements Expressible {
}
FieldComparator[] adjustedSorts = adjustSorts(buckets, bucketSorts);
- String json = getJsonFacetString(buckets, metrics, adjustedSorts, bucketSizeLimit);
+ this.resortNeeded = resortNeeded(adjustedSorts);
+ String json = getJsonFacetString(buckets, metrics, adjustedSorts, method, refine, bucketSizeLimit);
+ assert expectedJson(json);
ModifiableSolrParams paramsLoc = new ModifiableSolrParams(params);
paramsLoc.set("json.facet", json);
paramsLoc.set("rows", "0");
@@ -343,13 +500,58 @@ public class FacetStream extends TupleStream implements Expressible {
try {
NamedList response = cloudSolrClient.request(request, collection);
getTuples(response, buckets, metrics);
- Collections.sort(tuples, getStreamSort());
+ if(resortNeeded) {
+ Collections.sort(tuples, getStreamSort());
+ }
+
+ index=this.offset;
} catch (Exception e) {
throw new IOException(e);
}
}
+ private boolean expectedJson(String json) {
+ if(this.method != null) {
+ if(!json.contains("\"method\":\""+this.method+"\"")) {
+ return false;
+ }
+ }
+
+ if(this.refine) {
+ if(!json.contains("\"refine\":true")) {
+ return false;
+ }
+ }
+
+ if(serializeBucketSizeLimit) {
+ if(!json.contains("\"limit\":"+bucketSizeLimit)) {
+ return false;
+ }
+ } else {
+ if(!json.contains("\"limit\":"+(this.rows+this.offset+this.overfetch))) {
+ return false;
+ }
+ }
+
+ for(Bucket bucket : buckets) {
+ if(!json.contains("\""+bucket.toString()+"\":")) {
+ return false;
+ }
+ }
+
+ for(Metric metric: metrics) {
+ String func = metric.getFunctionName();
+ if(!func.equals("count")) {
+ if (!json.contains(metric.getIdentifier())) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
public void close() throws IOException {
if(cache == null) {
if (cloudSolrClient != null) {
@@ -359,21 +561,32 @@ public class FacetStream extends TupleStream implements Expressible {
}
public Tuple read() throws IOException {
- if(index < tuples.size() && index < bucketSizeLimit) {
+ if(index < tuples.size() && index < (offset+rows)) {
Tuple tuple = tuples.get(index);
++index;
return tuple;
} else {
Map fields = new HashMap();
+
+ if(bucketSizeLimit == Integer.MAX_VALUE) {
+ fields.put("totalRows", tuples.size());
+ }
+
fields.put("EOF", true);
+
Tuple tuple = new Tuple(fields);
return tuple;
}
}
- private String getJsonFacetString(Bucket[] _buckets, Metric[] _metrics, FieldComparator[] _sorts, int _limit) {
+ private String getJsonFacetString(Bucket[] _buckets,
+ Metric[] _metrics,
+ FieldComparator[] _sorts,
+ String _method,
+ boolean _refine,
+ int _limit) {
StringBuilder buf = new StringBuilder();
- appendJson(buf, _buckets, _metrics, _sorts, _limit, 0);
+ appendJson(buf, _buckets, _metrics, _sorts, _limit, _method, _refine,0);
return "{"+buf.toString()+"}";
}
@@ -399,11 +612,22 @@ public class FacetStream extends TupleStream implements Expressible {
}
}
+ private boolean resortNeeded(FieldComparator[] fieldComparators) {
+ for(FieldComparator fieldComparator : fieldComparators) {
+ if(fieldComparator.getLeftFieldName().contains("(")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private void appendJson(StringBuilder buf,
Bucket[] _buckets,
Metric[] _metrics,
FieldComparator[] _sorts,
int _limit,
+ String method,
+ boolean refine,
int level) {
buf.append('"');
buf.append(_buckets[level].toString());
@@ -412,42 +636,63 @@ public class FacetStream extends TupleStream implements Expressible {
buf.append("\"type\":\"terms\"");
buf.append(",\"field\":\""+_buckets[level].toString()+"\"");
buf.append(",\"limit\":"+_limit);
- buf.append(",\"sort\":{\""+getFacetSort(_sorts[level].getLeftFieldName(), _metrics)+"\":\""+_sorts[level].getOrder()+"\"}");
+
+ if(refine) {
+ buf.append(",\"refine\":true");
+ }
+
+ if(method != null) {
+ buf.append(",\"method\":\""+method+"\"");
+ }
+
+ String fsort = getFacetSort(_sorts[level].getLeftFieldName(), _metrics);
+
+ buf.append(",\"sort\":{\""+fsort+"\":\""+_sorts[level].getOrder()+"\"}");
buf.append(",\"facet\":{");
int metricCount = 0;
+
+
+ ++level;
for(Metric metric : _metrics) {
- String identifier = metric.getIdentifier();
- if(!identifier.startsWith("count(")) {
- if(metricCount>0) {
- buf.append(",");
+ //Only compute the metric if it's a leaf node or if the branch level sort equals is the metric
+ String facetKey = "facet_"+metricCount;
+ if(level == _buckets.length || fsort.equals(facetKey) ) {
+ String identifier = metric.getIdentifier();
+ if (!identifier.startsWith("count(")) {
+ if (metricCount > 0) {
+ buf.append(",");
+ }
+ buf.append("\""+ facetKey + "\":\"" + identifier + "\"");
+ ++metricCount;
}
- buf.append("\"facet_" + metricCount + "\":\"" +identifier+"\"");
- ++metricCount;
}
}
- ++level;
+
if(level < _buckets.length) {
if(metricCount>0) {
buf.append(",");
}
- appendJson(buf, _buckets, _metrics, _sorts, _limit, level);
+ appendJson(buf, _buckets, _metrics, _sorts, _limit, method, refine, level);
}
buf.append("}}");
}
private String getFacetSort(String id, Metric[] _metrics) {
int index = 0;
+ int metricCount=0;
for(Metric metric : _metrics) {
if(metric.getIdentifier().startsWith("count(")) {
if(id.startsWith("count(")) {
return "count";
}
+ ++index;
} else {
if (id.equals(_metrics[index].getIdentifier())) {
- return "facet_" + index;
+ return "facet_" + metricCount;
}
++index;
+ ++metricCount;
}
}
return "index";
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3d942131/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionTest.java
----------------------------------------------------------------------
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 24264b6..7e2451e 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
@@ -986,6 +986,147 @@ public class StreamExpressionTest extends SolrCloudTestCase {
assertTrue(count.doubleValue() == 2);
+ clause = "facet("
+ + "collection1, "
+ + "q=\"*:*\", "
+ + "fl=\"a_s,a_i,a_f\", "
+ + "sort=\"a_s asc\", "
+ + "buckets=\"a_s\", "
+ + "bucketSorts=\"sum(a_i) desc\", "
+ + "rows=2, "
+ + "sum(a_i), sum(a_f), "
+ + "min(a_i), min(a_f), "
+ + "max(a_i), max(a_f), "
+ + "avg(a_i), avg(a_f), "
+ + "count(*)"
+ + ")";
+
+ stream = factory.constructStream(clause);
+ tuples = getTuples(stream);
+
+
+ //Test rows
+
+ tuple = tuples.get(0);
+ assertEquals(tuples.size(), 2);
+
+ bucket = tuple.getString("a_s");
+ sumi = tuple.getDouble("sum(a_i)");
+ sumf = tuple.getDouble("sum(a_f)");
+ mini = tuple.getDouble("min(a_i)");
+ minf = tuple.getDouble("min(a_f)");
+ maxi = tuple.getDouble("max(a_i)");
+ maxf = tuple.getDouble("max(a_f)");
+ avgi = tuple.getDouble("avg(a_i)");
+ avgf = tuple.getDouble("avg(a_f)");
+ count = tuple.getDouble("count(*)");
+
+ assertTrue(bucket.equals("hello3"));
+ assertTrue(sumi.doubleValue() == 38.0D);
+ assertTrue(sumf.doubleValue() == 26.0D);
+ assertTrue(mini.doubleValue() == 3.0D);
+ assertTrue(minf.doubleValue() == 3.0D);
+ assertTrue(maxi.doubleValue() == 13.0D);
+ assertTrue(maxf.doubleValue() == 9.0D);
+ assertTrue(avgi.doubleValue() == 9.5D);
+ assertTrue(avgf.doubleValue() == 6.5D);
+ assertTrue(count.doubleValue() == 4);
+
+ tuple = tuples.get(1);
+ bucket = tuple.getString("a_s");
+ sumi = tuple.getDouble("sum(a_i)");
+ sumf = tuple.getDouble("sum(a_f)");
+ mini = tuple.getDouble("min(a_i)");
+ minf = tuple.getDouble("min(a_f)");
+ maxi = tuple.getDouble("max(a_i)");
+ maxf = tuple.getDouble("max(a_f)");
+ avgi = tuple.getDouble("avg(a_i)");
+ avgf = tuple.getDouble("avg(a_f)");
+ count = tuple.getDouble("count(*)");
+
+ assertTrue(bucket.equals("hello0"));
+ assertTrue(sumi.doubleValue() == 17.0D);
+ assertTrue(sumf.doubleValue() == 18.0D);
+ assertTrue(mini.doubleValue() == 0.0D);
+ assertTrue(minf.doubleValue() == 1.0D);
+ assertTrue(maxi.doubleValue() == 14.0D);
+ assertTrue(maxf.doubleValue() == 10.0D);
+ assertTrue(avgi.doubleValue() == 4.25D);
+ assertTrue(avgf.doubleValue() == 4.5D);
+ assertTrue(count.doubleValue() == 4);
+
+
+ clause = "facet("
+ + "collection1, "
+ + "q=\"*:*\", "
+ + "fl=\"a_s,a_i,a_f\", "
+ + "sort=\"a_s asc\", "
+ + "buckets=\"a_s\", "
+ + "bucketSorts=\"sum(a_i) desc\", "
+ + "rows=2, offset=1, method=dvhash, refine=true,"
+ + "sum(a_i), sum(a_f), "
+ + "min(a_i), min(a_f), "
+ + "max(a_i), max(a_f), "
+ + "avg(a_i), avg(a_f), "
+ + "count(*)"
+ + ")";
+
+ stream = factory.constructStream(clause);
+ tuples = getTuples(stream);
+
+
+ //Test offset
+
+ tuple = tuples.get(0);
+ assertEquals(tuples.size(), 2);
+
+ tuple = tuples.get(0);
+ bucket = tuple.getString("a_s");
+ sumi = tuple.getDouble("sum(a_i)");
+ sumf = tuple.getDouble("sum(a_f)");
+ mini = tuple.getDouble("min(a_i)");
+ minf = tuple.getDouble("min(a_f)");
+ maxi = tuple.getDouble("max(a_i)");
+ maxf = tuple.getDouble("max(a_f)");
+ avgi = tuple.getDouble("avg(a_i)");
+ avgf = tuple.getDouble("avg(a_f)");
+ count = tuple.getDouble("count(*)");
+
+ assertTrue(bucket.equals("hello0"));
+ assertTrue(sumi.doubleValue() == 17.0D);
+ assertTrue(sumf.doubleValue() == 18.0D);
+ assertTrue(mini.doubleValue() == 0.0D);
+ assertTrue(minf.doubleValue() == 1.0D);
+ assertTrue(maxi.doubleValue() == 14.0D);
+ assertTrue(maxf.doubleValue() == 10.0D);
+ assertTrue(avgi.doubleValue() == 4.25D);
+ assertTrue(avgf.doubleValue() == 4.5D);
+ assertTrue(count.doubleValue() == 4);
+
+ tuple = tuples.get(1);
+ bucket = tuple.getString("a_s");
+ sumi = tuple.getDouble("sum(a_i)");
+ sumf = tuple.getDouble("sum(a_f)");
+ mini = tuple.getDouble("min(a_i)");
+ minf = tuple.getDouble("min(a_f)");
+ maxi = tuple.getDouble("max(a_i)");
+ maxf = tuple.getDouble("max(a_f)");
+ avgi = tuple.getDouble("avg(a_i)");
+ avgf = tuple.getDouble("avg(a_f)");
+ count = tuple.getDouble("count(*)");
+
+ assertTrue(bucket.equals("hello4"));
+ assertTrue(sumi.longValue() == 15);
+ assertTrue(sumf.doubleValue() == 11.0D);
+ assertTrue(mini.doubleValue() == 4.0D);
+ assertTrue(minf.doubleValue() == 4.0D);
+ assertTrue(maxi.doubleValue() == 11.0D);
+ assertTrue(maxf.doubleValue() == 7.0D);
+ assertTrue(avgi.doubleValue() == 7.5D);
+ assertTrue(avgf.doubleValue() == 5.5D);
+ assertTrue(count.doubleValue() == 2);
+
+
//Test index sort
clause = "facet("
+ "collection1, "
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3d942131/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionToExpessionTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionToExpessionTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionToExpessionTest.java
index e43176a..289b925 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionToExpessionTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionToExpessionTest.java
@@ -16,6 +16,8 @@
*/
package org.apache.solr.client.solrj.io.stream;
+import java.io.IOException;
+
import org.apache.lucene.util.LuceneTestCase;
import org.apache.solr.client.solrj.io.ops.GroupOperation;
import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
@@ -247,17 +249,17 @@ public class StreamExpressionToExpessionTest extends LuceneTestCase {
// Basic test
try (FacetStream stream = new FacetStream(StreamExpressionParser.parse("facet("
- + "collection1, "
- + "q=\"*:*\", "
- + "buckets=\"a_s\", "
- + "bucketSorts=\"sum(a_i) asc\", "
- + "bucketSizeLimit=100, "
- + "sum(a_i), sum(a_f), "
- + "min(a_i), min(a_f), "
- + "max(a_i), max(a_f), "
- + "avg(a_i), avg(a_f), "
- + "count(*)"
- + ")"), factory)){
+ + "collection1, "
+ + "q=\"*:*\", "
+ + "buckets=\"a_s\", "
+ + "bucketSorts=\"sum(a_i) asc\", "
+ + "bucketSizeLimit=100, "
+ + "sum(a_i), sum(a_f), "
+ + "min(a_i), min(a_f), "
+ + "max(a_i), max(a_f), "
+ + "avg(a_i), avg(a_f), "
+ + "count(*)"
+ + ")"), factory)){
expressionString = stream.toExpression(factory).toString();
assertTrue(expressionString.contains("facet(collection1"));
assertTrue(expressionString.contains("q=\"*:*\""));
@@ -273,7 +275,186 @@ public class StreamExpressionToExpessionTest extends LuceneTestCase {
assertTrue(expressionString.contains("avg(a_i,false)"));
assertTrue(expressionString.contains("avg(a_f,false)"));
assertTrue(expressionString.contains("count(*)"));
+ assertEquals(stream.getBucketSizeLimit(), 100);
+ assertEquals(stream.getRows(), 100);
+ assertEquals(stream.getOffset(), 0);
}
+
+ try (FacetStream stream = new FacetStream(StreamExpressionParser.parse("facet("
+ + "collection1, "
+ + "q=\"*:*\", "
+ + "buckets=\"a_s\", "
+ + "bucketSorts=\"sum(a_i) asc\", "
+ + "sum(a_i), sum(a_f), "
+ + "min(a_i), min(a_f), "
+ + "max(a_i), max(a_f), "
+ + "avg(a_i), avg(a_f), "
+ + "count(*)"
+ + ")"), factory)){
+ expressionString = stream.toExpression(factory).toString();
+ assertTrue(expressionString.contains("facet(collection1"));
+ assertTrue(expressionString.contains("q=\"*:*\""));
+ assertTrue(expressionString.contains("buckets=a_s"));
+ assertTrue(expressionString.contains("bucketSorts=\"sum(a_i) asc\""));
+ assertTrue(expressionString.contains("rows=10"));
+ assertTrue(expressionString.contains("offset=0"));
+ assertTrue(expressionString.contains("overfetch=150"));
+ assertTrue(expressionString.contains("sum(a_i)"));
+ assertTrue(expressionString.contains("sum(a_f)"));
+ assertTrue(expressionString.contains("min(a_i)"));
+ assertTrue(expressionString.contains("min(a_f)"));
+ assertTrue(expressionString.contains("max(a_i)"));
+ assertTrue(expressionString.contains("max(a_f)"));
+ assertTrue(expressionString.contains("avg(a_i,false)"));
+ assertTrue(expressionString.contains("avg(a_f,false)"));
+ assertTrue(expressionString.contains("count(*)"));
+ assertEquals(stream.getOverfetch(), 150);
+ assertEquals(stream.getBucketSizeLimit(), 160);
+ assertEquals(stream.getRows(), 10);
+ assertEquals(stream.getOffset(), 0);
+ }
+
+ try (FacetStream stream = new FacetStream(StreamExpressionParser.parse("facet("
+ + "collection1, "
+ + "q=\"*:*\", "
+ + "buckets=\"a_s\", "
+ + "bucketSizeLimit=100, "
+ + "sum(a_i), sum(a_f), "
+ + "min(a_i), min(a_f), "
+ + "max(a_i), max(a_f), "
+ + "avg(a_i), avg(a_f), "
+ + "count(*)"
+ + ")"), factory)){
+ expressionString = stream.toExpression(factory).toString();
+ assertTrue(expressionString.contains("facet(collection1"));
+ assertTrue(expressionString.contains("q=\"*:*\""));
+ assertTrue(expressionString.contains("buckets=a_s"));
+ assertTrue(expressionString.contains("bucketSorts=\"count(*) desc\""));
+ assertTrue(expressionString.contains("bucketSizeLimit=100"));
+ assertTrue(expressionString.contains("sum(a_i)"));
+ assertTrue(expressionString.contains("sum(a_f)"));
+ assertTrue(expressionString.contains("min(a_i)"));
+ assertTrue(expressionString.contains("min(a_f)"));
+ assertTrue(expressionString.contains("max(a_i)"));
+ assertTrue(expressionString.contains("max(a_f)"));
+ assertTrue(expressionString.contains("avg(a_i,false)"));
+ assertTrue(expressionString.contains("avg(a_f,false)"));
+ assertTrue(expressionString.contains("count(*)"));
+ }
+
+ try (FacetStream stream = new FacetStream(StreamExpressionParser.parse("facet("
+ + "collection1, "
+ + "q=\"*:*\", "
+ + "buckets=\"a_s\", "
+ + "bucketSorts=\"sum(a_i) asc\", "
+ + "rows=10, method=dvhash, "
+ + "sum(a_i), sum(a_f), "
+ + "min(a_i), min(a_f), "
+ + "max(a_i), max(a_f), "
+ + "avg(a_i), avg(a_f), "
+ + "count(*)"
+ + ")"), factory)){
+ expressionString = stream.toExpression(factory).toString();
+ assertTrue(expressionString.contains("facet(collection1"));
+ assertTrue(expressionString.contains("q=\"*:*\""));
+ assertTrue(expressionString.contains("buckets=a_s"));
+ assertTrue(expressionString.contains("bucketSorts=\"sum(a_i) asc\""));
+ assertTrue(!expressionString.contains("bucketSizeLimit"));
+ assertTrue(expressionString.contains("rows=10"));
+ assertTrue(expressionString.contains("offset=0"));
+ assertTrue(expressionString.contains("overfetch=150"));
+ assertTrue(expressionString.contains("method=dvhash"));
+ assertTrue(expressionString.contains("sum(a_i)"));
+ assertTrue(expressionString.contains("sum(a_f)"));
+ assertTrue(expressionString.contains("min(a_i)"));
+ assertTrue(expressionString.contains("min(a_f)"));
+ assertTrue(expressionString.contains("max(a_i)"));
+ assertTrue(expressionString.contains("max(a_f)"));
+ assertTrue(expressionString.contains("avg(a_i,false)"));
+ assertTrue(expressionString.contains("avg(a_f,false)"));
+ assertTrue(expressionString.contains("count(*)"));
+ assertEquals(stream.getBucketSizeLimit(), 160);
+ assertEquals(stream.getRows(), 10);
+ assertEquals(stream.getOffset(), 0);
+ assertEquals(stream.getOverfetch(), 150);
+
+ }
+
+ try (FacetStream stream = new FacetStream(StreamExpressionParser.parse("facet("
+ + "collection1, "
+ + "q=\"*:*\", "
+ + "buckets=\"a_s\", "
+ + "bucketSorts=\"sum(a_i) asc\", "
+ + "rows=10, offset=100, overfetch=30, method=dvhash, "
+ + "sum(a_i), sum(a_f), "
+ + "min(a_i), min(a_f), "
+ + "max(a_i), max(a_f), "
+ + "avg(a_i), avg(a_f), "
+ + "count(*)"
+ + ")"), factory)){
+ expressionString = stream.toExpression(factory).toString();
+ assertTrue(expressionString.contains("facet(collection1"));
+ assertTrue(expressionString.contains("q=\"*:*\""));
+ assertTrue(expressionString.contains("buckets=a_s"));
+ assertTrue(expressionString.contains("bucketSorts=\"sum(a_i) asc\""));
+ assertTrue(!expressionString.contains("bucketSizeLimit"));
+ assertTrue(expressionString.contains("rows=10"));
+ assertTrue(expressionString.contains("offset=100"));
+ assertTrue(expressionString.contains("overfetch=30"));
+ assertTrue(expressionString.contains("method=dvhash"));
+ assertTrue(expressionString.contains("sum(a_i)"));
+ assertTrue(expressionString.contains("sum(a_f)"));
+ assertTrue(expressionString.contains("min(a_i)"));
+ assertTrue(expressionString.contains("min(a_f)"));
+ assertTrue(expressionString.contains("max(a_i)"));
+ assertTrue(expressionString.contains("max(a_f)"));
+ assertTrue(expressionString.contains("avg(a_i,false)"));
+ assertTrue(expressionString.contains("avg(a_f,false)"));
+ assertTrue(expressionString.contains("count(*)"));
+ assertEquals(stream.getBucketSizeLimit(), 140);
+ assertEquals(stream.getRows(), 10);
+ assertEquals(stream.getOffset(), 100);
+ assertEquals(stream.getOverfetch(), 30);
+
+ }
+
+ try (FacetStream stream = new FacetStream(StreamExpressionParser.parse("facet("
+ + "collection1, "
+ + "q=\"*:*\", "
+ + "buckets=\"a_s\", "
+ + "bucketSorts=\"sum(a_i) asc\", "
+ + "rows=-1, offset=100, overfetch=-1, method=dvhash, "
+ + "sum(a_i), sum(a_f), "
+ + "min(a_i), min(a_f), "
+ + "max(a_i), max(a_f), "
+ + "avg(a_i), avg(a_f), "
+ + "count(*)"
+ + ")"), factory)){
+ expressionString = stream.toExpression(factory).toString();
+ assertTrue(expressionString.contains("facet(collection1"));
+ assertTrue(expressionString.contains("q=\"*:*\""));
+ assertTrue(expressionString.contains("buckets=a_s"));
+ assertTrue(expressionString.contains("bucketSorts=\"sum(a_i) asc\""));
+ assertTrue(!expressionString.contains("bucketSizeLimit"));
+ assertTrue(expressionString.contains("rows=-1"));
+ assertTrue(expressionString.contains("offset=100"));
+ assertTrue(expressionString.contains("overfetch=-1"));
+ assertTrue(expressionString.contains("method=dvhash"));
+ assertTrue(expressionString.contains("sum(a_i)"));
+ assertTrue(expressionString.contains("sum(a_f)"));
+ assertTrue(expressionString.contains("min(a_i)"));
+ assertTrue(expressionString.contains("min(a_f)"));
+ assertTrue(expressionString.contains("max(a_i)"));
+ assertTrue(expressionString.contains("max(a_f)"));
+ assertTrue(expressionString.contains("avg(a_i,false)"));
+ assertTrue(expressionString.contains("avg(a_f,false)"));
+ assertTrue(expressionString.contains("count(*)"));
+ assertEquals(stream.getBucketSizeLimit(), Integer.MAX_VALUE);
+ assertEquals(stream.getRows(), Integer.MAX_VALUE);
+ assertEquals(stream.getOffset(), 100);
+ assertEquals(stream.getOverfetch(), -1);
+ }
+
}
@Test