Search: Add search_type for `count` to return count but still support facets, closes #718.

This commit is contained in:
kimchy 2011-02-24 00:29:42 +02:00
parent f7100c0698
commit ee9beda398
14 changed files with 292 additions and 58 deletions

View File

@ -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 + "]");
}

View File

@ -53,6 +53,8 @@ public class TransportSearchAction extends BaseAction<SearchRequest, SearchRespo
private final TransportSearchScanAction scanAction;
private final TransportSearchCountAction countAction;
private final boolean optimizeSingleShard;
@Inject public TransportSearchAction(Settings settings, ThreadPool threadPool,
@ -61,7 +63,8 @@ public class TransportSearchAction extends BaseAction<SearchRequest, SearchRespo
TransportSearchQueryThenFetchAction queryThenFetchAction,
TransportSearchDfsQueryAndFetchAction dfsQueryAndFetchAction,
TransportSearchQueryAndFetchAction queryAndFetchAction,
TransportSearchScanAction scanAction) {
TransportSearchScanAction scanAction,
TransportSearchCountAction countAction) {
super(settings, threadPool);
this.clusterService = clusterService;
this.dfsQueryThenFetchAction = dfsQueryThenFetchAction;
@ -69,6 +72,7 @@ public class TransportSearchAction extends BaseAction<SearchRequest, SearchRespo
this.dfsQueryAndFetchAction = dfsQueryAndFetchAction;
this.queryAndFetchAction = queryAndFetchAction;
this.scanAction = scanAction;
this.countAction = countAction;
this.optimizeSingleShard = componentSettings.getAsBoolean("optimize_single_shard", true);
@ -77,7 +81,7 @@ public class TransportSearchAction extends BaseAction<SearchRequest, SearchRespo
@Override protected void doExecute(SearchRequest searchRequest, ActionListener<SearchResponse> 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<SearchRequest, SearchRespo
queryAndFetchAction.execute(searchRequest, listener);
} else if (searchRequest.searchType() == SearchType.SCAN) {
scanAction.execute(searchRequest, listener);
} else if (searchRequest.searchType() == SearchType.COUNT) {
countAction.execute(searchRequest, listener);
}
}

View File

@ -0,0 +1,95 @@
/*
* 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.action.search.type;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.routing.ShardRouting;
import org.elasticsearch.common.collect.ImmutableMap;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.search.SearchShardTarget;
import org.elasticsearch.search.action.SearchServiceListener;
import org.elasticsearch.search.action.SearchServiceTransportAction;
import org.elasticsearch.search.controller.SearchPhaseController;
import org.elasticsearch.search.controller.ShardDoc;
import org.elasticsearch.search.fetch.FetchSearchResultProvider;
import org.elasticsearch.search.internal.InternalSearchRequest;
import org.elasticsearch.search.internal.InternalSearchResponse;
import org.elasticsearch.search.query.QuerySearchResult;
import org.elasticsearch.search.query.QuerySearchResultProvider;
import org.elasticsearch.threadpool.ThreadPool;
import java.util.Map;
import static org.elasticsearch.action.search.type.TransportSearchHelper.*;
/**
* @author kimchy (shay.banon)
*/
public class TransportSearchCountAction extends TransportSearchTypeAction {
@Inject public TransportSearchCountAction(Settings settings, ThreadPool threadPool, ClusterService clusterService,
TransportSearchCache transportSearchCache, SearchServiceTransportAction searchService, SearchPhaseController searchPhaseController) {
super(settings, threadPool, clusterService, transportSearchCache, searchService, searchPhaseController);
}
@Override protected void doExecute(SearchRequest searchRequest, ActionListener<SearchResponse> listener) {
new AsyncAction(searchRequest, listener).start();
}
private class AsyncAction extends BaseAsyncAction<QuerySearchResult> {
private final Map<SearchShardTarget, QuerySearchResultProvider> queryFetchResults = searchCache.obtainQueryResults();
private AsyncAction(SearchRequest request, ActionListener<SearchResponse> listener) {
super(request, listener);
}
@Override protected String firstPhaseName() {
return "query";
}
@Override protected void sendExecuteFirstPhase(DiscoveryNode node, InternalSearchRequest request, SearchServiceListener<QuerySearchResult> 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.<SearchShardTarget, FetchSearchResultProvider>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];
}

View File

@ -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());

View File

@ -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.<String, Filter>of(), new ScopePhase[0]);
private final Query query;
private final ImmutableMap<String, Filter> namedFilters;

View File

@ -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<SearchService> {
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<SearchService> {
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());

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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<String> 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<String> 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<String> 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<String> 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) {

View File

@ -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<DfsSearchResult> 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<DfsSearchResult> 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<SearchShardTarget, QueryFetchSearchResult> 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<SearchShardTarget, QuerySearchResultProvider> 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) {

View File

@ -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<DfsSearchResult> 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<DfsSearchResult> 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<DfsSearchResult> 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<SearchShardTarget, QuerySearchResultProvider> 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) {

View File

@ -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));