public HistogramResult histogram( String query, Indexer.DateHistogramInterval interval, String filter, TimeRange range) throws IndexHelper.InvalidRangeFormatException { DateHistogramFacetBuilder fb = FacetBuilders.dateHistogramFacet("histogram") .field("timestamp") .interval(interval.toString().toLowerCase()); fb.facetFilter(standardFilters(range, filter)); QueryStringQueryBuilder qs = queryString(query); qs.allowLeadingWildcard(server.getConfiguration().isAllowLeadingWildcardSearches()); SearchRequestBuilder srb = c.prepareSearch(); srb.setIndices(IndexHelper.determineAffectedIndices(server, range).toArray(new String[] {})); srb.setQuery(qs); srb.addFacet(fb); final SearchRequest request = srb.request(); SearchResponse r = c.search(request).actionGet(); return new DateHistogramResult( (DateHistogramFacet) r.getFacets().facet("histogram"), query, request.source(), interval, r.getTook()); }
@Override public SearchRequestBuilder initRequestBuilder(SearchRequestBuilder srb) { // the dateFilter should not apply to the date facets! dateFilter = null; srb = super.initRequestBuilder(srb); if (dateFilter != null) srb.setFilter(dateFilter); if (isDateFacets()) { // too much work to convert the generic case with all the date math // so cheat for our case: String name = ElasticTweetSearch.DATE_FACET; RangeFacetBuilder rfb = FacetBuilders.rangeFacet(name).field(ElasticTweetSearch.DATE); MyDate date = new MyDate(); // latest rfb.addUnboundedTo(Helper.toLocalDateTime(date.clone().minusHours(8).castToHour().toDate())); // first day rfb.addUnboundedTo(Helper.toLocalDateTime(date.castToDay().toDate())); for (int i = 0; i < 7; i++) { // 'from' must be smaller than 'to'! Date oldDate = date.toDate(); rfb.addRange( Helper.toLocalDateTime(date.minusDays(1).toDate()), Helper.toLocalDateTime(oldDate)); } // oldest rfb.addUnboundedFrom(Helper.toLocalDateTime(date.toDate())); srb.addFacet(rfb); } return srb; }
@Override public AbstractFacetBuilder fromFacetField(String ff, int limit) { AbstractFacetBuilder facetBuilder; if (ff.equals(ElasticTweetSearch.FIRST_URL_TITLE) || ff.equals(ElasticTweetSearch.TAG)) { // hmmh no real differences ... strange facetBuilder = FacetBuilders.termsStats(ff) .keyField(ff) .valueScript("doc.score") .order(ComparatorType.TOTAL) .size(limit); // fb = // FacetBuilders.termsStats(ff).keyField(ff).valueScript("doc.relevance.value").order(ComparatorType.TOTAL);//.size(15); // fb = // FacetBuilders.termsStats(ff).keyField(ff).valueScript("doc.relevance.value").order(ComparatorType.COUNT).size(15); } else facetBuilder = super.fromFacetField(ff, limit); if (dateFilter != null) facetBuilder.facetFilter(dateFilter); return facetBuilder; }
@Test public void testMultiMatchQuery() throws Exception { try { client.admin().indices().prepareDelete("test").execute().actionGet(); } catch (Exception e) { // ignore } client .admin() .indices() .prepareCreate("test") .setSettings(ImmutableSettings.settingsBuilder().put("number_of_shards", 1)) .execute() .actionGet(); client .prepareIndex("test", "type1", "1") .setSource("field1", "value1", "field2", "value4", "field3", "value3") .execute() .actionGet(); client .prepareIndex("test", "type1", "2") .setSource("field1", "value2", "field2", "value5", "field3", "value2") .execute() .actionGet(); client .prepareIndex("test", "type1", "3") .setSource("field1", "value3", "field2", "value6", "field3", "value1") .execute() .actionGet(); client.admin().indices().prepareRefresh("test").execute().actionGet(); MultiMatchQueryBuilder builder = QueryBuilders.multiMatchQuery("value1 value2 value4", "field1", "field2"); SearchResponse searchResponse = client .prepareSearch() .setQuery(builder) .addFacet(FacetBuilders.termsFacet("field1").field("field1")) .execute() .actionGet(); assertThat(searchResponse.hits().totalHits(), equalTo(2l)); assertThat("1", equalTo(searchResponse.hits().getAt(0).id())); assertThat("2", equalTo(searchResponse.hits().getAt(1).id())); builder.useDisMax(false); searchResponse = client.prepareSearch().setQuery(builder).execute().actionGet(); assertThat(searchResponse.hits().totalHits(), equalTo(2l)); assertThat("1", equalTo(searchResponse.hits().getAt(0).id())); assertThat("2", equalTo(searchResponse.hits().getAt(1).id())); client.admin().indices().prepareRefresh("test").execute().actionGet(); builder = QueryBuilders.multiMatchQuery("value1", "field1", "field2") .operator( MatchQueryBuilder.Operator .AND); // Operator only applies on terms inside a field! Fields are always OR-ed // together. searchResponse = client.prepareSearch().setQuery(builder).execute().actionGet(); assertThat(searchResponse.hits().totalHits(), equalTo(1l)); assertThat("1", equalTo(searchResponse.hits().getAt(0).id())); client.admin().indices().prepareRefresh("test").execute().actionGet(); builder = QueryBuilders.multiMatchQuery("value1", "field1", "field3^1.5") .operator( MatchQueryBuilder.Operator .AND); // Operator only applies on terms inside a field! Fields are always OR-ed // together. searchResponse = client.prepareSearch().setQuery(builder).execute().actionGet(); assertThat(searchResponse.hits().totalHits(), equalTo(2l)); assertThat("3", equalTo(searchResponse.hits().getAt(0).id())); assertThat("1", equalTo(searchResponse.hits().getAt(1).id())); client.admin().indices().prepareRefresh("test").execute().actionGet(); builder = QueryBuilders.multiMatchQuery("value1") .field("field1") .field("field3", 1.5f) .operator( MatchQueryBuilder.Operator .AND); // Operator only applies on terms inside a field! Fields are always OR-ed // together. searchResponse = client.prepareSearch().setQuery(builder).execute().actionGet(); assertThat(searchResponse.hits().totalHits(), equalTo(2l)); assertThat("3", equalTo(searchResponse.hits().getAt(0).id())); assertThat("1", equalTo(searchResponse.hits().getAt(1).id())); // Test lenient client .prepareIndex("test", "type1", "3") .setSource("field1", "value7", "field2", "value8", "field4", 5) .execute() .actionGet(); client.admin().indices().prepareRefresh("test").execute().actionGet(); builder = QueryBuilders.multiMatchQuery("value1", "field1", "field2", "field4"); try { client.prepareSearch().setQuery(builder).execute().actionGet(); fail("Exception expected"); } catch (SearchPhaseExecutionException e) { assertThat(e.shardFailures()[0].status(), equalTo(RestStatus.BAD_REQUEST)); } builder.lenient(true); searchResponse = client.prepareSearch().setQuery(builder).execute().actionGet(); assertThat(searchResponse.hits().totalHits(), equalTo(1l)); assertThat("1", equalTo(searchResponse.hits().getAt(0).id())); }
@Test // Just test the integration with facets and aggregations, not the facet and aggregation // functionality! public void testFacetsAndAggregations() throws Exception { client().admin().indices().prepareCreate("test").execute().actionGet(); ensureGreen(); int numQueries = atLeast(250); int numUniqueQueries = between(1, numQueries / 2); String[] values = new String[numUniqueQueries]; for (int i = 0; i < values.length; i++) { values[i] = "value" + i; } int[] expectedCount = new int[numUniqueQueries]; logger.info("--> registering {} queries", numQueries); for (int i = 0; i < numQueries; i++) { String value = values[i % numUniqueQueries]; expectedCount[i % numUniqueQueries]++; QueryBuilder queryBuilder = matchQuery("field1", value); client() .prepareIndex("test", PercolatorService.TYPE_NAME, Integer.toString(i)) .setSource( jsonBuilder() .startObject() .field("query", queryBuilder) .field("field2", "b") .endObject()) .execute() .actionGet(); } client().admin().indices().prepareRefresh("test").execute().actionGet(); for (int i = 0; i < numQueries; i++) { String value = values[i % numUniqueQueries]; PercolateRequestBuilder percolateRequestBuilder = client() .preparePercolate() .setIndices("test") .setDocumentType("type") .setPercolateDoc( docBuilder() .setDoc(jsonBuilder().startObject().field("field1", value).endObject())); boolean useAggs = randomBoolean(); if (useAggs) { percolateRequestBuilder.addAggregation(AggregationBuilders.terms("a").field("field2")); } else { percolateRequestBuilder.addFacet(FacetBuilders.termsFacet("a").field("field2")); } if (randomBoolean()) { percolateRequestBuilder.setPercolateQuery(matchAllQuery()); } if (randomBoolean()) { percolateRequestBuilder.setScore(true); } else { percolateRequestBuilder.setSortByScore(true).setSize(numQueries); } boolean countOnly = randomBoolean(); if (countOnly) { percolateRequestBuilder.setOnlyCount(countOnly); } PercolateResponse response = percolateRequestBuilder.execute().actionGet(); assertMatchCount(response, expectedCount[i % numUniqueQueries]); if (!countOnly) { assertThat(response.getMatches(), arrayWithSize(expectedCount[i % numUniqueQueries])); } if (useAggs) { List<Aggregation> aggregations = response.getAggregations().asList(); assertThat(aggregations.size(), equalTo(1)); assertThat(aggregations.get(0).getName(), equalTo("a")); List<Terms.Bucket> buckets = new ArrayList<Terms.Bucket>(((Terms) aggregations.get(0)).buckets()); assertThat(buckets.size(), equalTo(1)); assertThat(buckets.get(0).getKey().string(), equalTo("b")); assertThat(buckets.get(0).getDocCount(), equalTo((long) expectedCount[i % values.length])); } else { assertThat(response.getFacets().facets().size(), equalTo(1)); assertThat(response.getFacets().facets().get(0).getName(), equalTo("a")); assertThat( ((TermsFacet) response.getFacets().facets().get(0)).getEntries().size(), equalTo(1)); assertThat( ((TermsFacet) response.getFacets().facets().get(0)).getEntries().get(0).getCount(), equalTo(expectedCount[i % values.length])); assertThat( ((TermsFacet) response.getFacets().facets().get(0)) .getEntries() .get(0) .getTerm() .string(), equalTo("b")); } } }