Skip to content

Commit

Permalink
datastore-solr: fix facet query parser, #36
Browse files Browse the repository at this point in the history
  • Loading branch information
jtarraga committed Oct 5, 2018
1 parent aca9092 commit 5ede4af
Showing 1 changed file with 54 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,12 @@ public class FacetQueryParser {
private static final String FACET_SEPARATOR = ";";
public static final String LABEL_SEPARATOR = "___";
private static final String NESTED_FACET_SEPARATOR = ">>";
private static final String NESTED_SUBFACET_SEPARATOR = "--"; //"\\+";
private static final String NESTED_SUBFACET_SEPARATOR = ",";
private static final String INCLUDE_SEPARATOR = ",";
private static final String RANGE_IDENTIFIER = "..";
private static final String AGGREGATION_IDENTIFIER = "(";
private static final String[] AGGREGATION_FUNCTIONS = {"sum", "avg", "max", "min", "unique", "percentile", "sumsq", "variance",
"stddev", };

// public static final Pattern RANGE_PATTERN =
// Pattern.compile("^([a-zA-Z][a-zA-Z0-9_.]+)\\[([-]?[0-9]+)\\.\\.([-]?[0-9]+)]:([-]?[0-9]+)$");
public static final Pattern CATEGORICAL_PATTERN = Pattern.compile("^([a-zA-Z][a-zA-Z0-9_.]+)(\\[[a-zA-Z0-9,*]+])?(:\\*|:\\d+)?$");

private int count;
Expand All @@ -47,6 +45,7 @@ public FacetQueryParser() {

/**
* This method accepts a simple facet declaration format and converts it into a rich JSON query.
*
* @param query A string with the format: chrom>>type,biotype,avg>>gerp,avg;type;biotype>>sadasd
* @return A JSON string facet query
* @throws Exception Any exception related with JSON conversion
Expand All @@ -57,20 +56,16 @@ public String parse(String query) throws Exception {
}

Map<String, Object> jsonFacetMap = new LinkedHashMap<>();
if (query.contains(FACET_SEPARATOR)) {
String[] split = query.split(FACET_SEPARATOR);
for (String facet : split) {
if (facet.contains(NESTED_FACET_SEPARATOR)) {
parseNestedFacet(facet, jsonFacetMap);
} else {
parseSimpleFacet(facet, jsonFacetMap);
String[] split = query.split(FACET_SEPARATOR);
for (String facet : split) {
if (facet.contains(NESTED_FACET_SEPARATOR)) {
parseNestedFacet(facet, jsonFacetMap);
} else {
List<String> simpleFacets = getSubFacets(facet);
for (String simpleFacet : simpleFacets) {
parseSimpleFacet(simpleFacet, jsonFacetMap);
}
}
} else {
String[] split = query.split("[" + FACET_SEPARATOR + "\\-\\-]");
for (String facet : split) {
parseSimpleFacet(facet, jsonFacetMap);
}
}

return parseJson(new ObjectMapper().writeValueAsString(jsonFacetMap));
Expand All @@ -82,7 +77,11 @@ private void parseSimpleFacet(String facet, Map<String, Object> jsonFacetMap) th
if (facetMap == null) {
// Aggregation
label = getLabelFromAggregation(facet);
jsonFacetMap.put(label, facet);
if (facet.startsWith("percentile")) {
jsonFacetMap.put(label, facet.replace(")", ",1,10,25,50,75,90,99)"));
} else {
jsonFacetMap.put(label, facet);
}
} else {
// Categorical or range
label = getLabel(facetMap);
Expand All @@ -104,14 +103,8 @@ private String getLabel(Map<String, Object> facetMap) {
private String getLabelFromAggregation(String facet) {
String label;
String aggregationName = facet.substring(0, facet.indexOf("("));
if (facet.startsWith("percentile")) {
String fieldName = facet.substring(facet.indexOf("(") + 1, facet.indexOf(","));
String[] params = facet.substring(facet.indexOf(",") + 1).split(",");
label = fieldName + LABEL_SEPARATOR + aggregationName + LABEL_SEPARATOR + StringUtils.join(params, LABEL_SEPARATOR);
} else {
String fieldName = facet.substring(facet.indexOf("(") + 1, facet.indexOf(")"));
label = fieldName + LABEL_SEPARATOR + aggregationName;
}
String fieldName = facet.substring(facet.indexOf("(") + 1, facet.indexOf(")"));
label = fieldName + LABEL_SEPARATOR + aggregationName;
return label + LABEL_SEPARATOR + (count++);
}

Expand All @@ -125,7 +118,7 @@ private Map<String, Object> parseFacet(String facet) throws Exception {
Map<String, Object> outputMap = new HashMap<>();
if (facet.contains(AGGREGATION_IDENTIFIER)) {
// Validate function
for (String function: AGGREGATION_FUNCTIONS) {
for (String function : AGGREGATION_FUNCTIONS) {
if (facet.startsWith(function)) {
return null;
}
Expand Down Expand Up @@ -160,7 +153,7 @@ private Map<String, Object> parseFacet(String facet) throws Exception {
} else {
// domain : { filter : "popularity:HIGH OR popularity:LOW" }
List<String> filters = new ArrayList<>();
for (String value : include.split(",")) {
for (String value : include.split(INCLUDE_SEPARATOR)) {
filters.add(matcher.group(1) + ":" + value);
}
Map<String, Object> auxMap = new HashMap<>();
Expand Down Expand Up @@ -191,8 +184,8 @@ private void parseNestedFacet(String nestedFacet, Map<String, Object> jsonFacet)
Map<String, Object> childFacetMap = new HashMap<>();
for (int i = split.length - 1; i >= 0; i--) {
String facet = split[i];
String[] subfacets = facet.split(NESTED_SUBFACET_SEPARATOR);
for (String subfacet : subfacets) {
List<String> subfacets = getSubFacets(facet);
for (String subfacet: subfacets) {
parseSimpleFacet(subfacet, rootFacetMap);
}

Expand Down Expand Up @@ -254,4 +247,36 @@ static Number parseNumber(String number) {
}
}

static List<String> getSubFacets(String query) {
String facet = "";
List<String> facets = new ArrayList<>();
String[] split = query.split(NESTED_SUBFACET_SEPARATOR);
for (String s: split) {
if (s.contains("[")) {
if (s.contains("]")) {
facets.add(s);
facet = null;
} else {
if (StringUtils.isEmpty(facet)) {
facet = s;
} else {
facets.add(facet);
facet = s;
}
}
} else if (s.contains("]")) {
facets.add(facet + "," + s);
facet = null;
} else {
if (StringUtils.isEmpty(facet)) {
facets.add(s);
facet = null;
} else {
facet += ("," + s);
}
}
}

return facets;
}
}

0 comments on commit 5ede4af

Please sign in to comment.