From ee9beda3981c4b4acb5da85779f659bb27988767 Mon Sep 17 00:00:00 2001 From: kimchy Date: Thu, 24 Feb 2011 00:29:42 +0200 Subject: [PATCH] Search: Add search_type for `count` to return count but still support facets, closes #718. --- .../action/search/SearchType.java | 10 +- .../action/search/TransportSearchAction.java | 10 +- .../type/TransportSearchCountAction.java | 95 +++++++++++++++++++ .../search/type/TransportSearchHelper.java | 2 +- .../index/query/ParsedQuery.java | 3 + .../elasticsearch/search/SearchService.java | 9 +- .../search/count/CountSearchResult.java | 74 +++++++++++++++ .../internal/InternalSearchRequest.java | 16 +++- .../search/internal/SearchContext.java | 10 +- .../search/query/QueryPhase.java | 39 +++++++- .../SingleShardEmbeddedSearchTests.java | 51 ++++------ .../ThreeShardsEmbeddedSearchTests.java | 13 +-- ...dsUnbalancedShardsEmbeddedSearchTests.java | 13 +-- .../search/facet/SimpleFacetsTests.java | 5 +- 14 files changed, 292 insertions(+), 58 deletions(-) create mode 100644 modules/elasticsearch/src/main/java/org/elasticsearch/action/search/type/TransportSearchCountAction.java create mode 100644 modules/elasticsearch/src/main/java/org/elasticsearch/search/count/CountSearchResult.java diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/SearchType.java b/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/SearchType.java index 84a142b7b77..389ed360f1c 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/SearchType.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/SearchType.java @@ -54,7 +54,11 @@ public enum SearchType { * Performs scanning of the results which executes the search without any sorting. * It will automatically start scrolling the result set. */ - SCAN((byte) 4); + SCAN((byte) 4), + /** + * Only counts the results, will still execute facets and the like. + */ + COUNT((byte) 5); /** * The default search type ({@link #QUERY_THEN_FETCH}. @@ -88,6 +92,8 @@ public enum SearchType { return QUERY_AND_FETCH; } else if (id == 4) { return SCAN; + } else if (id == 5) { + return COUNT; } else { throw new ElasticSearchIllegalArgumentException("No search type for [" + id + "]"); } @@ -112,6 +118,8 @@ public enum SearchType { return SearchType.QUERY_AND_FETCH; } else if ("scan".equals(searchType)) { return SearchType.SCAN; + } else if ("count".equals(searchType)) { + return SearchType.COUNT; } else { throw new ElasticSearchIllegalArgumentException("No search type for [" + searchType + "]"); } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java b/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java index 9716eafcac1..547da7b0e27 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/TransportSearchAction.java @@ -53,6 +53,8 @@ public class TransportSearchAction extends BaseAction listener) { // optimize search type for cases where there is only one shard group to search on - if (optimizeSingleShard && searchRequest.searchType() != SCAN) { + if (optimizeSingleShard && searchRequest.searchType() != SCAN && searchRequest.searchType() != COUNT) { try { ClusterState clusterState = clusterService.state(); searchRequest.indices(clusterState.metaData().concreteIndices(searchRequest.indices())); @@ -104,6 +108,8 @@ public class TransportSearchAction extends BaseAction listener) { + new AsyncAction(searchRequest, listener).start(); + } + + private class AsyncAction extends BaseAsyncAction { + + private final Map queryFetchResults = searchCache.obtainQueryResults(); + + + private AsyncAction(SearchRequest request, ActionListener listener) { + super(request, listener); + } + + @Override protected String firstPhaseName() { + return "query"; + } + + @Override protected void sendExecuteFirstPhase(DiscoveryNode node, InternalSearchRequest request, SearchServiceListener listener) { + searchService.sendExecuteQuery(node, request, listener); + } + + @Override protected void processFirstPhaseResult(ShardRouting shard, QuerySearchResult result) { + queryFetchResults.put(result.shardTarget(), result); + } + + @Override protected void moveToSecondPhase() throws Exception { + // no need to sort, since we know we have no hits back + final InternalSearchResponse internalResponse = searchPhaseController.merge(EMPTY_DOCS, queryFetchResults, ImmutableMap.of()); + String scrollId = null; + if (request.scroll() != null) { + scrollId = buildScrollId(request.searchType(), queryFetchResults.values()); + } + listener.onResponse(new SearchResponse(internalResponse, scrollId, expectedSuccessfulOps, successulOps.get(), buildTookInMillis(), buildShardFailures())); + searchCache.releaseQueryResults(queryFetchResults); + } + } + + private static ShardDoc[] EMPTY_DOCS = new ShardDoc[0]; +} \ No newline at end of file diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/type/TransportSearchHelper.java b/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/type/TransportSearchHelper.java index ac7ebd8ca8f..570f13a0f27 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/type/TransportSearchHelper.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/action/search/type/TransportSearchHelper.java @@ -64,7 +64,7 @@ public abstract class TransportSearchHelper { } public static InternalSearchRequest internalSearchRequest(ShardRouting shardRouting, int numberOfShards, SearchRequest request) { - InternalSearchRequest internalRequest = new InternalSearchRequest(shardRouting, numberOfShards); + InternalSearchRequest internalRequest = new InternalSearchRequest(shardRouting, numberOfShards, request.searchType()); internalRequest.source(request.source(), request.sourceOffset(), request.sourceLength()); internalRequest.extraSource(request.extraSource(), request.extraSourceOffset(), request.extraSourceLength()); internalRequest.scroll(request.scroll()); diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/ParsedQuery.java b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/ParsedQuery.java index 321bce400db..8dbd8628a99 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/ParsedQuery.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/index/query/ParsedQuery.java @@ -22,6 +22,7 @@ package org.elasticsearch.index.query; import org.apache.lucene.search.Filter; import org.apache.lucene.search.Query; import org.elasticsearch.common.collect.ImmutableMap; +import org.elasticsearch.common.lucene.search.Queries; import org.elasticsearch.search.internal.ScopePhase; /** @@ -31,6 +32,8 @@ import org.elasticsearch.search.internal.ScopePhase; */ public class ParsedQuery { + public static ParsedQuery MATCH_ALL_PARSED_QUERY = new ParsedQuery(Queries.MATCH_ALL_QUERY, ImmutableMap.of(), new ScopePhase[0]); + private final Query query; private final ImmutableMap namedFilters; diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/search/SearchService.java b/modules/elasticsearch/src/main/java/org/elasticsearch/search/SearchService.java index 0f657a31653..b876e9e45f8 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/search/SearchService.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/search/SearchService.java @@ -21,6 +21,7 @@ package org.elasticsearch.search; import org.apache.lucene.search.TopDocs; import org.elasticsearch.ElasticSearchException; +import org.elasticsearch.action.search.SearchType; import org.elasticsearch.cluster.ClusterService; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Unicode; @@ -219,7 +220,11 @@ public class SearchService extends AbstractLifecycleComponent { try { contextProcessing(context); queryPhase.execute(context); - contextProcessedSuccessfully(context); + if (context.searchType() == SearchType.COUNT) { + freeContext(context.id()); + } else { + contextProcessedSuccessfully(context); + } return context.queryResult(); } catch (RuntimeException e) { freeContext(context); @@ -375,7 +380,7 @@ public class SearchService extends AbstractLifecycleComponent { SearchShardTarget shardTarget = new SearchShardTarget(clusterService.localNode().id(), request.index(), request.shardId()); Engine.Searcher engineSearcher = indexShard.searcher(); - SearchContext context = new SearchContext(idGenerator.incrementAndGet(), shardTarget, request.numberOfShards(), request.timeout(), request.types(), engineSearcher, indexService, scriptService); + SearchContext context = new SearchContext(idGenerator.incrementAndGet(), shardTarget, request.searchType(), request.numberOfShards(), request.timeout(), request.types(), engineSearcher, indexService, scriptService); SearchContext.setCurrent(context); try { context.scroll(request.scroll()); diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/search/count/CountSearchResult.java b/modules/elasticsearch/src/main/java/org/elasticsearch/search/count/CountSearchResult.java new file mode 100644 index 00000000000..10a393c134e --- /dev/null +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/search/count/CountSearchResult.java @@ -0,0 +1,74 @@ +/* + * Licensed to Elastic Search and Shay Banon under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Elastic Search licenses this + * file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.search.count; + +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.io.stream.Streamable; +import org.elasticsearch.search.SearchPhaseResult; +import org.elasticsearch.search.SearchShardTarget; + +import java.io.IOException; + +/** + * The initial scan search result, including the count of hits matching the provided query. + */ +public class CountSearchResult implements Streamable, SearchPhaseResult { + + private long id; + + private long totalHits; + + private SearchShardTarget shardTarget; + + public CountSearchResult() { + } + + public CountSearchResult(long id, long totalHits) { + this.id = id; + this.totalHits = totalHits; + } + + public long id() { + return this.id; + } + + public long totalHits() { + return this.totalHits; + } + + @Override public SearchShardTarget shardTarget() { + return shardTarget; + } + + @Override public void shardTarget(SearchShardTarget shardTarget) { + this.shardTarget = shardTarget; + } + + @Override public void readFrom(StreamInput in) throws IOException { + id = in.readLong(); + totalHits = in.readVLong(); + } + + @Override public void writeTo(StreamOutput out) throws IOException { + out.writeLong(id); + out.writeVLong(totalHits); + } +} \ No newline at end of file diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/InternalSearchRequest.java b/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/InternalSearchRequest.java index 6e317eb84c1..933627c763b 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/InternalSearchRequest.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/InternalSearchRequest.java @@ -19,6 +19,7 @@ package org.elasticsearch.search.internal; +import org.elasticsearch.action.search.SearchType; import org.elasticsearch.cluster.routing.ShardRouting; import org.elasticsearch.common.Bytes; import org.elasticsearch.common.Strings; @@ -61,6 +62,8 @@ public class InternalSearchRequest implements Streamable { private int numberOfShards; + private SearchType searchType; + private Scroll scroll; private TimeValue timeout; @@ -78,14 +81,15 @@ public class InternalSearchRequest implements Streamable { public InternalSearchRequest() { } - public InternalSearchRequest(ShardRouting shardRouting, int numberOfShards) { - this(shardRouting.index(), shardRouting.id(), numberOfShards); + public InternalSearchRequest(ShardRouting shardRouting, int numberOfShards, SearchType searchType) { + this(shardRouting.index(), shardRouting.id(), numberOfShards, searchType); } - public InternalSearchRequest(String index, int shardId, int numberOfShards) { + public InternalSearchRequest(String index, int shardId, int numberOfShards, SearchType searchType) { this.index = index; this.shardId = shardId; this.numberOfShards = numberOfShards; + this.searchType = searchType; } public String index() { @@ -96,6 +100,10 @@ public class InternalSearchRequest implements Streamable { return shardId; } + public SearchType searchType() { + return this.searchType; + } + public int numberOfShards() { return numberOfShards; } @@ -171,6 +179,7 @@ public class InternalSearchRequest implements Streamable { @Override public void readFrom(StreamInput in) throws IOException { index = in.readUTF(); shardId = in.readVInt(); + searchType = SearchType.fromId(in.readByte()); numberOfShards = in.readVInt(); if (in.readBoolean()) { scroll = readScroll(in); @@ -206,6 +215,7 @@ public class InternalSearchRequest implements Streamable { @Override public void writeTo(StreamOutput out) throws IOException { out.writeUTF(index); out.writeVInt(shardId); + out.writeByte(searchType.id()); out.writeVInt(numberOfShards); if (scroll == null) { out.writeBoolean(false); diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/SearchContext.java b/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/SearchContext.java index 1beaf6edf5a..717f656da55 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/SearchContext.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/search/internal/SearchContext.java @@ -23,6 +23,7 @@ import org.apache.lucene.search.Filter; import org.apache.lucene.search.Query; import org.apache.lucene.search.Sort; import org.elasticsearch.ElasticSearchException; +import org.elasticsearch.action.search.SearchType; import org.elasticsearch.common.collect.ImmutableList; import org.elasticsearch.common.collect.Lists; import org.elasticsearch.common.lease.Releasable; @@ -75,6 +76,8 @@ public class SearchContext implements Releasable { private final SearchShardTarget shardTarget; + private final SearchType searchType; + private final int numberOfShards; private final Engine.Searcher engineSearcher; @@ -144,9 +147,10 @@ public class SearchContext implements Releasable { private volatile long lastAccessTime; - public SearchContext(long id, SearchShardTarget shardTarget, int numberOfShards, TimeValue timeout, + public SearchContext(long id, SearchShardTarget shardTarget, SearchType searchType, int numberOfShards, TimeValue timeout, String[] types, Engine.Searcher engineSearcher, IndexService indexService, ScriptService scriptService) { this.id = id; + this.searchType = searchType; this.shardTarget = shardTarget; this.numberOfShards = numberOfShards; this.timeout = timeout; @@ -182,6 +186,10 @@ public class SearchContext implements Releasable { return this.id; } + public SearchType searchType() { + return this.searchType; + } + public SearchShardTarget shardTarget() { return this.shardTarget; } diff --git a/modules/elasticsearch/src/main/java/org/elasticsearch/search/query/QueryPhase.java b/modules/elasticsearch/src/main/java/org/elasticsearch/search/query/QueryPhase.java index 583d1e11a1e..0846cec2dec 100644 --- a/modules/elasticsearch/src/main/java/org/elasticsearch/search/query/QueryPhase.java +++ b/modules/elasticsearch/src/main/java/org/elasticsearch/search/query/QueryPhase.java @@ -21,13 +21,13 @@ package org.elasticsearch.search.query; import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.*; +import org.elasticsearch.action.search.SearchType; import org.elasticsearch.common.collect.ImmutableMap; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.lucene.search.function.BoostScoreFunction; import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery; import org.elasticsearch.index.query.ParsedQuery; import org.elasticsearch.search.SearchParseElement; -import org.elasticsearch.search.SearchParseException; import org.elasticsearch.search.SearchPhase; import org.elasticsearch.search.facet.FacetPhase; import org.elasticsearch.search.internal.ContextIndexSearcher; @@ -73,7 +73,7 @@ public class QueryPhase implements SearchPhase { @Override public void preProcess(SearchContext context) { if (context.query() == null) { - throw new SearchParseException(context, "No query specified in search request"); + context.parsedQuery(ParsedQuery.MATCH_ALL_PARSED_QUERY); } if (context.queryBoost() != 1.0f) { context.parsedQuery(new ParsedQuery(new FunctionScoreQuery(context.query(), new BoostScoreFunction(context.queryBoost())), context.parsedQuery())); @@ -187,7 +187,15 @@ public class QueryPhase implements SearchPhase { } } - if (searchContext.scanning()) { + if (searchContext.searchType() == SearchType.COUNT) { + CountCollector countCollector = new CountCollector(); + try { + searchContext.searcher().search(query, countCollector); + } catch (ScanCollector.StopCollectingException e) { + // all is well + } + topDocs = countCollector.topDocs(); + } else if (searchContext.scanning()) { ScanCollector scanCollector = new ScanCollector(searchContext.from(), searchContext.size()); try { searchContext.searcher().search(query, scanCollector); @@ -210,6 +218,31 @@ public class QueryPhase implements SearchPhase { facetPhase.execute(searchContext); } + static class CountCollector extends Collector { + + private int totalHits = 0; + + @Override public void setScorer(Scorer scorer) throws IOException { + } + + @Override public void collect(int doc) throws IOException { + totalHits++; + } + + @Override public void setNextReader(IndexReader reader, int docBase) throws IOException { + } + + @Override public boolean acceptsDocsOutOfOrder() { + return true; + } + + public TopDocs topDocs() { + return new TopDocs(totalHits, EMPTY, 0); + } + + private static ScoreDoc[] EMPTY = new ScoreDoc[0]; + } + static class ScanCollector extends Collector { private final int from; diff --git a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/embedded/SingleShardEmbeddedSearchTests.java b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/embedded/SingleShardEmbeddedSearchTests.java index a40fd79cb22..d5c36c6bdc2 100644 --- a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/embedded/SingleShardEmbeddedSearchTests.java +++ b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/embedded/SingleShardEmbeddedSearchTests.java @@ -19,6 +19,7 @@ package org.elasticsearch.test.integration.search.embedded; +import org.elasticsearch.action.search.SearchType; import org.elasticsearch.client.Client; import org.elasticsearch.common.collect.Maps; import org.elasticsearch.common.collect.Sets; @@ -31,8 +32,6 @@ import org.elasticsearch.search.controller.SearchPhaseController; import org.elasticsearch.search.controller.ShardDoc; import org.elasticsearch.search.dfs.AggregatedDfs; import org.elasticsearch.search.dfs.DfsSearchResult; -import org.elasticsearch.search.facet.FacetBuilders; -import org.elasticsearch.search.facet.query.QueryFacet; import org.elasticsearch.search.fetch.FetchSearchRequest; import org.elasticsearch.search.fetch.FetchSearchResult; import org.elasticsearch.search.fetch.QueryFetchSearchResult; @@ -103,7 +102,7 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { } @Test public void testDirectDfs() throws Exception { - DfsSearchResult dfsResult = searchService.executeDfsPhase(searchRequest(searchSource().query(termQuery("name", "test1")))); + DfsSearchResult dfsResult = searchService.executeDfsPhase(searchRequest(searchSource().query(termQuery("name", "test1")), SearchType.DFS_QUERY_THEN_FETCH)); assertThat(dfsResult.terms().length, equalTo(1)); assertThat(dfsResult.freqs().length, equalTo(1)); @@ -113,12 +112,12 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { } @Test public void testDirectQuery() throws Exception { - QuerySearchResult queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(termQuery("name", "test1")))); + QuerySearchResult queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(termQuery("name", "test1")), SearchType.QUERY_THEN_FETCH)); assertThat(queryResult.topDocs().totalHits, equalTo(1)); } @Test public void testDirectFetch() throws Exception { - QueryFetchSearchResult queryFetchResult = searchService.executeFetchPhase(searchRequest(searchSource().query(termQuery("name", "test1")))); + QueryFetchSearchResult queryFetchResult = searchService.executeFetchPhase(searchRequest(searchSource().query(termQuery("name", "test1")), SearchType.QUERY_AND_FETCH)); assertThat(queryFetchResult.queryResult().topDocs().totalHits, equalTo(1)); assertThat(queryFetchResult.fetchResult().hits().hits().length, equalTo(1)); assertThat(queryFetchResult.fetchResult().hits().hits()[0].sourceAsString(), equalTo(source("1", "test1", 1))); @@ -128,7 +127,7 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { @Test public void testScan() throws Exception { Scroll scroll = new Scroll(TimeValue.timeValueMillis(500)); - ScanSearchResult scanResult = searchService.executeScan(searchRequest(searchSource().query(matchAllQuery()).size(2)).scroll(scroll)); + ScanSearchResult scanResult = searchService.executeScan(searchRequest(searchSource().query(matchAllQuery()).size(2), SearchType.SCAN).scroll(scroll)); assertThat(scanResult.totalHits(), equalTo(5l)); Set idsLoaded = Sets.newHashSet(); @@ -165,7 +164,7 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { } @Test public void testQueryThenFetch() throws Exception { - QuerySearchResult queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(termQuery("name", "test1")))); + QuerySearchResult queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(termQuery("name", "test1")), SearchType.QUERY_THEN_FETCH)); assertThat(queryResult.topDocs().totalHits, equalTo(1)); ShardDoc[] sortedShardList = searchPhaseController.sortDocs(newArrayList(queryResult)); @@ -180,7 +179,7 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { } @Test public void testQueryThenFetchIterateWithFrom() throws Exception { - QuerySearchResult queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(matchAllQuery()).from(0).size(2))); + QuerySearchResult queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(matchAllQuery()).from(0).size(2), SearchType.QUERY_THEN_FETCH)); assertThat(queryResult.topDocs().totalHits, equalTo(5)); Set idsLoaded = Sets.newHashSet(); @@ -197,7 +196,7 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { } // iterate to the next 2 - queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(matchAllQuery()).from(2).size(2))); + queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(matchAllQuery()).from(2).size(2), SearchType.QUERY_THEN_FETCH)); assertThat(queryResult.topDocs().totalHits, equalTo(5)); sortedShardList = searchPhaseController.sortDocs(newArrayList(queryResult)); @@ -212,7 +211,7 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { } // iterate to the next 2 - queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(matchAllQuery()).from(4).size(2))); + queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(matchAllQuery()).from(4).size(2), SearchType.QUERY_THEN_FETCH)); assertThat(queryResult.topDocs().totalHits, equalTo(5)); sortedShardList = searchPhaseController.sortDocs(newArrayList(queryResult)); @@ -232,7 +231,7 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { } @Test public void testQueryThenFetchIterateWithFromSortedByAge() throws Exception { - QuerySearchResult queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(matchAllQuery()).from(0).size(2).sort("age", SortOrder.DESC))); + QuerySearchResult queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(matchAllQuery()).from(0).size(2).sort("age", SortOrder.DESC), SearchType.QUERY_THEN_FETCH)); assertThat(queryResult.topDocs().totalHits, equalTo(5)); Set idsLoaded = Sets.newHashSet(); @@ -249,7 +248,7 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { } // iterate to the next 2 - queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(matchAllQuery()).from(2).size(2).sort("age", SortOrder.DESC))); + queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(matchAllQuery()).from(2).size(2).sort("age", SortOrder.DESC), SearchType.QUERY_THEN_FETCH)); assertThat(queryResult.topDocs().totalHits, equalTo(5)); sortedShardList = searchPhaseController.sortDocs(newArrayList(queryResult)); @@ -264,7 +263,7 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { } // iterate to the next 2 - queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(matchAllQuery()).from(4).size(2).sort("age", SortOrder.DESC))); + queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(matchAllQuery()).from(4).size(2).sort("age", SortOrder.DESC), SearchType.QUERY_THEN_FETCH)); assertThat(queryResult.topDocs().totalHits, equalTo(5)); sortedShardList = searchPhaseController.sortDocs(newArrayList(queryResult)); @@ -284,7 +283,7 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { } @Test public void testQueryAndFetch() throws Exception { - QueryFetchSearchResult result = searchService.executeFetchPhase(searchRequest(searchSource().query(termQuery("name", "test1")))); + QueryFetchSearchResult result = searchService.executeFetchPhase(searchRequest(searchSource().query(termQuery("name", "test1")), SearchType.QUERY_AND_FETCH)); FetchSearchResult fetchResult = result.fetchResult(); assertThat(fetchResult.hits().hits()[0].sourceAsString(), equalTo(source("1", "test1", 1))); assertThat(fetchResult.hits().hits()[0].id(), equalTo("1")); @@ -292,7 +291,7 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { } @Test public void testQueryAndFetchIterateWithFrom() throws Exception { - QueryFetchSearchResult result = searchService.executeFetchPhase(searchRequest(searchSource().query(matchAllQuery()).from(0).size(2).sort("age", SortOrder.DESC))); + QueryFetchSearchResult result = searchService.executeFetchPhase(searchRequest(searchSource().query(matchAllQuery()).from(0).size(2).sort("age", SortOrder.DESC), SearchType.QUERY_AND_FETCH)); assertThat(result.queryResult().topDocs().totalHits, equalTo(5)); Set idsLoaded = Sets.newHashSet(); @@ -307,7 +306,7 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { } // iterate to the next 2 - result = searchService.executeFetchPhase(searchRequest(searchSource().query(matchAllQuery()).from(2).size(2).sort("age", SortOrder.DESC))); + result = searchService.executeFetchPhase(searchRequest(searchSource().query(matchAllQuery()).from(2).size(2).sort("age", SortOrder.DESC), SearchType.QUERY_AND_FETCH)); assertThat(result.queryResult().topDocs().totalHits, equalTo(5)); sortedShardList = searchPhaseController.sortDocs(newArrayList(result)); @@ -318,7 +317,7 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { for (SearchHit hit : searchResponse.hits()) { idsLoaded.add(hit.id()); } - result = searchService.executeFetchPhase(searchRequest(searchSource().query(matchAllQuery()).from(4).size(2).sort("age", SortOrder.DESC))); + result = searchService.executeFetchPhase(searchRequest(searchSource().query(matchAllQuery()).from(4).size(2).sort("age", SortOrder.DESC), SearchType.QUERY_AND_FETCH)); assertThat(result.queryResult().topDocs().totalHits, equalTo(5)); sortedShardList = searchPhaseController.sortDocs(newArrayList(result)); @@ -336,7 +335,7 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { } @Test public void testDfsQueryThenFetch() throws Exception { - DfsSearchResult dfsResult = searchService.executeDfsPhase(searchRequest(searchSource().query(termQuery("name", "test1")))); + DfsSearchResult dfsResult = searchService.executeDfsPhase(searchRequest(searchSource().query(termQuery("name", "test1")), SearchType.DFS_QUERY_THEN_FETCH)); AggregatedDfs dfs = searchPhaseController.aggregateDfs(newArrayList(dfsResult)); QuerySearchResult queryResult = searchService.executeQueryPhase(new QuerySearchRequest(dfsResult.id(), dfs)); @@ -353,18 +352,8 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { assertThat(fetchResult.hits().hits()[0].type(), equalTo("type1")); } - @Test public void testSimpleQueryFacets() throws Exception { - QuerySearchResult queryResult = searchService.executeQueryPhase(searchRequest( - searchSource().query(wildcardQuery("name", "te*")) - .facet(FacetBuilders.queryFacet("age1", termQuery("age", 1))) - .facet(FacetBuilders.queryFacet("age2", termQuery("age", 2))) - )); - assertThat(queryResult.facets().facet(QueryFacet.class, "age2").count(), equalTo(1l)); - assertThat(queryResult.facets().facet(QueryFacet.class, "age1").count(), equalTo(1l)); - } - @Test public void testQueryFetchKeepAliveTimeout() throws Exception { - QuerySearchResult queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(termQuery("name", "test1"))).scroll(new Scroll(TimeValue.timeValueMillis(10)))); + QuerySearchResult queryResult = searchService.executeQueryPhase(searchRequest(searchSource().query(termQuery("name", "test1")), SearchType.QUERY_THEN_FETCH).scroll(new Scroll(TimeValue.timeValueMillis(10)))); assertThat(queryResult.topDocs().totalHits, equalTo(1)); ShardDoc[] sortedShardList = searchPhaseController.sortDocs(newArrayList(queryResult)); @@ -384,8 +373,8 @@ public class SingleShardEmbeddedSearchTests extends AbstractNodesTests { } - private InternalSearchRequest searchRequest(SearchSourceBuilder builder) { - return new InternalSearchRequest("test", 0, 1).source(builder.buildAsBytes()); + private InternalSearchRequest searchRequest(SearchSourceBuilder builder, SearchType searchType) { + return new InternalSearchRequest("test", 0, 1, searchType).source(builder.buildAsBytes()); } private void index(String id, String nameValue, int age) { diff --git a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/embedded/ThreeShardsEmbeddedSearchTests.java b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/embedded/ThreeShardsEmbeddedSearchTests.java index 3e024df31c0..9131a19347a 100644 --- a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/embedded/ThreeShardsEmbeddedSearchTests.java +++ b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/embedded/ThreeShardsEmbeddedSearchTests.java @@ -19,6 +19,7 @@ package org.elasticsearch.test.integration.search.embedded; +import org.elasticsearch.action.search.SearchType; import org.elasticsearch.client.Client; import org.elasticsearch.client.Requests; import org.elasticsearch.cluster.ClusterService; @@ -115,7 +116,7 @@ public class ThreeShardsEmbeddedSearchTests extends AbstractNodesTests { List dfsResults = newArrayList(); for (ShardIterator shardIt : clusterService.operationRouting().searchShards(clusterService.state(), new String[]{"test"}, null, null)) { for (ShardRouting shardRouting : shardIt) { - InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder) + InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder, SearchType.QUERY_THEN_FETCH) .scroll(new Scroll(new TimeValue(10, TimeUnit.MINUTES))); dfsResults.add(nodeToSearchService.get(shardRouting.currentNodeId()).executeDfsPhase(searchRequest)); } @@ -183,7 +184,7 @@ public class ThreeShardsEmbeddedSearchTests extends AbstractNodesTests { List dfsResults = newArrayList(); for (ShardIterator shardIt : clusterService.operationRouting().searchShards(clusterService.state(), new String[]{"test"}, null, null)) { for (ShardRouting shardRouting : shardIt) { - InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder) + InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder, SearchType.QUERY_THEN_FETCH) .scroll(new Scroll(new TimeValue(10, TimeUnit.MINUTES))); dfsResults.add(nodeToSearchService.get(shardRouting.currentNodeId()).executeDfsPhase(searchRequest)); } @@ -277,7 +278,7 @@ public class ThreeShardsEmbeddedSearchTests extends AbstractNodesTests { Map queryFetchResults = newHashMap(); for (ShardIterator shardIt : clusterService.operationRouting().searchShards(clusterService.state(), new String[]{"test"}, null, null)) { for (ShardRouting shardRouting : shardIt) { - InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder) + InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder, SearchType.QUERY_AND_FETCH) .scroll(new Scroll(new TimeValue(10, TimeUnit.MINUTES))); QueryFetchSearchResult queryFetchResult = nodeToSearchService.get(shardRouting.currentNodeId()).executeFetchPhase(searchRequest); queryFetchResults.put(queryFetchResult.shardTarget(), queryFetchResult); @@ -329,7 +330,7 @@ public class ThreeShardsEmbeddedSearchTests extends AbstractNodesTests { Map queryResults = newHashMap(); for (ShardIterator shardIt : clusterService.operationRouting().searchShards(clusterService.state(), new String[]{"test"}, null, null)) { for (ShardRouting shardRouting : shardIt) { - InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder) + InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder, SearchType.QUERY_THEN_FETCH) .scroll(new Scroll(new TimeValue(10, TimeUnit.MINUTES))); QuerySearchResult queryResult = nodeToSearchService.get(shardRouting.currentNodeId()).executeQueryPhase(searchRequest); queryResults.put(queryResult.shardTarget(), queryResult); @@ -358,8 +359,8 @@ public class ThreeShardsEmbeddedSearchTests extends AbstractNodesTests { testSimpleFacets(); } - private InternalSearchRequest searchRequest(ShardRouting shardRouting, SearchSourceBuilder builder) { - return new InternalSearchRequest(shardRouting, 3).source(builder.buildAsBytes()); + private InternalSearchRequest searchRequest(ShardRouting shardRouting, SearchSourceBuilder builder, SearchType searchType) { + return new InternalSearchRequest(shardRouting, 3, searchType).source(builder.buildAsBytes()); } private void index(Client client, String id, String nameValue, int age) { diff --git a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/embedded/ThreeShardsUnbalancedShardsEmbeddedSearchTests.java b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/embedded/ThreeShardsUnbalancedShardsEmbeddedSearchTests.java index 0a3b7952173..e1d9ec65c43 100644 --- a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/embedded/ThreeShardsUnbalancedShardsEmbeddedSearchTests.java +++ b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/embedded/ThreeShardsUnbalancedShardsEmbeddedSearchTests.java @@ -19,6 +19,7 @@ package org.elasticsearch.test.integration.search.embedded; +import org.elasticsearch.action.search.SearchType; import org.elasticsearch.client.Client; import org.elasticsearch.client.Requests; import org.elasticsearch.cluster.ClusterService; @@ -123,7 +124,7 @@ public class ThreeShardsUnbalancedShardsEmbeddedSearchTests extends AbstractNode List dfsResults = newArrayList(); for (ShardIterator shardIt : clusterService.operationRouting().searchShards(clusterService.state(), new String[]{"test"}, null, null)) { for (ShardRouting shardRouting : shardIt) { - InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder) + InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder, SearchType.DFS_QUERY_THEN_FETCH) .scroll(new Scroll(new TimeValue(10, TimeUnit.MINUTES))); dfsResults.add(nodeToSearchService.get(shardRouting.currentNodeId()).executeDfsPhase(searchRequest)); } @@ -190,7 +191,7 @@ public class ThreeShardsUnbalancedShardsEmbeddedSearchTests extends AbstractNode List dfsResults = newArrayList(); for (ShardIterator shardIt : clusterService.operationRouting().searchShards(clusterService.state(), new String[]{"test"}, null, null)) { for (ShardRouting shardRouting : shardIt) { - InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder) + InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder, SearchType.DFS_QUERY_THEN_FETCH) .scroll(new Scroll(new TimeValue(10, TimeUnit.MINUTES))); dfsResults.add(nodeToSearchService.get(shardRouting.currentNodeId()).executeDfsPhase(searchRequest)); } @@ -280,7 +281,7 @@ public class ThreeShardsUnbalancedShardsEmbeddedSearchTests extends AbstractNode List dfsResults = newArrayList(); for (ShardIterator shardIt : clusterService.operationRouting().searchShards(clusterService.state(), new String[]{"test"}, null, null)) { for (ShardRouting shardRouting : shardIt) { - InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder) + InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder, SearchType.QUERY_AND_FETCH) .scroll(new Scroll(new TimeValue(10, TimeUnit.MINUTES))); dfsResults.add(nodeToSearchService.get(shardRouting.currentNodeId()).executeDfsPhase(searchRequest)); } @@ -335,7 +336,7 @@ public class ThreeShardsUnbalancedShardsEmbeddedSearchTests extends AbstractNode Map queryResults = newHashMap(); for (ShardIterator shardIt : clusterService.operationRouting().searchShards(clusterService.state(), new String[]{"test"}, null, null)) { for (ShardRouting shardRouting : shardIt) { - InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder) + InternalSearchRequest searchRequest = searchRequest(shardRouting, sourceBuilder, SearchType.QUERY_THEN_FETCH) .scroll(new Scroll(new TimeValue(10, TimeUnit.MINUTES))); QuerySearchResult queryResult = nodeToSearchService.get(shardRouting.currentNodeId()).executeQueryPhase(searchRequest); queryResults.put(queryResult.shardTarget(), queryResult); @@ -364,8 +365,8 @@ public class ThreeShardsUnbalancedShardsEmbeddedSearchTests extends AbstractNode testSimpleFacets(); } - private static InternalSearchRequest searchRequest(ShardRouting shardRouting, SearchSourceBuilder builder) { - return new InternalSearchRequest(shardRouting, 3).source(builder.buildAsBytes()); + private static InternalSearchRequest searchRequest(ShardRouting shardRouting, SearchSourceBuilder builder, SearchType searchType) { + return new InternalSearchRequest(shardRouting, 3, searchType).source(builder.buildAsBytes()); } private void index(Client client, String id, String nameValue, int age) { diff --git a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/facet/SimpleFacetsTests.java b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/facet/SimpleFacetsTests.java index b1dfd273255..5dea2161eb4 100644 --- a/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/facet/SimpleFacetsTests.java +++ b/modules/test/integration/src/test/java/org/elasticsearch/test/integration/search/facet/SimpleFacetsTests.java @@ -105,7 +105,7 @@ public class SimpleFacetsTests extends AbstractNodesTests { client.admin().indices().prepareRefresh().execute().actionGet(); SearchResponse searchResponse = client.prepareSearch() - .setQuery(matchAllQuery()) + .setSearchType(SearchType.COUNT) .setFacets(XContentFactory.jsonBuilder().startObject() .startObject("facet1") .startObject("terms") @@ -115,7 +115,8 @@ public class SimpleFacetsTests extends AbstractNodesTests { .endObject().copiedBytes()) .execute().actionGet(); - assertThat(searchResponse.hits().hits().length, equalTo(2)); + assertThat(searchResponse.hits().totalHits(), equalTo(2l)); + assertThat(searchResponse.hits().hits().length, equalTo(0)); TermsFacet facet = searchResponse.facets().facet("facet1"); assertThat(facet.name(), equalTo("facet1")); assertThat(facet.entries().size(), equalTo(2));