private SearchResponse doSearch(SearchRequestBuilder searchRequest, SearchQuery searchQuery) { if (searchQuery.getFilter() != null) { searchRequest.setPostFilter(searchQuery.getFilter()); } if (CollectionUtils.isNotEmpty(searchQuery.getElasticsearchSorts())) { for (SortBuilder sort : searchQuery.getElasticsearchSorts()) { searchRequest.addSort(sort); } } if (CollectionUtils.isNotEmpty(searchQuery.getFacets())) { for (FacetRequest facetRequest : searchQuery.getFacets()) { FacetBuilder facet = facetRequest.getFacet(); if (facetRequest.applyQueryFilter() && searchQuery.getFilter() != null) { facet.facetFilter(searchQuery.getFilter()); } searchRequest.addFacet(facet); } } if (searchQuery.getHighlightFields() != null) { for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) { searchRequest.addHighlightedField(highlightField); } } if (CollectionUtils.isNotEmpty(searchQuery.getAggregations())) { for (AbstractAggregationBuilder aggregationBuilder : searchQuery.getAggregations()) { searchRequest.addAggregation(aggregationBuilder); } } return searchRequest.setQuery(searchQuery.getQuery()).execute().actionGet(); }
private void explanFields( SearchRequestBuilder request, List<Field> fields, AggregationBuilder<?> groupByAgg) throws SqlParseException { for (Field field : fields) { if (field instanceof MethodField) { AbstractAggregationBuilder makeAgg = aggMaker.makeFieldAgg((MethodField) field, groupByAgg); if (groupByAgg != null) { groupByAgg.subAggregation(makeAgg); } else { request.addAggregation(makeAgg); } } else if (field instanceof Field) { request.addField(field.getName()); } else { throw new SqlParseException("it did not support this field method " + field); } } }
@Override public Map<String, Integer> countTermsByField(SearchCriteria searchCriteria, String field) { ElasticSearchCriteria criteria = (ElasticSearchCriteria) searchCriteria; if (criteria == null) return null; SearchRequestBuilder srb = criteria2builder(criteria); srb.setFrom(0); srb.setSize(0); TermsBuilder tb = AggregationBuilders.terms(field); tb.field(field); srb.addAggregation(tb); try { SearchResponse response = srb.execute().get(); StringTerms aggr = response.getAggregations().get(field); Map<String, Integer> result = new LinkedHashMap<>(); for (Terms.Bucket bucket : aggr.getBuckets()) { result.put(bucket.getKey(), (int) bucket.getDocCount()); } return result; } catch (Exception e) { logger.error(e.getMessage(), e); } return Collections.emptyMap(); }
// Make sure that unordered, reversed, disjoint and/or overlapping ranges are supported // Duel with filters public void testRandomRanges() throws Exception { final int numDocs = scaledRandomIntBetween(500, 5000); final double[][] docs = new double[numDocs][]; for (int i = 0; i < numDocs; ++i) { final int numValues = randomInt(5); docs[i] = new double[numValues]; for (int j = 0; j < numValues; ++j) { docs[i][j] = randomDouble() * 100; } } createIndex("idx"); for (int i = 0; i < docs.length; ++i) { XContentBuilder source = jsonBuilder().startObject().startArray("values"); for (int j = 0; j < docs[i].length; ++j) { source = source.value(docs[i][j]); } source = source.endArray().endObject(); client().prepareIndex("idx", "type").setSource(source).execute().actionGet(); } assertNoFailures( client() .admin() .indices() .prepareRefresh("idx") .setIndicesOptions(IndicesOptions.lenientExpandOpen()) .execute() .get()); final int numRanges = randomIntBetween(1, 20); final double[][] ranges = new double[numRanges][]; for (int i = 0; i < ranges.length; ++i) { switch (randomInt(2)) { case 0: ranges[i] = new double[] {Double.NEGATIVE_INFINITY, randomInt(100)}; break; case 1: ranges[i] = new double[] {randomInt(100), Double.POSITIVE_INFINITY}; break; case 2: ranges[i] = new double[] {randomInt(100), randomInt(100)}; break; default: throw new AssertionError(); } } RangeBuilder query = range("range").field("values"); for (int i = 0; i < ranges.length; ++i) { String key = Integer.toString(i); if (ranges[i][0] == Double.NEGATIVE_INFINITY) { query.addUnboundedTo(key, ranges[i][1]); } else if (ranges[i][1] == Double.POSITIVE_INFINITY) { query.addUnboundedFrom(key, ranges[i][0]); } else { query.addRange(key, ranges[i][0], ranges[i][1]); } } SearchRequestBuilder reqBuilder = client().prepareSearch("idx").addAggregation(query); for (int i = 0; i < ranges.length; ++i) { RangeFilterBuilder filter = FilterBuilders.rangeFilter("values"); if (ranges[i][0] != Double.NEGATIVE_INFINITY) { filter = filter.from(ranges[i][0]); } if (ranges[i][1] != Double.POSITIVE_INFINITY) { filter = filter.to(ranges[i][1]); } reqBuilder = reqBuilder.addAggregation(filter("filter" + i).filter(filter)); } SearchResponse resp = reqBuilder.execute().actionGet(); Range range = resp.getAggregations().get("range"); for (int i = 0; i < ranges.length; ++i) { long count = 0; for (double[] values : docs) { for (double value : values) { if (value >= ranges[i][0] && value < ranges[i][1]) { ++count; break; } } } final Range.Bucket bucket = range.getBucketByKey(Integer.toString(i)); assertEquals(bucket.getKey(), count, bucket.getDocCount()); final Filter filter = resp.getAggregations().get("filter" + i); assertThat(filter.getDocCount(), equalTo(count)); } }
@Override public SqlElasticSearchRequestBuilder explain() throws SqlParseException { this.request = client.prepareSearch(); request.setListenerThreaded(false); setIndicesAndTypes(); setWhere(select.getWhere()); AggregationBuilder<?> lastAgg = null; for (List<Field> groupBy : select.getGroupBys()) { if (!groupBy.isEmpty()) { Field field = groupBy.get(0); lastAgg = aggMaker.makeGroupAgg(field); if (lastAgg != null && lastAgg instanceof TermsBuilder && !(field instanceof MethodField)) { ((TermsBuilder) lastAgg).size(select.getRowCount()); } if (field.isNested()) { AggregationBuilder nestedBuilder = createNestedAggregation(field); if (insertFilterIfExistsAfter(lastAgg, groupBy, nestedBuilder, 1)) { groupBy.remove(1); } else { nestedBuilder.subAggregation(lastAgg); } request.addAggregation(wrapNestedIfNeeded(nestedBuilder, field.isReverseNested())); } else { request.addAggregation(lastAgg); } for (int i = 1; i < groupBy.size(); i++) { field = groupBy.get(i); AggregationBuilder<?> subAgg = aggMaker.makeGroupAgg(field); if (subAgg instanceof TermsBuilder && !(field instanceof MethodField)) { ((TermsBuilder) subAgg).size(0); } if (field.isNested()) { AggregationBuilder nestedBuilder = createNestedAggregation(field); if (insertFilterIfExistsAfter(subAgg, groupBy, nestedBuilder, i + 1)) { groupBy.remove(i + 1); i++; } else { nestedBuilder.subAggregation(subAgg); } lastAgg.subAggregation(wrapNestedIfNeeded(nestedBuilder, field.isReverseNested())); } else { lastAgg.subAggregation(subAgg); } lastAgg = subAgg; } } } Map<String, KVValue> groupMap = aggMaker.getGroupMap(); // add field if (select.getFields().size() > 0) { setFields(select.getFields()); explanFields(request, select.getFields(), lastAgg); } // add order if (lastAgg != null && select.getOrderBys().size() > 0) { for (Order order : select.getOrderBys()) { KVValue temp = groupMap.get(order.getName()); if (temp != null) { TermsBuilder termsBuilder = (TermsBuilder) temp.value; switch (temp.key) { case "COUNT": termsBuilder.order(Terms.Order.count(isASC(order))); break; case "KEY": termsBuilder.order(Terms.Order.term(isASC(order))); // add the sort to the request also so the results get sorted as well request.addSort(order.getName(), SortOrder.valueOf(order.getType())); break; case "FIELD": termsBuilder.order(Terms.Order.aggregation(order.getName(), isASC(order))); break; default: throw new SqlParseException(order.getName() + " can not to order"); } } else { request.addSort(order.getName(), SortOrder.valueOf(order.getType())); } } } setLimitFromHint(this.select.getHints()); request.setSearchType(SearchType.DEFAULT); updateRequestWithIndexAndRoutingOptions(select, request); SqlElasticSearchRequestBuilder sqlElasticRequestBuilder = new SqlElasticSearchRequestBuilder(request); return sqlElasticRequestBuilder; }