replace xcontent with datastructures for JSON building
This commit is contained in:
parent
9b38b62d42
commit
a52894f663
11 changed files with 289 additions and 306 deletions
|
@ -1,5 +1,4 @@
|
|||
dependencies {
|
||||
api project(':cql-common')
|
||||
implementation "org.xbib:content-core:${project.property('xbib-content.version')}"
|
||||
implementation "org.xbib:content-json:${project.property('xbib-content.version')}"
|
||||
implementation "org.xbib:datastructures-json-tiny:${project.property('xbib-datastructures.version')}"
|
||||
}
|
||||
|
|
|
@ -3,6 +3,6 @@ module org.xbib.cql.elasticsearch {
|
|||
exports org.xbib.cql.elasticsearch.ast;
|
||||
exports org.xbib.cql.elasticsearch.model;
|
||||
requires transitive org.xbib.cql;
|
||||
requires org.xbib.content.core;
|
||||
requires org.xbib.content.json;
|
||||
requires org.xbib.datastructures.api;
|
||||
requires org.xbib.datastructures.json.tiny;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package org.xbib.cql.elasticsearch;
|
||||
|
||||
import org.xbib.content.XContentBuilder;
|
||||
import org.xbib.cql.BooleanGroup;
|
||||
import org.xbib.cql.BooleanOperator;
|
||||
import org.xbib.cql.Comparitor;
|
||||
|
@ -27,6 +26,7 @@ import org.xbib.cql.elasticsearch.ast.Operator;
|
|||
import org.xbib.cql.elasticsearch.ast.Token;
|
||||
import org.xbib.cql.elasticsearch.ast.TokenType;
|
||||
import org.xbib.cql.elasticsearch.model.ElasticsearchQueryModel;
|
||||
import org.xbib.datastructures.json.tiny.JsonBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.ZonedDateTime;
|
||||
|
@ -45,7 +45,7 @@ public class ElasticsearchFilterGenerator implements Visitor {
|
|||
|
||||
private final String globalField;
|
||||
|
||||
private FilterGenerator filterGen;
|
||||
private final FilterGenerator filterGen;
|
||||
|
||||
public ElasticsearchFilterGenerator(String globalField) {
|
||||
this(globalField, new ElasticsearchQueryModel());
|
||||
|
@ -55,11 +55,7 @@ public class ElasticsearchFilterGenerator implements Visitor {
|
|||
this.globalField = globalField;
|
||||
this.model = model;
|
||||
this.stack = new Stack<>();
|
||||
try {
|
||||
this.filterGen = new FilterGenerator();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void addOrFilter(String filterKey, Collection<String> filterValues) {
|
||||
|
@ -76,7 +72,7 @@ public class ElasticsearchFilterGenerator implements Visitor {
|
|||
}
|
||||
}
|
||||
|
||||
public XContentBuilder getResult() throws IOException {
|
||||
public JsonBuilder getResult() {
|
||||
return filterGen.getResult();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package org.xbib.cql.elasticsearch;
|
||||
|
||||
import org.xbib.content.XContentBuilder;
|
||||
import org.xbib.content.core.DefaultXContentBuilder;
|
||||
import org.xbib.cql.BooleanGroup;
|
||||
import org.xbib.cql.BooleanOperator;
|
||||
import org.xbib.cql.CQLParser;
|
||||
|
@ -29,6 +27,7 @@ import org.xbib.cql.elasticsearch.ast.Operator;
|
|||
import org.xbib.cql.elasticsearch.ast.Token;
|
||||
import org.xbib.cql.elasticsearch.ast.TokenType;
|
||||
import org.xbib.cql.elasticsearch.model.ElasticsearchQueryModel;
|
||||
import org.xbib.datastructures.json.tiny.JsonBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.ZonedDateTime;
|
||||
|
@ -67,7 +66,7 @@ public class ElasticsearchQueryGenerator implements Visitor {
|
|||
|
||||
private FacetsGenerator facetGen;
|
||||
|
||||
private XContentBuilder sort;
|
||||
private SortGenerator sortGen;
|
||||
|
||||
private final String globalField;
|
||||
|
||||
|
@ -82,6 +81,7 @@ public class ElasticsearchQueryGenerator implements Visitor {
|
|||
this.queryGen = new QueryGenerator();
|
||||
this.filterGen = new FilterGenerator();
|
||||
this.facetGen = new FacetsGenerator();
|
||||
this.sortGen = new SortGenerator();
|
||||
}
|
||||
|
||||
public ElasticsearchQueryModel getModel() {
|
||||
|
@ -98,11 +98,6 @@ public class ElasticsearchQueryGenerator implements Visitor {
|
|||
return this;
|
||||
}
|
||||
|
||||
public ElasticsearchQueryGenerator setSort(XContentBuilder sort) {
|
||||
this.sort = sort;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ElasticsearchQueryGenerator setBoostParams(String boostField, String modifier, Float factor, String boostMode) {
|
||||
this.boostField = boostField;
|
||||
this.modifier = modifier;
|
||||
|
@ -137,16 +132,16 @@ public class ElasticsearchQueryGenerator implements Visitor {
|
|||
return this;
|
||||
}
|
||||
|
||||
public String getQueryResult() throws IOException {
|
||||
return queryGen.getResult().string();
|
||||
public String getQueryResult() {
|
||||
return queryGen.getResult().build();
|
||||
}
|
||||
|
||||
public String getFacetResult() throws IOException {
|
||||
return facetGen.getResult().string();
|
||||
public String getFacetResult() {
|
||||
return facetGen.getResult().build();
|
||||
}
|
||||
|
||||
public String getSourceResult() throws IOException {
|
||||
return sourceGen.getResult().string();
|
||||
public String getSourceResult() {
|
||||
return sourceGen.getResult().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -162,7 +157,7 @@ public class ElasticsearchQueryGenerator implements Visitor {
|
|||
}
|
||||
if (model.hasFilter()) {
|
||||
queryGen.startFiltered();
|
||||
} else if (filterGenerator.getResult().string().length() > 0) {
|
||||
} else if (filterGenerator.getResult().build().length() > 0) {
|
||||
queryGen.startFiltered();
|
||||
}
|
||||
Node querynode = stack.pop();
|
||||
|
@ -180,11 +175,10 @@ public class ElasticsearchQueryGenerator implements Visitor {
|
|||
filterGen.visit(model.getFilterExpression());
|
||||
filterGen.endFilter();
|
||||
queryGen.end();
|
||||
} else if (filterGenerator.getResult().string().length() > 0) {
|
||||
} else if (filterGenerator.getResult().build().length() > 0) {
|
||||
queryGen.end();
|
||||
DefaultXContentBuilder contentBuilder = (DefaultXContentBuilder) filterGenerator.getResult();
|
||||
byte[] b = contentBuilder.bytes().toBytes();
|
||||
queryGen.getResult().rawField("filter", b, 0, b.length);
|
||||
JsonBuilder contentBuilder = filterGenerator.getResult();
|
||||
queryGen.getResult(). copy(contentBuilder);
|
||||
queryGen.endFiltered();
|
||||
}
|
||||
if (boostField != null) {
|
||||
|
@ -195,15 +189,13 @@ public class ElasticsearchQueryGenerator implements Visitor {
|
|||
facetGen.visit(model.getFacetExpression());
|
||||
}
|
||||
queryGen.end();
|
||||
Expression sortnode = model.getSort();
|
||||
SortGenerator sortGen = new SortGenerator();
|
||||
if (sortnode != null) {
|
||||
if (model.getSort() != null) {
|
||||
sortGen = new SortGenerator();
|
||||
sortGen.start();
|
||||
sortGen.visit(sortnode);
|
||||
sortGen.visit(model.getSort());
|
||||
sortGen.end();
|
||||
sort = sortGen.getResult();
|
||||
}
|
||||
sourceGen.build(queryGen, from, size, sort, facetGen.getResult());
|
||||
sourceGen.build(queryGen, from, size, sortGen.getResult(), facetGen.getResult());
|
||||
} catch (IOException e) {
|
||||
throw new SyntaxException("unable to build a valid query from " + node + " , reason: " + e.getMessage(), e);
|
||||
}
|
||||
|
@ -326,7 +318,7 @@ public class ElasticsearchQueryGenerator implements Visitor {
|
|||
if (sb.length() > 0) {
|
||||
sb.append('.');
|
||||
}
|
||||
sb.append(modifier.toString());
|
||||
sb.append(modifier);
|
||||
modifier = stack.pop();
|
||||
}
|
||||
String modifiable = sb.toString();
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package org.xbib.cql.elasticsearch;
|
||||
|
||||
import org.xbib.content.XContentBuilder;
|
||||
import org.xbib.content.json.JsonXContent;
|
||||
import org.xbib.cql.SyntaxException;
|
||||
import org.xbib.cql.elasticsearch.ast.Expression;
|
||||
import org.xbib.cql.elasticsearch.ast.Modifier;
|
||||
import org.xbib.cql.elasticsearch.ast.Name;
|
||||
import org.xbib.cql.elasticsearch.ast.Operator;
|
||||
import org.xbib.cql.elasticsearch.ast.Token;
|
||||
import org.xbib.datastructures.json.tiny.JsonBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
@ -20,36 +19,36 @@ public class FacetsGenerator implements Visitor {
|
|||
|
||||
private int facetlength = 10;
|
||||
|
||||
private final XContentBuilder builder;
|
||||
private final JsonBuilder builder;
|
||||
|
||||
public FacetsGenerator() throws IOException {
|
||||
this.builder = JsonXContent.contentBuilder();
|
||||
this.builder = new JsonBuilder();
|
||||
}
|
||||
|
||||
public void start() throws IOException {
|
||||
builder.startObject();
|
||||
builder.beginMap();
|
||||
}
|
||||
|
||||
public void end() throws IOException {
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
}
|
||||
|
||||
public void startFacets() throws IOException {
|
||||
builder.startObject("aggregations");
|
||||
builder.beginMap("aggregations");
|
||||
}
|
||||
|
||||
public void endFacets() throws IOException {
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
}
|
||||
|
||||
public XContentBuilder getResult() throws IOException {
|
||||
public JsonBuilder getResult() {
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Token node) {
|
||||
try {
|
||||
builder.value(node.toString().getBytes());
|
||||
builder.buildValue(node.toString());
|
||||
} catch (IOException e) {
|
||||
throw new SyntaxException(e.getMessage(), e);
|
||||
}
|
||||
|
@ -58,7 +57,7 @@ public class FacetsGenerator implements Visitor {
|
|||
@Override
|
||||
public void visit(Name node) {
|
||||
try {
|
||||
builder.value(node.toString().getBytes());
|
||||
builder.buildValue(node.toString());
|
||||
} catch (IOException e) {
|
||||
throw new SyntaxException(e.getMessage(), e);
|
||||
}
|
||||
|
@ -67,7 +66,7 @@ public class FacetsGenerator implements Visitor {
|
|||
@Override
|
||||
public void visit(Modifier node) {
|
||||
try {
|
||||
builder.value(node.toString().getBytes());
|
||||
builder.buildValue(node.toString());
|
||||
} catch (IOException e) {
|
||||
throw new SyntaxException(e.getMessage(), e);
|
||||
}
|
||||
|
@ -76,7 +75,7 @@ public class FacetsGenerator implements Visitor {
|
|||
@Override
|
||||
public void visit(Operator node) {
|
||||
try {
|
||||
builder.value(node.toString().getBytes());
|
||||
builder.buildValue(node.toString());
|
||||
} catch (IOException e) {
|
||||
throw new SyntaxException(e.getMessage(), e);
|
||||
}
|
||||
|
@ -88,8 +87,9 @@ public class FacetsGenerator implements Visitor {
|
|||
Operator op = node.getOperator();
|
||||
switch (op) {
|
||||
case TERMS_FACET: {
|
||||
builder.startObject().field("myfacet", "myvalue")
|
||||
.endObject();
|
||||
builder.beginMap()
|
||||
.field("myfacet", "myvalue")
|
||||
.endMap();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -122,7 +122,7 @@ public class FacetsGenerator implements Visitor {
|
|||
break;
|
||||
}
|
||||
}
|
||||
builder.startObject();
|
||||
builder.beginMap();
|
||||
for (String index : facetMap.keySet()) {
|
||||
if ("*".equals(index)) {
|
||||
continue;
|
||||
|
@ -130,18 +130,19 @@ public class FacetsGenerator implements Visitor {
|
|||
// TODO(jprante) range aggregations etc.
|
||||
String facetType = "terms";
|
||||
Integer size = facetMap.get(index);
|
||||
builder.field(index)
|
||||
.startObject()
|
||||
.field(facetType).startObject()
|
||||
builder.buildKey(index)
|
||||
.beginMap()
|
||||
.buildKey(facetType)
|
||||
.beginMap()
|
||||
.field("field", index)
|
||||
.field("size", size > 0 ? size : 10)
|
||||
.startObject("order")
|
||||
.beginMap("order")
|
||||
.field(order, dir)
|
||||
.endObject()
|
||||
.endObject();
|
||||
builder.endObject();
|
||||
.endMap()
|
||||
.endMap();
|
||||
builder.endMap();
|
||||
}
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package org.xbib.cql.elasticsearch;
|
||||
|
||||
import org.xbib.content.XContentBuilder;
|
||||
import org.xbib.content.json.JsonXContent;
|
||||
import org.xbib.cql.SyntaxException;
|
||||
import org.xbib.cql.elasticsearch.ast.Expression;
|
||||
import org.xbib.cql.elasticsearch.ast.Modifier;
|
||||
|
@ -10,6 +8,7 @@ import org.xbib.cql.elasticsearch.ast.Node;
|
|||
import org.xbib.cql.elasticsearch.ast.Operator;
|
||||
import org.xbib.cql.elasticsearch.ast.Token;
|
||||
import org.xbib.cql.util.QuotedStringTokenizer;
|
||||
import org.xbib.datastructures.json.tiny.JsonBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -18,10 +17,10 @@ import java.io.IOException;
|
|||
*/
|
||||
public class FilterGenerator implements Visitor {
|
||||
|
||||
private XContentBuilder builder;
|
||||
private final JsonBuilder builder;
|
||||
|
||||
public FilterGenerator() throws IOException {
|
||||
this.builder = JsonXContent.contentBuilder();
|
||||
public FilterGenerator() {
|
||||
this.builder = new JsonBuilder();
|
||||
}
|
||||
|
||||
public FilterGenerator(QueryGenerator queryGenerator) throws IOException {
|
||||
|
@ -29,33 +28,33 @@ public class FilterGenerator implements Visitor {
|
|||
}
|
||||
|
||||
public FilterGenerator start() throws IOException {
|
||||
builder.startObject();
|
||||
builder.beginMap();
|
||||
return this;
|
||||
}
|
||||
|
||||
public FilterGenerator end() throws IOException {
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
return this;
|
||||
}
|
||||
|
||||
public FilterGenerator startFilter() throws IOException {
|
||||
builder.startObject("filter");
|
||||
builder.beginMap("filter");
|
||||
return this;
|
||||
}
|
||||
|
||||
public FilterGenerator endFilter() throws IOException {
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
return this;
|
||||
}
|
||||
|
||||
public XContentBuilder getResult() throws IOException {
|
||||
public JsonBuilder getResult() {
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Token node) {
|
||||
try {
|
||||
builder.value(node.getString());
|
||||
builder.buildValue(node.getString());
|
||||
} catch (IOException e) {
|
||||
throw new SyntaxException(e.getMessage(), e);
|
||||
}
|
||||
|
@ -64,7 +63,7 @@ public class FilterGenerator implements Visitor {
|
|||
@Override
|
||||
public void visit(Name node) {
|
||||
try {
|
||||
builder.field(node.toString());
|
||||
builder.buildKey(node.toString());
|
||||
} catch (IOException e) {
|
||||
throw new SyntaxException(e.getMessage(), e);
|
||||
}
|
||||
|
@ -73,7 +72,7 @@ public class FilterGenerator implements Visitor {
|
|||
@Override
|
||||
public void visit(Modifier node) {
|
||||
try {
|
||||
builder.value(node.toString());
|
||||
builder.buildValue(node.toString());
|
||||
} catch (IOException e) {
|
||||
throw new SyntaxException(e.getMessage(), e);
|
||||
}
|
||||
|
@ -82,7 +81,7 @@ public class FilterGenerator implements Visitor {
|
|||
@Override
|
||||
public void visit(Operator node) {
|
||||
try {
|
||||
builder.value(node.toString());
|
||||
builder.buildValue(node.toString());
|
||||
} catch (IOException e) {
|
||||
throw new SyntaxException(e.getMessage(), e);
|
||||
}
|
||||
|
@ -111,17 +110,18 @@ public class FilterGenerator implements Visitor {
|
|||
case EQUALS: {
|
||||
String field = arg1.toString();
|
||||
String value = tok2 != null ? tok2.getString() : "";
|
||||
builder.startObject(tok2 != null && tok2.isBoundary() ? "prefix" : "term");
|
||||
builder.field(field, value).endObject();
|
||||
builder.beginMap(tok2 != null && tok2.isBoundary() ? "prefix" : "term");
|
||||
builder.field(field, value)
|
||||
.endMap();
|
||||
break;
|
||||
}
|
||||
case NOT_EQUALS: {
|
||||
String field = arg1.toString();
|
||||
String value = tok2 != null ? tok2.getString() : "";
|
||||
builder.startObject("not")
|
||||
.startObject(tok2 != null && tok2.isBoundary() ? "prefix" : "term")
|
||||
builder.beginMap("not")
|
||||
.beginMap(tok2 != null && tok2.isBoundary() ? "prefix" : "term")
|
||||
.field(field, value)
|
||||
.endObject().endObject();
|
||||
.endMap().endMap();
|
||||
break;
|
||||
}
|
||||
case ALL: {
|
||||
|
@ -129,18 +129,18 @@ public class FilterGenerator implements Visitor {
|
|||
String value = arg2 != null ? arg2.toString() : "";
|
||||
boolean phrase = arg2 instanceof Token && ((Token) arg2).isQuoted();
|
||||
if (phrase) {
|
||||
builder.startArray("and");
|
||||
builder.beginCollection("and");
|
||||
QuotedStringTokenizer qst = new QuotedStringTokenizer(value);
|
||||
while (qst.hasMoreTokens()) {
|
||||
builder.startObject().startObject("term")
|
||||
builder.beginMap().beginMap("term")
|
||||
.field(field, qst.nextToken())
|
||||
.endObject().endObject();
|
||||
.endMap().endMap();
|
||||
}
|
||||
builder.endArray();
|
||||
builder.endCollection();
|
||||
} else {
|
||||
builder.startObject(tok2 != null && tok2.isBoundary() ? "prefix" : "term")
|
||||
builder.beginMap(tok2 != null && tok2.isBoundary() ? "prefix" : "term")
|
||||
.field(field, value)
|
||||
.endObject();
|
||||
.endMap();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -149,66 +149,66 @@ public class FilterGenerator implements Visitor {
|
|||
String field = arg1.toString();
|
||||
String value = arg2 != null ? arg2.toString() : "";
|
||||
if (phrase) {
|
||||
builder.startArray("or");
|
||||
builder.beginCollection("or");
|
||||
QuotedStringTokenizer qst = new QuotedStringTokenizer(value);
|
||||
while (qst.hasMoreTokens()) {
|
||||
builder.startObject().startObject("term")
|
||||
.field(field, qst.nextToken()).endObject().endObject();
|
||||
builder.beginMap().beginMap("term")
|
||||
.field(field, qst.nextToken()).endMap().endMap();
|
||||
}
|
||||
builder.endArray();
|
||||
builder.endCollection();
|
||||
} else {
|
||||
builder.startObject(tok2 != null && tok2.isBoundary() ? "prefix" : "term")
|
||||
builder.beginMap(tok2 != null && tok2.isBoundary() ? "prefix" : "term")
|
||||
.field(field, value)
|
||||
.endObject();
|
||||
.endMap();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RANGE_GREATER_THAN: {
|
||||
String field = arg1.toString();
|
||||
String value = tok2 != null ? tok2.getString() : "";
|
||||
builder.startObject("range").startObject(field)
|
||||
builder.beginMap("range").beginMap(field)
|
||||
.field("from", value)
|
||||
.field("include_lower", false)
|
||||
.endObject().endObject();
|
||||
.endMap().endMap();
|
||||
break;
|
||||
}
|
||||
case RANGE_GREATER_OR_EQUAL: {
|
||||
String field = arg1.toString();
|
||||
String value = arg2 != null ? arg2.toString() : "";
|
||||
builder.startObject("range").startObject(field)
|
||||
builder.beginMap("range").beginMap(field)
|
||||
.field("from", value)
|
||||
.field("include_lower", true)
|
||||
.endObject().endObject();
|
||||
.endMap().endMap();
|
||||
break;
|
||||
}
|
||||
case RANGE_LESS_THAN: {
|
||||
String field = arg1.toString();
|
||||
String value = arg2 != null ? arg2.toString() : "";
|
||||
builder.startObject("range").startObject(field)
|
||||
builder.beginMap("range").beginMap(field)
|
||||
.field("to", value)
|
||||
.field("include_upper", false)
|
||||
.endObject().endObject();
|
||||
.endMap().endMap();
|
||||
break;
|
||||
}
|
||||
case RANGE_LESS_OR_EQUALS: {
|
||||
String field = arg1.toString();
|
||||
String value = arg2 != null ? arg2.toString() : "";
|
||||
builder.startObject("range").startObject(field)
|
||||
builder.beginMap("range").beginMap(field)
|
||||
.field("to", value)
|
||||
.field("include_upper", true)
|
||||
.endObject().endObject();
|
||||
.endMap().endMap();
|
||||
break;
|
||||
}
|
||||
case RANGE_WITHIN: {
|
||||
String field = arg1.toString();
|
||||
String value = tok2 != null ? tok2.getString() : "";
|
||||
String[] s = value.split(" ");
|
||||
builder.startObject("range").startObject(field).
|
||||
builder.beginMap("range").beginMap(field).
|
||||
field("from", s[0])
|
||||
.field("to", s[1])
|
||||
.field("include_lower", true)
|
||||
.field("include_upper", true)
|
||||
.endObject().endObject();
|
||||
.endMap().endMap();
|
||||
break;
|
||||
}
|
||||
case AND: {
|
||||
|
@ -217,18 +217,18 @@ public class FilterGenerator implements Visitor {
|
|||
arg1.accept(this);
|
||||
}
|
||||
} else {
|
||||
builder.startObject("bool");
|
||||
builder.startArray("must");
|
||||
builder.beginMap("bool");
|
||||
builder.beginCollection("must");
|
||||
Node[] args = node.getArgs();
|
||||
for (int i = 0; i < node.getArgs().length; i++) {
|
||||
if (args[i].isVisible()) {
|
||||
builder.startObject();
|
||||
builder.beginMap();
|
||||
args[i].accept(this);
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
}
|
||||
}
|
||||
builder.endArray();
|
||||
builder.endObject();
|
||||
builder.endCollection();
|
||||
builder.endMap();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -238,51 +238,51 @@ public class FilterGenerator implements Visitor {
|
|||
arg1.accept(this);
|
||||
}
|
||||
} else {
|
||||
builder.startObject("bool");
|
||||
builder.startArray("should");
|
||||
builder.beginMap("bool");
|
||||
builder.beginCollection("should");
|
||||
Node[] args = node.getArgs();
|
||||
for (int i = 0; i < node.getArgs().length; i++) {
|
||||
if (args[i].isVisible()) {
|
||||
builder.startObject();
|
||||
builder.beginMap();
|
||||
args[i].accept(this);
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
}
|
||||
}
|
||||
builder.endArray();
|
||||
builder.endObject();
|
||||
builder.endCollection();
|
||||
builder.endMap();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OR_FILTER: {
|
||||
builder.startObject("bool");
|
||||
builder.startArray("should");
|
||||
builder.beginMap("bool");
|
||||
builder.beginCollection("should");
|
||||
Node[] args = node.getArgs();
|
||||
for (int i = 0; i < args.length; i += 2) {
|
||||
if (args[i].isVisible()) {
|
||||
builder.startObject().startObject("term");
|
||||
builder.beginMap().beginMap("term");
|
||||
args[i].accept(this);
|
||||
args[i + 1].accept(this);
|
||||
builder.endObject().endObject();
|
||||
builder.endMap().endMap();
|
||||
}
|
||||
}
|
||||
builder.endArray();
|
||||
builder.endObject();
|
||||
builder.endCollection();
|
||||
builder.endMap();
|
||||
break;
|
||||
}
|
||||
case AND_FILTER: {
|
||||
builder.startObject("bool");
|
||||
builder.startArray("must");
|
||||
builder.beginMap("bool");
|
||||
builder.beginCollection("must");
|
||||
Node[] args = node.getArgs();
|
||||
for (int i = 0; i < args.length; i += 2) {
|
||||
if (args[i].isVisible()) {
|
||||
builder.startObject().startObject("term");
|
||||
builder.beginMap().beginMap("term");
|
||||
args[i].accept(this);
|
||||
args[i + 1].accept(this);
|
||||
builder.endObject().endObject();
|
||||
builder.endMap().endMap();
|
||||
}
|
||||
}
|
||||
builder.endArray();
|
||||
builder.endObject();
|
||||
builder.endCollection();
|
||||
builder.endMap();
|
||||
break;
|
||||
}
|
||||
case ANDNOT: {
|
||||
|
@ -291,18 +291,18 @@ public class FilterGenerator implements Visitor {
|
|||
arg1.accept(this);
|
||||
}
|
||||
} else {
|
||||
builder.startObject("bool");
|
||||
builder.startArray("must_not");
|
||||
builder.beginMap("bool");
|
||||
builder.beginCollection("must_not");
|
||||
Node[] args = node.getArgs();
|
||||
for (int i = 0; i < node.getArgs().length; i++) {
|
||||
if (args[i].isVisible()) {
|
||||
builder.startObject();
|
||||
builder.beginMap();
|
||||
args[i].accept(this);
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
}
|
||||
}
|
||||
builder.endArray();
|
||||
builder.endObject();
|
||||
builder.endCollection();
|
||||
builder.endMap();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -310,19 +310,19 @@ public class FilterGenerator implements Visitor {
|
|||
String field = arg1.toString();
|
||||
// we assume a default of 10 words is enough for proximity
|
||||
String value = arg2 != null ? arg2.toString() + "~10" : "";
|
||||
builder.startObject("field").field(field, value).endObject();
|
||||
builder.beginMap("field").field(field, value).endMap();
|
||||
break;
|
||||
}
|
||||
case TERM_FILTER: {
|
||||
String field = arg1.toString();
|
||||
String value = arg2 != null ? arg2.toString() : "";
|
||||
builder.startObject("term").field(field, value).endObject();
|
||||
builder.beginMap("term").field(field, value).endMap();
|
||||
break;
|
||||
}
|
||||
case QUERY_FILTER: {
|
||||
builder.startObject("query");
|
||||
builder.beginMap("query");
|
||||
arg1.accept(this);
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package org.xbib.cql.elasticsearch;
|
||||
|
||||
import org.xbib.content.XContentBuilder;
|
||||
import org.xbib.content.json.JsonXContent;
|
||||
import org.xbib.cql.SyntaxException;
|
||||
import org.xbib.cql.elasticsearch.ast.Expression;
|
||||
import org.xbib.cql.elasticsearch.ast.Modifier;
|
||||
|
@ -9,53 +7,54 @@ import org.xbib.cql.elasticsearch.ast.Name;
|
|||
import org.xbib.cql.elasticsearch.ast.Node;
|
||||
import org.xbib.cql.elasticsearch.ast.Operator;
|
||||
import org.xbib.cql.elasticsearch.ast.Token;
|
||||
import org.xbib.datastructures.json.tiny.JsonBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Build Elasticsearch query from abstract syntax tree.
|
||||
*/
|
||||
public class QueryGenerator implements Visitor {
|
||||
|
||||
private final XContentBuilder builder;
|
||||
private final JsonBuilder builder;
|
||||
|
||||
public QueryGenerator() throws IOException {
|
||||
this.builder = JsonXContent.contentBuilder();
|
||||
public QueryGenerator() {
|
||||
this.builder = new JsonBuilder();
|
||||
}
|
||||
|
||||
public void start() throws IOException {
|
||||
builder.startObject();
|
||||
builder.beginMap();
|
||||
}
|
||||
|
||||
public void end() throws IOException {
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
}
|
||||
|
||||
public void startFiltered() throws IOException {
|
||||
builder.startObject("filtered").startObject("query");
|
||||
builder.beginMap("filtered").beginMap("query");
|
||||
}
|
||||
|
||||
public void endFiltered() throws IOException {
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
}
|
||||
|
||||
public void startBoost(String boostField, String modifier, Float factor, String boostMode) throws IOException {
|
||||
builder.startObject("function_score")
|
||||
.startObject("field_value_factor")
|
||||
builder.beginMap("function_score")
|
||||
.beginMap("field_value_factor")
|
||||
.field("field", boostField)
|
||||
.field("modifier", modifier != null ? modifier : "log1p")
|
||||
.field("factor", factor != null ? factor : 1.0f)
|
||||
.endObject()
|
||||
.endMap()
|
||||
.field("boost_mode", boostMode != null ? boostMode : "multiply")
|
||||
.startObject("query");
|
||||
.beginMap("query");
|
||||
}
|
||||
|
||||
public void endBoost() throws IOException {
|
||||
builder.endObject().endObject();
|
||||
builder.endMap().endMap();
|
||||
}
|
||||
|
||||
public XContentBuilder getResult() {
|
||||
public JsonBuilder getResult() {
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
@ -64,19 +63,19 @@ public class QueryGenerator implements Visitor {
|
|||
try {
|
||||
switch (token.getType()) {
|
||||
case BOOL:
|
||||
builder.value(token.getBoolean());
|
||||
builder.buildValue(token.getBoolean());
|
||||
break;
|
||||
case INT:
|
||||
builder.value(token.getInteger());
|
||||
builder.buildValue(token.getInteger());
|
||||
break;
|
||||
case FLOAT:
|
||||
builder.value(token.getFloat());
|
||||
builder.buildValue(token.getFloat());
|
||||
break;
|
||||
case DATETIME:
|
||||
builder.value(token.getDate());
|
||||
builder.buildValue(token.getDate());
|
||||
break;
|
||||
case STRING:
|
||||
builder.value(token.getString());
|
||||
builder.buildValue(token.getString());
|
||||
break;
|
||||
default:
|
||||
throw new IOException("unknown token type: " + token);
|
||||
|
@ -89,7 +88,7 @@ public class QueryGenerator implements Visitor {
|
|||
@Override
|
||||
public void visit(Name node) {
|
||||
try {
|
||||
builder.field(node.toString());
|
||||
builder.buildKey(node.toString());
|
||||
} catch (IOException e) {
|
||||
throw new SyntaxException(e.getMessage(), e);
|
||||
}
|
||||
|
@ -98,7 +97,7 @@ public class QueryGenerator implements Visitor {
|
|||
@Override
|
||||
public void visit(Modifier node) {
|
||||
try {
|
||||
builder.value(node.toString());
|
||||
builder.buildValue(node.toString());
|
||||
} catch (IOException e) {
|
||||
throw new SyntaxException(e.getMessage(), e);
|
||||
}
|
||||
|
@ -107,7 +106,7 @@ public class QueryGenerator implements Visitor {
|
|||
@Override
|
||||
public void visit(Operator node) {
|
||||
try {
|
||||
builder.value(node.toString());
|
||||
builder.buildValue(node.toString());
|
||||
} catch (IOException e) {
|
||||
throw new SyntaxException(e.getMessage(), e);
|
||||
}
|
||||
|
@ -123,7 +122,7 @@ public class QueryGenerator implements Visitor {
|
|||
switch (op.getArity()) {
|
||||
case 0: {
|
||||
if (op == Operator.MATCH_ALL) {
|
||||
builder.startObject("match_all").endObject();
|
||||
builder.beginMap("match_all").endMap();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -148,91 +147,91 @@ public class QueryGenerator implements Visitor {
|
|||
String field = arg1.toString();
|
||||
String value = arg2 != null ? arg2.toString() : ""; // with quote
|
||||
// with phrase boost
|
||||
builder.startObject("bool")
|
||||
.startArray("should")
|
||||
.startObject()
|
||||
.startObject("simple_query_string")
|
||||
builder.beginMap("bool")
|
||||
.beginCollection("should")
|
||||
.beginMap()
|
||||
.beginMap("simple_query_string")
|
||||
.field("query", value)
|
||||
.field("fields", new String[]{field})
|
||||
.field("fields", Collections.singletonList(field))
|
||||
.field("analyze_wildcard", true)
|
||||
.field("default_operator", "and")
|
||||
.endObject()
|
||||
.endObject()
|
||||
.startObject()
|
||||
.startObject("simple_query_string")
|
||||
.endMap()
|
||||
.endMap()
|
||||
.beginMap()
|
||||
.beginMap("simple_query_string")
|
||||
.field("query", "\"" + value + "\"")
|
||||
.field("fields", new String[]{ field + "^2"})
|
||||
.field("fields", Collections.singletonList(field + "^2"))
|
||||
.field("default_operator", "and")
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endArray()
|
||||
.endMap()
|
||||
.endMap()
|
||||
.endCollection()
|
||||
.field("minimum_should_match", "1")
|
||||
.endObject();
|
||||
.endMap();
|
||||
break;
|
||||
}
|
||||
case NOT_EQUALS: {
|
||||
String field = arg1.toString();
|
||||
String value = arg2 != null ? arg2.toString() : ""; // with quote
|
||||
builder.startObject("bool")
|
||||
.startObject("must_not")
|
||||
.startObject("simple_query_string")
|
||||
builder.beginMap("bool")
|
||||
.beginMap("must_not")
|
||||
.beginMap("simple_query_string")
|
||||
.field("query", value)
|
||||
.field("fields", new String[]{field})
|
||||
.field("fields", Collections.singletonList(field))
|
||||
.field("analyze_wildcard", true)
|
||||
.field("default_operator", "and")
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endObject();
|
||||
.endMap()
|
||||
.endMap()
|
||||
.endMap();
|
||||
break;
|
||||
}
|
||||
case ALL: {
|
||||
String field = arg1.toString();
|
||||
String value = tok2 != null ? tok2.getString() : ""; // always unquoted
|
||||
// with phrase boost
|
||||
builder.startObject("bool")
|
||||
.startArray("should")
|
||||
.startObject()
|
||||
.startObject("simple_query_string")
|
||||
builder.beginMap("bool")
|
||||
.beginCollection("should")
|
||||
.beginMap()
|
||||
.beginMap("simple_query_string")
|
||||
.field("query", value)
|
||||
.field("fields", new String[]{field})
|
||||
.field("fields", Collections.singletonList(field))
|
||||
.field("analyze_wildcard", true)
|
||||
.field("default_operator", "and")
|
||||
.endObject()
|
||||
.endObject()
|
||||
.startObject()
|
||||
.startObject("simple_query_string")
|
||||
.endMap()
|
||||
.endMap()
|
||||
.beginMap()
|
||||
.beginMap("simple_query_string")
|
||||
.field("query", "\"" + value + "\"")
|
||||
.field("fields", new String[]{ field + "^2"})
|
||||
.field("fields", Collections.singletonList(field + "^2"))
|
||||
.field("default_operator", "and")
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endArray()
|
||||
.endMap()
|
||||
.endMap()
|
||||
.endCollection()
|
||||
.field("minimum_should_match", "1")
|
||||
.endObject();
|
||||
.endMap();
|
||||
break;
|
||||
}
|
||||
case ANY: {
|
||||
String field = arg1.toString();
|
||||
String value = tok2 != null ? tok2.getString() : ""; // always unquoted
|
||||
// with phrase boost
|
||||
builder.startObject("bool")
|
||||
.startArray("should")
|
||||
.startObject()
|
||||
.startObject("simple_query_string")
|
||||
builder.beginMap("bool")
|
||||
.beginCollection("should")
|
||||
.beginMap()
|
||||
.beginMap("simple_query_string")
|
||||
.field("query", value)
|
||||
.field("fields", new String[]{field})
|
||||
.field("fields", Collections.singletonList(field))
|
||||
.field("analyze_wildcard", true)
|
||||
.endObject()
|
||||
.endObject()
|
||||
.startObject()
|
||||
.startObject("simple_query_string")
|
||||
.endMap()
|
||||
.endMap()
|
||||
.beginMap()
|
||||
.beginMap("simple_query_string")
|
||||
.field("query", "\"" + value + "\"")
|
||||
.field("fields", new String[]{ field + "^2"})
|
||||
.endObject()
|
||||
.endObject()
|
||||
.endArray()
|
||||
.field("fields", Collections.singletonList(field + "^2"))
|
||||
.endMap()
|
||||
.endMap()
|
||||
.endCollection()
|
||||
.field("minimum_should_match", "1")
|
||||
.endObject();
|
||||
.endMap();
|
||||
break;
|
||||
}
|
||||
case PHRASE: {
|
||||
|
@ -240,18 +239,18 @@ public class QueryGenerator implements Visitor {
|
|||
String field = arg1.toString();
|
||||
String value = tok2.isQuoted() ? tok2.getString() : arg2.toString();
|
||||
if (tok2.isAll()) {
|
||||
builder.startObject("match_all").endObject();
|
||||
builder.beginMap("match_all").endMap();
|
||||
} else if (tok2.isWildcard()) {
|
||||
builder.startObject("wildcard").field(field, value).endObject();
|
||||
builder.beginMap("wildcard").field(field, value).endMap();
|
||||
} else if (tok2.isBoundary()) {
|
||||
builder.startObject("prefix").field(field, value).endObject();
|
||||
builder.beginMap("prefix").field(field, value).endMap();
|
||||
} else {
|
||||
builder.startObject("simple_query_string")
|
||||
builder.beginMap("simple_query_string")
|
||||
.field("query", value)
|
||||
.field("fields", new String[]{field})
|
||||
.field("fields",Collections.singletonList(field))
|
||||
.field("analyze_wildcard", true)
|
||||
.field("default_operator", "and")
|
||||
.endObject();
|
||||
.endMap();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -259,37 +258,37 @@ public class QueryGenerator implements Visitor {
|
|||
case RANGE_GREATER_THAN: {
|
||||
String field = arg1.toString();
|
||||
String value = arg2 != null ? arg2.toString() : "";
|
||||
builder.startObject("range").startObject(field)
|
||||
builder.beginMap("range").beginMap(field)
|
||||
.field("from", value)
|
||||
.field("include_lower", false)
|
||||
.endObject().endObject();
|
||||
.endMap().endMap();
|
||||
break;
|
||||
}
|
||||
case RANGE_GREATER_OR_EQUAL: {
|
||||
String field = arg1.toString();
|
||||
String value = arg2 != null ? arg2.toString() : "";
|
||||
builder.startObject("range").startObject(field)
|
||||
builder.beginMap("range").beginMap(field)
|
||||
.field("from", value)
|
||||
.field("include_lower", true)
|
||||
.endObject().endObject();
|
||||
.endMap().endMap();
|
||||
break;
|
||||
}
|
||||
case RANGE_LESS_THAN: {
|
||||
String field = arg1.toString();
|
||||
String value = arg2 != null ? arg2.toString() : "";
|
||||
builder.startObject("range").startObject(field)
|
||||
builder.beginMap("range").beginMap(field)
|
||||
.field("to", value)
|
||||
.field("include_upper", false)
|
||||
.endObject().endObject();
|
||||
.endMap().endMap();
|
||||
break;
|
||||
}
|
||||
case RANGE_LESS_OR_EQUALS: {
|
||||
String field = arg1.toString();
|
||||
String value = arg2 != null ? arg2.toString() : "";
|
||||
builder.startObject("range").startObject(field)
|
||||
builder.beginMap("range").beginMap(field)
|
||||
.field("to", value)
|
||||
.field("include_upper", true)
|
||||
.endObject().endObject();
|
||||
.endMap().endMap();
|
||||
break;
|
||||
}
|
||||
case RANGE_WITHIN: {
|
||||
|
@ -310,12 +309,12 @@ public class QueryGenerator implements Visitor {
|
|||
from = tok2.getStringList().get(0);
|
||||
to = tok2.getStringList().get(1);
|
||||
}
|
||||
builder.startObject("range").startObject(field)
|
||||
builder.beginMap("range").beginMap(field)
|
||||
.field("from", from)
|
||||
.field("to", to)
|
||||
.field("include_lower", true)
|
||||
.field("include_upper", true)
|
||||
.endObject().endObject();
|
||||
.endMap().endMap();
|
||||
break;
|
||||
}
|
||||
case AND: {
|
||||
|
@ -324,23 +323,23 @@ public class QueryGenerator implements Visitor {
|
|||
arg1.accept(this);
|
||||
}
|
||||
} else {
|
||||
builder.startObject("bool");
|
||||
builder.beginMap("bool");
|
||||
if (arg1.isVisible() && arg2.isVisible()) {
|
||||
builder.startArray("must").startObject();
|
||||
builder.beginCollection("must").beginMap();
|
||||
arg1.accept(this);
|
||||
builder.endObject().startObject();
|
||||
builder.endMap().beginMap();
|
||||
arg2.accept(this);
|
||||
builder.endObject().endArray();
|
||||
builder.endMap().endCollection();
|
||||
} else if (arg1.isVisible()) {
|
||||
builder.startObject("must");
|
||||
builder.beginMap("must");
|
||||
arg1.accept(this);
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
} else if (arg2.isVisible()) {
|
||||
builder.startObject("must");
|
||||
builder.beginMap("must");
|
||||
arg2.accept(this);
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
}
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -351,23 +350,23 @@ public class QueryGenerator implements Visitor {
|
|||
arg1.accept(this);
|
||||
}
|
||||
} else {
|
||||
builder.startObject("bool");
|
||||
builder.beginMap("bool");
|
||||
if (arg1.isVisible() && arg2.isVisible()) {
|
||||
builder.startArray("should").startObject();
|
||||
builder.beginCollection("should").beginMap();
|
||||
arg1.accept(this);
|
||||
builder.endObject().startObject();
|
||||
builder.endMap().beginMap();
|
||||
arg2.accept(this);
|
||||
builder.endObject().endArray();
|
||||
builder.endMap().endCollection();
|
||||
} else if (arg1.isVisible()) {
|
||||
builder.startObject("should");
|
||||
builder.beginMap("should");
|
||||
arg1.accept(this);
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
} else if (arg2.isVisible()) {
|
||||
builder.startObject("should");
|
||||
builder.beginMap("should");
|
||||
arg2.accept(this);
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
}
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -377,23 +376,23 @@ public class QueryGenerator implements Visitor {
|
|||
arg1.accept(this);
|
||||
}
|
||||
} else {
|
||||
builder.startObject("bool");
|
||||
builder.beginMap("bool");
|
||||
if (arg1.isVisible() && arg2.isVisible()) {
|
||||
builder.startArray("must_not").startObject();
|
||||
builder.beginCollection("must_not").beginMap();
|
||||
arg1.accept(this);
|
||||
builder.endObject().startObject();
|
||||
builder.endMap().beginMap();
|
||||
arg2.accept(this);
|
||||
builder.endObject().endArray();
|
||||
builder.endMap().endCollection();
|
||||
} else if (arg1.isVisible()) {
|
||||
builder.startObject("must_not");
|
||||
builder.beginMap("must_not");
|
||||
arg1.accept(this);
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
} else if (arg2.isVisible()) {
|
||||
builder.startObject("must_not");
|
||||
builder.beginMap("must_not");
|
||||
arg2.accept(this);
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
}
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -401,7 +400,7 @@ public class QueryGenerator implements Visitor {
|
|||
String field = arg1.toString();
|
||||
// we assume a default of 10 words is enough for proximity
|
||||
String value = arg2 != null ? arg2 + "~10" : "";
|
||||
builder.startObject("field").field(field, value).endObject();
|
||||
builder.beginMap("field").field(field, value).endMap();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package org.xbib.cql.elasticsearch;
|
||||
|
||||
import org.xbib.content.XContentBuilder;
|
||||
import org.xbib.content.json.JsonXContent;
|
||||
import org.xbib.cql.SyntaxException;
|
||||
import org.xbib.cql.elasticsearch.ast.Expression;
|
||||
import org.xbib.cql.elasticsearch.ast.Modifier;
|
||||
|
@ -9,6 +7,7 @@ import org.xbib.cql.elasticsearch.ast.Name;
|
|||
import org.xbib.cql.elasticsearch.ast.Node;
|
||||
import org.xbib.cql.elasticsearch.ast.Operator;
|
||||
import org.xbib.cql.elasticsearch.ast.Token;
|
||||
import org.xbib.datastructures.json.tiny.JsonBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Stack;
|
||||
|
@ -18,24 +17,24 @@ import java.util.Stack;
|
|||
*/
|
||||
public class SortGenerator implements Visitor {
|
||||
|
||||
private final XContentBuilder builder;
|
||||
private final JsonBuilder builder;
|
||||
|
||||
private final Stack<Modifier> modifiers;
|
||||
|
||||
public SortGenerator() throws IOException {
|
||||
this.builder = JsonXContent.contentBuilder();
|
||||
public SortGenerator() {
|
||||
this.builder = new JsonBuilder();
|
||||
this.modifiers = new Stack<>();
|
||||
}
|
||||
|
||||
public void start() throws IOException {
|
||||
builder.startArray();
|
||||
builder.beginCollection();
|
||||
}
|
||||
|
||||
public void end() throws IOException {
|
||||
builder.endArray();
|
||||
builder.endCollection();
|
||||
}
|
||||
|
||||
public XContentBuilder getResult() {
|
||||
public JsonBuilder getResult() {
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
@ -47,15 +46,15 @@ public class SortGenerator implements Visitor {
|
|||
public void visit(Name node) {
|
||||
try {
|
||||
if (modifiers.isEmpty()) {
|
||||
builder.startObject()
|
||||
.field(node.getName())
|
||||
.startObject()
|
||||
builder.beginMap()
|
||||
.buildKey(node.getName())
|
||||
.beginMap()
|
||||
.field("unmapped_type", "string")
|
||||
.field("missing", "_last")
|
||||
.endObject()
|
||||
.endObject();
|
||||
.endMap()
|
||||
.endMap();
|
||||
} else {
|
||||
builder.startObject().field(node.getName()).startObject();
|
||||
builder.beginMap().buildKey(node.getName()).beginMap();
|
||||
while (!modifiers.isEmpty()) {
|
||||
Modifier mod = modifiers.pop();
|
||||
String s = mod.getName().toString();
|
||||
|
@ -71,15 +70,15 @@ public class SortGenerator implements Visitor {
|
|||
break;
|
||||
}
|
||||
default: {
|
||||
builder.field(s, mod.getTerm());
|
||||
builder.field(s, mod.getTerm().toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
builder.field("unmapped_type", "string");
|
||||
builder.field("missing", "_last");
|
||||
builder.endObject();
|
||||
builder.endObject();
|
||||
builder.endMap();
|
||||
builder.endMap();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new SyntaxException(e.getMessage(), e);
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
package org.xbib.cql.elasticsearch;
|
||||
|
||||
import org.xbib.content.XContentBuilder;
|
||||
import org.xbib.content.core.DefaultXContentBuilder;
|
||||
import org.xbib.content.json.JsonXContent;
|
||||
import org.xbib.datastructures.json.tiny.JsonBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SourceGenerator {
|
||||
|
||||
private final XContentBuilder builder;
|
||||
private final JsonBuilder builder;
|
||||
|
||||
public SourceGenerator() throws IOException {
|
||||
this.builder = JsonXContent.contentBuilder();
|
||||
this.builder = new JsonBuilder();
|
||||
}
|
||||
|
||||
public void build(QueryGenerator query) throws IOException {
|
||||
|
@ -23,8 +21,8 @@ public class SourceGenerator {
|
|||
}
|
||||
|
||||
public void build(QueryGenerator query, Integer from, Integer size,
|
||||
XContentBuilder sort, XContentBuilder facets) throws IOException {
|
||||
builder.startObject();
|
||||
JsonBuilder sort, JsonBuilder facets) throws IOException {
|
||||
builder.beginMap();
|
||||
if (query != null) {
|
||||
if (from != null) {
|
||||
builder.field("from", from);
|
||||
|
@ -32,25 +30,23 @@ public class SourceGenerator {
|
|||
if (size != null) {
|
||||
builder.field("size", size);
|
||||
}
|
||||
copy(builder, "query", query.getResult());
|
||||
copy(builder, "sort", sort);
|
||||
copy(builder, "aggregations", facets);
|
||||
if (query.getResult() != null) {
|
||||
builder.buildKey("query");
|
||||
builder.copy(query.getResult());
|
||||
}
|
||||
builder.endObject();
|
||||
builder.close();
|
||||
if (sort != null && sort.build().length() > 0) {
|
||||
builder.buildKey("sort");
|
||||
builder.copy(sort);
|
||||
}
|
||||
if (facets != null && facets.build().length() > 0) {
|
||||
builder.buildKey("aggregations");
|
||||
builder.copy(facets);
|
||||
}
|
||||
}
|
||||
builder.endMap();
|
||||
}
|
||||
|
||||
public XContentBuilder getResult() {
|
||||
public JsonBuilder getResult() {
|
||||
return builder;
|
||||
}
|
||||
|
||||
private void copy(XContentBuilder builder, String rawFieldName, XContentBuilder anotherBuilder) throws IOException {
|
||||
if (anotherBuilder != null) {
|
||||
DefaultXContentBuilder contentBuilder = (DefaultXContentBuilder) anotherBuilder;
|
||||
if (contentBuilder.bytes().length() > 0) {
|
||||
byte[] b = contentBuilder.bytes().toBytes();
|
||||
builder.rawField(rawFieldName, b, 0, b.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,12 +7,11 @@ import java.io.IOException;
|
|||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class ElasticsearchQueryTest {
|
||||
|
||||
@Test
|
||||
|
@ -27,7 +26,7 @@ class ElasticsearchQueryTest {
|
|||
parser.parse();
|
||||
ElasticsearchFilterGenerator generator = new ElasticsearchFilterGenerator("cql.allIndexes");
|
||||
parser.getCQLQuery().accept(generator);
|
||||
String json = generator.getResult().string();
|
||||
String json = generator.getResult().build();
|
||||
assertEquals(json, "{\"term\":{\"cql.allIndexes\":\"Jörg\"}}");
|
||||
}
|
||||
|
||||
|
@ -38,7 +37,7 @@ class ElasticsearchQueryTest {
|
|||
parser.parse();
|
||||
ElasticsearchFilterGenerator generator = new ElasticsearchFilterGenerator("cql.allIndexes");
|
||||
parser.getCQLQuery().accept(generator);
|
||||
String json = generator.getResult().string();
|
||||
String json = generator.getResult().build();
|
||||
assertEquals(json, "{\"query\":{\"term\":{\"dc.type\":\"electronic\"}}}");
|
||||
}
|
||||
|
||||
|
@ -49,7 +48,7 @@ class ElasticsearchQueryTest {
|
|||
parser.parse();
|
||||
ElasticsearchFilterGenerator generator = new ElasticsearchFilterGenerator("cql.allIndexes");
|
||||
parser.getCQLQuery().accept(generator);
|
||||
String json = generator.getResult().string();
|
||||
String json = generator.getResult().build();
|
||||
assertEquals(
|
||||
"{\"query\":{\"bool\":{\"must\":[{\"term\":{\"dc.type\":\"electronic\"}},{\"term\":{\"dc.date\":\"2013\"}}]}}}",
|
||||
json
|
||||
|
@ -63,7 +62,7 @@ class ElasticsearchQueryTest {
|
|||
parser.parse();
|
||||
ElasticsearchFilterGenerator generator = new ElasticsearchFilterGenerator("cql.allIndexes");
|
||||
parser.getCQLQuery().accept(generator);
|
||||
String json = generator.getResult().string();
|
||||
String json = generator.getResult().build();
|
||||
assertEquals(
|
||||
"{\"query\":{\"bool\":{\"must\":[{\"bool\":{\"must\":[{\"term\":{\"dc.format\":\"online\"}}," +
|
||||
"{\"term\":{\"dc.type\":\"electronic\"}}]}},{\"term\":{\"dc.date\":\"2013\"}}]}}}",
|
||||
|
@ -112,6 +111,8 @@ class ElasticsearchQueryTest {
|
|||
}
|
||||
} catch (Exception e) {
|
||||
errors++;
|
||||
Logger.getAnonymousLogger().log(Level.SEVERE, line);
|
||||
Logger.getAnonymousLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
group = org.xbib
|
||||
name = cql
|
||||
version = 3.1.4
|
||||
version = 4.0.0
|
||||
|
||||
gradle.wrapper.version = 6.6.1
|
||||
xbib-content.version = 3.0.0
|
||||
xbib-datastructures.version = 1.0.0
|
||||
|
|
Loading…
Reference in a new issue