package sagan.search.support; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import io.searchbox.client.JestResult; import com.google.common.collect.Lists; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @Service class SearchResultParser { public SearchResults parseResults(JestResult jestResult, Pageable pageable, String originalSearchTerm) { JsonObject response = jestResult.getJsonObject(); JsonObject hits = response.getAsJsonObject("hits"); JsonArray resultsArray = hits.getAsJsonArray("hits"); ArrayList<SearchResult> results = prepareResults(resultsArray, originalSearchTerm); int totalResults = hits.get("total").getAsInt(); PageImpl<SearchResult> page = new PageImpl<>(results, pageable, totalResults); List<SearchFacet> facets = prepareFacets(response); return new SearchResults(page, facets); } private List<SearchFacet> prepareFacets(JsonObject response) { JsonObject facets = response.getAsJsonObject("facets"); if (facets == null) { return Collections.emptyList(); } JsonObject pathsResult = facets.getAsJsonObject("facet_paths_result"); List<JsonElement> terms = sortedTermElements(pathsResult.getAsJsonArray("terms")); SearchFacetTreeBuilder builder = new SearchFacetTreeBuilder(); for (JsonElement element : terms) { JsonObject jsonObject = element.getAsJsonObject(); String term = jsonObject.get("term").getAsString(); int count = jsonObject.get("count").getAsInt(); builder.addTerm(term, count); } return builder.build(); } private List<JsonElement> sortedTermElements(JsonArray termArray) { ArrayList<JsonElement> list = Lists.newArrayList(termArray); Collections.sort(list, (o1, o2) -> { String term1 = o1.getAsJsonObject().get("term").getAsString().replace(" ", ""); String term2 = o2.getAsJsonObject().get("term").getAsString().replace(" ", ""); return term1.compareTo(term2); }); return list; } private ArrayList<SearchResult> prepareResults(JsonArray hits, String originalSearchTerm) { ArrayList<SearchResult> results = new ArrayList<>(); for (JsonElement element : hits) { JsonObject hit = element.getAsJsonObject(); String id = hit.get("_id").getAsString(); JsonObject source = hit.getAsJsonObject("_source"); String title = source.get("title").getAsString(); String url = source.get("path").getAsString(); String type = hit.get("_type").getAsString(); String summary = source.get("summary").getAsString(); String subtitle = safelyLookupFieldString(source, "subTitle"); String highlight = extractHighlight(hit); SearchResult result = new SearchResult(id, title, subtitle, summary, url, type, highlight, originalSearchTerm); results.add(result); } return results; } private String safelyLookupFieldString(JsonObject source, String field) { JsonElement fieldElement = source.get(field); return (fieldElement != null) ? fieldElement.getAsString() : ""; } private String extractHighlight(JsonObject hit) { String summary = null; JsonObject highlight = hit.getAsJsonObject("highlight"); if (highlight != null) { JsonArray rawContent = highlight.getAsJsonArray("rawContent"); summary = rawContent.get(0).getAsString(); } return summary; } }