├── README.md ├── src ├── test │ ├── resources │ │ ├── heatmap-png.json │ │ └── heatmap-normal.json │ └── java │ │ └── com │ │ └── datastax │ │ └── alexott │ │ └── search │ │ ├── SolrQueryTest.java │ │ └── FacetParsersTest.java └── main │ └── java │ └── com │ └── datastax │ └── alexott │ └── search │ ├── FacetParsers.java │ ├── Heatmap.java │ └── SolrQuery.java ├── .gitignore └── pom.xml /README.md: -------------------------------------------------------------------------------- 1 | # dse-search-tools 2 | Utility classes for work with DSE Search 3 | -------------------------------------------------------------------------------- /src/test/resources/heatmap-png.json: -------------------------------------------------------------------------------- 1 | {"lat_long":{"gridLevel":2,"columns":32,"rows":32,"minX":-180.0,"maxX":180.0,"minY":-90.0,"maxY":90.0,"counts_png":"iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAXElEQVR42mNgYGD4P8B41AGjDqCmYUL0doAcEFcCsS+Ur0VvBwgCcT8Qh9A6CjzpnQaC0fjcVLTQczQbjjpg1AGjDhh1wKgDgFhyoB0gN5oGRh0w6oBRBwweBwAAx7z/afcsq1wAAAAASUVORK5CYII="}} 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | pom.xml.tag 3 | pom.xml.releaseBackup 4 | pom.xml.versionsBackup 5 | pom.xml.next 6 | release.properties 7 | dependency-reduced-pom.xml 8 | buildNumber.properties 9 | .mvn/timing.properties 10 | 11 | # Avoid ignoring Maven wrapper jar file (.jar files are usually ignored) 12 | !/.mvn/wrapper/maven-wrapper.jar 13 | *~ 14 | /.idea/ 15 | -------------------------------------------------------------------------------- /src/test/java/com/datastax/alexott/search/SolrQueryTest.java: -------------------------------------------------------------------------------- 1 | package com.datastax.alexott.search; 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException; 4 | import junit.framework.TestCase; 5 | 6 | public class SolrQueryTest extends TestCase { 7 | 8 | public void testDefault () throws JsonProcessingException { 9 | SolrQuery solrQuery = SolrQuery.builder().build(); 10 | assertEquals("{\"q\":\"*:*\"}", solrQuery.get()); 11 | } 12 | 13 | public void testFq () throws JsonProcessingException { 14 | SolrQuery solrQuery = SolrQuery.builder().withFilterQuery("q:1").build(); 15 | assertEquals("{\"q\":\"*:*\",\"fq\":\"q:1\"}", solrQuery.get()); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /src/test/resources/heatmap-normal.json: -------------------------------------------------------------------------------- 1 | {"lat_long":{"gridLevel":2,"columns":32,"rows":32,"minX":-180.0,"maxX":180.0,"minY":-90.0,"maxY":90.0,"counts_ints2D":[null,null,null,null,null,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,121,77,0,42,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,143,84,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,73,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,83,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,73,0,0,0],null,null,null,null,null,null,null,null,null,null,null,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,0,0],null,null,null,null,null,null,null,null,null]}} 2 | -------------------------------------------------------------------------------- /src/main/java/com/datastax/alexott/search/FacetParsers.java: -------------------------------------------------------------------------------- 1 | package com.datastax.alexott.search; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | 5 | import java.io.IOException; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | public class FacetParsers { 10 | final static ObjectMapper OBJECT_MAPPER = new ObjectMapper(); 11 | 12 | public static Map parseHeatmap(String json) { 13 | Map map = new HashMap(); 14 | try { 15 | Map m = new HashMap<>(); 16 | m = OBJECT_MAPPER.readValue(json, m.getClass()); 17 | for (Map.Entry e: m.entrySet()) { 18 | Heatmap h = OBJECT_MAPPER.convertValue(e.getValue(), Heatmap.class); 19 | map.put(e.getKey(), h); 20 | } 21 | } catch (IOException e) { 22 | return null; 23 | } 24 | 25 | return map; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/com/datastax/alexott/search/FacetParsersTest.java: -------------------------------------------------------------------------------- 1 | package com.datastax.alexott.search; 2 | 3 | import junit.framework.TestCase; 4 | import org.apache.commons.lang3.StringUtils; 5 | 6 | import java.io.IOException; 7 | import java.nio.file.Files; 8 | import java.nio.file.Paths; 9 | import java.util.Map; 10 | 11 | public class FacetParsersTest extends TestCase { 12 | public void testHeatmapNormal() throws IOException { 13 | String normalJson = new String(Files.readAllBytes(Paths.get("src/test/resources/heatmap-normal.json"))); 14 | assertNotNull(normalJson); 15 | Map m = FacetParsers.parseHeatmap(normalJson); 16 | assertNotNull(m); 17 | Heatmap h = m.get("lat_long"); 18 | assertNotNull(h); 19 | assertEquals(32, h.getRows()); 20 | assertEquals(32, h.getColumns()); 21 | } 22 | 23 | public void testHeatmapPng() throws IOException { 24 | String normalJson = new String(Files.readAllBytes(Paths.get("src/test/resources/heatmap-png.json"))); 25 | assertNotNull(normalJson); 26 | Map m = FacetParsers.parseHeatmap(normalJson); 27 | assertNotNull(m); 28 | Heatmap h = m.get("lat_long"); 29 | assertNotNull(h); 30 | assertEquals(32, h.getRows()); 31 | assertEquals(32, h.getColumns()); 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/java/com/datastax/alexott/search/Heatmap.java: -------------------------------------------------------------------------------- 1 | package com.datastax.alexott.search; 2 | 3 | import com.fasterxml.jackson.annotation.JsonGetter; 4 | import com.fasterxml.jackson.annotation.JsonIgnore; 5 | import com.fasterxml.jackson.annotation.JsonProperty; 6 | 7 | 8 | import java.util.Base64; 9 | import java.util.List; 10 | 11 | public class Heatmap { 12 | @JsonProperty 13 | int gridLevel; 14 | @JsonProperty 15 | int columns; 16 | @JsonProperty 17 | int rows; 18 | @JsonProperty 19 | double minX, minY, maxX, maxY; 20 | 21 | @JsonProperty 22 | String counts_png; 23 | @JsonProperty("counts_ints2D") 24 | List> counts; 25 | 26 | 27 | public int getGridLevel() { 28 | return gridLevel; 29 | } 30 | 31 | public int getColumns() { 32 | return columns; 33 | } 34 | 35 | public int getRows() { 36 | return rows; 37 | } 38 | 39 | public double getMinX() { 40 | return minX; 41 | } 42 | 43 | public double getMinY() { 44 | return minY; 45 | } 46 | 47 | public double getMaxX() { 48 | return maxX; 49 | } 50 | 51 | public double getMaxY() { 52 | return maxY; 53 | } 54 | 55 | @JsonGetter("counts_png") 56 | public String getCountsPngRaw() { 57 | return counts_png; 58 | } 59 | 60 | public List> getCounts() { 61 | return counts; 62 | } 63 | 64 | @JsonIgnore 65 | public byte[] getCountsPng() { 66 | if (counts_png == null) { 67 | return null; 68 | } 69 | return Base64.getDecoder().decode(counts_png); 70 | } 71 | 72 | @Override 73 | public String toString() { 74 | return "Heatmap{" + 75 | "gridLevel=" + gridLevel + 76 | ", columns=" + columns + 77 | ", rows=" + rows + 78 | ", minX=" + minX + 79 | ", minY=" + minY + 80 | ", maxX=" + maxX + 81 | ", maxY=" + maxY + 82 | ", counts_png='" + counts_png + '\'' + 83 | ", counts=" + counts + 84 | '}'; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.datastax.alexott 6 | dse-search-tools 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | Search helpers for DSE 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 2.9.9 16 | 2.9.9.3 17 | 1.8 18 | 19 | 20 | 21 | 22 | junit 23 | junit 24 | 3.8.1 25 | test 26 | 27 | 28 | com.fasterxml.jackson.core 29 | jackson-databind 30 | ${jackson.databind.version} 31 | 32 | 33 | com.fasterxml.jackson.core 34 | jackson-annotations 35 | ${jackson.version} 36 | 37 | 38 | com.fasterxml.jackson.core 39 | jackson-core 40 | ${jackson.version} 41 | 42 | 43 | com.fasterxml.jackson.module 44 | jackson-module-parameter-names 45 | ${jackson.version} 46 | 47 | 48 | com.fasterxml.jackson.datatype 49 | jackson-datatype-jdk8 50 | ${jackson.version} 51 | 52 | 53 | com.fasterxml.jackson.datatype 54 | jackson-datatype-jsr310 55 | ${jackson.version} 56 | 57 | 58 | org.apache.commons 59 | commons-lang3 60 | 3.8.1 61 | test 62 | 63 | 64 | 65 | 66 | 67 | 68 | maven-compiler-plugin 69 | 3.6.1 70 | 71 | ${java.version} 72 | ${java.version} 73 | true 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/main/java/com/datastax/alexott/search/SolrQuery.java: -------------------------------------------------------------------------------- 1 | package com.datastax.alexott.search; 2 | 3 | import com.fasterxml.jackson.annotation.JsonInclude; 4 | import com.fasterxml.jackson.annotation.JsonProperty; 5 | import com.fasterxml.jackson.core.JsonProcessingException; 6 | import com.fasterxml.jackson.databind.ObjectMapper; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | /* 12 | * Class for easier building of the Solr queries for DSE. 13 | * 14 | * https://docs.datastax.com/en/dse/5.1/dse-dev/datastax_enterprise/search/siQuerySyntax.html#siQuerySyntax 15 | */ 16 | public class SolrQuery { 17 | final static String DEFAULT_QUERY = "*:*"; 18 | final static ObjectMapper OBJECT_MAPPER = new ObjectMapper(); 19 | 20 | final String query; 21 | 22 | private SolrQuery() { 23 | query = DEFAULT_QUERY; 24 | } 25 | 26 | private SolrQuery(String q) { 27 | query = q; 28 | } 29 | 30 | @JsonInclude(JsonInclude.Include.NON_NULL) 31 | public static class Builder { 32 | @JsonProperty 33 | String q = DEFAULT_QUERY; 34 | @JsonProperty 35 | String fq = null; 36 | @JsonProperty 37 | String sort = null; 38 | @JsonProperty 39 | String paging = null; 40 | @JsonProperty 41 | Integer start = null; 42 | @JsonProperty("distrib.singlePass") 43 | Boolean singlePass = null; 44 | @JsonProperty("shards.failover") 45 | Boolean shardsFailover = null; 46 | @JsonProperty("shards.tolerant") 47 | Boolean shardsTolerant = null; 48 | @JsonProperty 49 | Boolean commit = null; 50 | @JsonProperty("route.partition") 51 | List routePartition = null; 52 | @JsonProperty("route.range") 53 | List routeRange = null; 54 | @JsonProperty("query.name") 55 | String queryName = null; 56 | @JsonProperty 57 | Map facet = null; 58 | 59 | private Builder() {} 60 | 61 | public Builder withQuery(final String q) { 62 | this.q = q; 63 | return this; 64 | } 65 | 66 | public Builder withFilterQuery(final String fq) { 67 | this.fq = fq; 68 | return this; 69 | } 70 | 71 | public Builder withPaging(final String pg) { 72 | this.paging = pg; 73 | return this; 74 | } 75 | 76 | public Builder withSort(final String srt) { 77 | this.sort = srt; 78 | return this; 79 | } 80 | 81 | // TODO: add function that will take field name & direction, and append to sort string 82 | 83 | 84 | public Builder withQueryName(final String qn) { 85 | this.queryName = qn; 86 | return this; 87 | } 88 | 89 | // TODO: don't have enabled/disabled, but instead allow to change only non-default value 90 | public Builder withSinglePassEnabled() { 91 | this.singlePass = true; 92 | return this; 93 | } 94 | 95 | public Builder withSinglePassDisabled() { 96 | this.singlePass = false; 97 | return this; 98 | } 99 | 100 | public Builder withCommitEnabled() { 101 | this.commit = true; 102 | return this; 103 | } 104 | 105 | public Builder withFacet(Map fc) { 106 | facet = fc; 107 | return this; 108 | } 109 | 110 | // TODO: add withFacet that will take a Facet instance 111 | 112 | public SolrQuery build() throws JsonProcessingException { 113 | String query = OBJECT_MAPPER.writeValueAsString(this); 114 | // System.out.println("Generated query: '" + query + "'"); 115 | return new SolrQuery(query); 116 | } 117 | } 118 | 119 | public static Builder builder() { 120 | return new Builder(); 121 | } 122 | 123 | public String get() { 124 | return query; 125 | } 126 | 127 | } 128 | --------------------------------------------------------------------------------