aboutsummaryrefslogtreecommitdiffstats
path: root/container-search/src/main/java/com/yahoo
diff options
context:
space:
mode:
Diffstat (limited to 'container-search/src/main/java/com/yahoo')
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java211
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/BoolField.java1
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/ClusterParams.java29
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/IndexedBackend.java (renamed from container-search/src/main/java/com/yahoo/prelude/fastsearch/FastSearcher.java)34
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/SummaryParameters.java21
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackend.java (renamed from container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java)74
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/searcher/BlendingSearcher.java4
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/Dispatcher.java10
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java6
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/InvokerFactory.java8
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/SearchErrorInvoker.java4
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/SearchInvoker.java6
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java4
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcInvokerFactory.java6
-rw-r--r--container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java9
-rw-r--r--container-search/src/main/java/com/yahoo/search/searchchain/Execution.java4
-rw-r--r--container-search/src/main/java/com/yahoo/search/yql/FieldFiller.java2
-rw-r--r--container-search/src/main/java/com/yahoo/vespa/streamingvisitors/MetricsSearcher.java2
-rw-r--r--container-search/src/main/java/com/yahoo/vespa/streamingvisitors/StreamingBackend.java (renamed from container-search/src/main/java/com/yahoo/vespa/streamingvisitors/StreamingSearcher.java)54
-rw-r--r--container-search/src/main/java/com/yahoo/vespa/streamingvisitors/StreamingVisitor.java14
-rw-r--r--container-search/src/main/java/com/yahoo/vespa/streamingvisitors/VisitorFactory.java2
21 files changed, 233 insertions, 272 deletions
diff --git a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
index f481d58d334..855a524473d 100644
--- a/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java
@@ -1,6 +1,7 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.cluster;
+import com.yahoo.collections.TinyIdentitySet;
import com.yahoo.component.annotation.Inject;
import com.yahoo.component.ComponentId;
import com.yahoo.component.chain.dependencies.After;
@@ -10,9 +11,8 @@ import com.yahoo.container.core.documentapi.VespaDocumentAccess;
import com.yahoo.container.handler.VipStatus;
import com.yahoo.prelude.fastsearch.ClusterParams;
import com.yahoo.prelude.fastsearch.DocumentdbInfoConfig;
-import com.yahoo.prelude.fastsearch.FastSearcher;
-import com.yahoo.prelude.fastsearch.SummaryParameters;
-import com.yahoo.prelude.fastsearch.VespaBackEndSearcher;
+import com.yahoo.prelude.fastsearch.IndexedBackend;
+import com.yahoo.prelude.fastsearch.VespaBackend;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
import com.yahoo.search.Searcher;
@@ -24,14 +24,17 @@ import com.yahoo.search.result.ErrorMessage;
import com.yahoo.search.schema.Cluster;
import com.yahoo.search.schema.SchemaInfo;
import com.yahoo.search.searchchain.Execution;
-import com.yahoo.vespa.streamingvisitors.StreamingSearcher;
+import com.yahoo.vespa.streamingvisitors.StreamingBackend;
import com.yahoo.yolean.Exceptions;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
@@ -40,8 +43,6 @@ import java.util.concurrent.FutureTask;
import java.util.concurrent.RejectedExecutionException;
import java.util.stream.Collectors;
-import static com.yahoo.container.QrSearchersConfig.Searchcluster.Indexingmode.STREAMING;
-
/**
* A searcher which forwards to a cluster of monitored native Vespa backends.
*
@@ -58,13 +59,12 @@ public class ClusterSearcher extends Searcher {
private final String searchClusterName;
// The set of document types contained in this search cluster
- private final Set<String> schemas;
+ private final Map<String, VespaBackend> schema2Searcher;
private final SchemaInfo schemaInfo;
private final long maxQueryTimeout; // in milliseconds
private final long maxQueryCacheTimeout; // in milliseconds
- private final VespaBackEndSearcher server;
private final Executor executor;
private final GlobalPhaseRanker globalPhaseRanker;
@@ -86,26 +86,28 @@ public class ClusterSearcher extends Searcher {
searchClusterName = clusterConfig.clusterName();
QrSearchersConfig.Searchcluster searchClusterConfig = getSearchClusterConfigFromClusterName(qrsConfig, searchClusterName);
this.globalPhaseRanker = globalPhaseRanker;
- schemas = new LinkedHashSet<>();
+ schema2Searcher = new LinkedHashMap<>();
maxQueryTimeout = ParameterParser.asMilliSeconds(clusterConfig.maxQueryTimeout(), DEFAULT_MAX_QUERY_TIMEOUT);
maxQueryCacheTimeout = ParameterParser.asMilliSeconds(clusterConfig.maxQueryCacheTimeout(), DEFAULT_MAX_QUERY_CACHE_TIMEOUT);
- SummaryParameters docSumParams = new SummaryParameters(qrsConfig
- .com().yahoo().prelude().fastsearch().FastSearcher().docsum()
- .defaultclass());
-
- for (DocumentdbInfoConfig.Documentdb docDb : documentDbConfig.documentdb())
- schemas.add(docDb.name());
-
- String uniqueServerId = UUID.randomUUID().toString();
- if (searchClusterConfig.indexingmode() == STREAMING) {
- server = streamingCluster(uniqueServerId, searchClusterIndex,
- searchClusterConfig, docSumParams, documentDbConfig, schemaInfo, access);
- vipStatus.addToRotation(server.getName());
- } else {
- server = searchDispatch(searchClusterIndex, searchClusterName, uniqueServerId,
- docSumParams, documentDbConfig, schemaInfo, dispatchers);
+ VespaBackend streaming = null, indexed = null;
+ ClusterParams clusterParams = makeClusterParams(searchClusterIndex, qrsConfig
+ .com().yahoo().prelude().fastsearch().IndexedBackend().docsum()
+ .defaultclass(), documentDbConfig, schemaInfo);
+ for (DocumentdbInfoConfig.Documentdb docDb : documentDbConfig.documentdb()) {
+ if (docDb.mode() == DocumentdbInfoConfig.Documentdb.Mode.Enum.INDEX) {
+ if (indexed == null) {
+ indexed = searchDispatch(clusterParams, searchClusterName, dispatchers);
+ }
+ schema2Searcher.put(docDb.name(), indexed);
+ } else if (docDb.mode() == DocumentdbInfoConfig.Documentdb.Mode.Enum.STREAMING) {
+ if (streaming == null) {
+ streaming = streamingCluster(clusterParams, searchClusterConfig, access);
+ vipStatus.addToRotation(streaming.getName());
+ }
+ schema2Searcher.put(docDb.name(), streaming);
+ }
}
}
@@ -115,91 +117,88 @@ public class ClusterSearcher extends Searcher {
return searchCluster;
}
}
- return null;
+ throw new IllegalStateException("No configured search cluster '" + name + "' among : " +
+ config.searchcluster().stream().map(QrSearchersConfig.Searchcluster::name).toList());
}
- private static ClusterParams makeClusterParams(int searchclusterIndex) {
- return new ClusterParams("sc" + searchclusterIndex + ".num" + 0);
+ private static ClusterParams makeClusterParams(int searchclusterIndex, String defaultSummary,
+ DocumentdbInfoConfig documentDbConfig, SchemaInfo schemaInfo)
+ {
+ return new ClusterParams("sc" + searchclusterIndex + ".num" + 0, UUID.randomUUID().toString(),
+ defaultSummary, documentDbConfig, schemaInfo);
}
- private static FastSearcher searchDispatch(int searchclusterIndex,
- String searchClusterName,
- String serverId,
- SummaryParameters docSumParams,
- DocumentdbInfoConfig documentdbInfoConfig,
- SchemaInfo schemaInfo,
- ComponentRegistry<Dispatcher> dispatchers) {
- ClusterParams clusterParams = makeClusterParams(searchclusterIndex);
+ private static IndexedBackend searchDispatch(ClusterParams clusterParams,
+ String searchClusterName,
+ ComponentRegistry<Dispatcher> dispatchers)
+ {
ComponentId dispatcherComponentId = new ComponentId("dispatcher." + searchClusterName);
Dispatcher dispatcher = dispatchers.getComponent(dispatcherComponentId);
if (dispatcher == null)
- throw new IllegalArgumentException("Configuration error: No dispatcher " + dispatcherComponentId +
- " is configured");
- return new FastSearcher(serverId, dispatcher, docSumParams, clusterParams, documentdbInfoConfig, schemaInfo);
+ throw new IllegalArgumentException("Configuration error: No dispatcher " + dispatcherComponentId + " is configured");
+ return new IndexedBackend(clusterParams, dispatcher);
}
- private static StreamingSearcher streamingCluster(String serverId,
- int searchclusterIndex,
- QrSearchersConfig.Searchcluster searchClusterConfig,
- SummaryParameters docSumParams,
- DocumentdbInfoConfig documentdbInfoConfig,
- SchemaInfo schemaInfo,
- VespaDocumentAccess access) {
- if (searchClusterConfig.searchdef().size() != 1)
- throw new IllegalArgumentException("Streaming search clusters can only contain a single schema but got " +
- searchClusterConfig.searchdef());
- ClusterParams clusterParams = makeClusterParams(searchclusterIndex);
- StreamingSearcher searcher = new StreamingSearcher(access);
- searcher.setSearchClusterName(searchClusterConfig.rankprofiles_configid());
- searcher.setStorageClusterRouteSpec(searchClusterConfig.storagecluster().routespec());
- searcher.init(serverId, docSumParams, clusterParams, documentdbInfoConfig, schemaInfo);
- return searcher;
+ private static StreamingBackend streamingCluster(ClusterParams clusterParams,
+ QrSearchersConfig.Searchcluster searchClusterConfig,
+ VespaDocumentAccess access)
+ {
+ return new StreamingBackend(clusterParams, searchClusterConfig.rankprofiles_configid(),
+ access, searchClusterConfig.storagecluster().routespec());
}
/** Do not use, for internal testing purposes only. **/
- ClusterSearcher(SchemaInfo schemaInfo, Set<String> schemas, VespaBackEndSearcher searcher, Executor executor) {
+ ClusterSearcher(SchemaInfo schemaInfo, Map<String, VespaBackend> schema2Searcher, Executor executor) {
this.schemaInfo = schemaInfo;
searchClusterName = "testScenario";
maxQueryTimeout = DEFAULT_MAX_QUERY_TIMEOUT;
maxQueryCacheTimeout = DEFAULT_MAX_QUERY_CACHE_TIMEOUT;
- server = searcher;
this.executor = executor;
this.globalPhaseRanker = null;
- this.schemas = schemas;
+ this.schema2Searcher = schema2Searcher;
}
/** Do not use, for internal testing purposes only. **/
- ClusterSearcher(SchemaInfo schemaInfo, Set<String> schemas) {
- this(schemaInfo, schemas, null, null);
+ ClusterSearcher(SchemaInfo schemaInfo, Map<String, VespaBackend> schema2Searcher) {
+ this(schemaInfo, schema2Searcher, null);
}
@Override
public Result search(Query query, Execution execution) {
validateQueryTimeout(query);
validateQueryCache(query);
- Searcher searcher = server;
- if (searcher == null) {
+ if (schema2Searcher.isEmpty()) {
return new Result(query, ErrorMessage.createNoBackendsInService("Could not search"));
}
if (query.getTimeLeft() <= 0) {
return new Result(query, ErrorMessage.createTimeout("No time left for searching"));
}
- return doSearch(searcher, query, execution);
+ return doSearch(query);
}
@Override
- public void fill(com.yahoo.search.Result result, String summaryClass, Execution execution) {
+ public void fill(Result result, String summaryClass, Execution execution) {
+ fill(result, summaryClass);
+ }
+ private void fill(Result result, String summaryClass) {
Query query = result.getQuery();
-
- Searcher searcher = server;
- if (searcher != null) {
- if (query.getTimeLeft() > 0) {
- searcher.fill(result, summaryClass, execution);
- } else {
- if (result.hits().getErrorHit() == null) {
- result.hits().addError(ErrorMessage.createTimeout("No time left to get summaries, query timeout was " +
- query.getTimeout() + " ms"));
+ var restrict = query.getModel().getRestrict();
+ Collection<VespaBackend> servers = (restrict != null && ! restrict.isEmpty())
+ ? query.getModel().getRestrict().stream()
+ .map(schema2Searcher::get)
+ .collect(Collectors.toCollection(TinyIdentitySet::new))
+ : schema2Searcher.values().stream().collect(Collectors.toCollection(TinyIdentitySet::new));
+
+ if ( ! servers.isEmpty() ) {
+ for (var server : servers) {
+ if (query.getTimeLeft() > 0) {
+ server.fill(result, summaryClass);
+ } else {
+ if (result.hits().getErrorHit() == null) {
+ result.hits().addError(ErrorMessage.createTimeout("No time left to get summaries, query timeout was " +
+ query.getTimeout() + " ms"));
+ }
}
}
} else {
@@ -230,22 +229,21 @@ public class ClusterSearcher extends Searcher {
query.getRanking().setQueryCache(false);
}
- private Result doSearch(Searcher searcher, Query query, Execution execution) {
- if (schemas.size() > 1) {
- return searchMultipleDocumentTypes(searcher, query, execution);
+ private Result doSearch(Query query) {
+ if (schema2Searcher.size() > 1) {
+ return searchMultipleDocumentTypes(query);
} else {
- String docType = schemas.iterator().next();
- query.getModel().setRestrict(docType);
- return perSchemaSearch(searcher, query, execution);
+ String schema = schema2Searcher.keySet().iterator().next();
+ query.getModel().setRestrict(schema);
+ return perSchemaSearch(schema, query);
}
}
- private Result perSchemaSearch(Searcher searcher, Query query, Execution execution) {
+ private Result perSchemaSearch(String schema, Query query) {
Set<String> restrict = query.getModel().getRestrict();
if (restrict.size() != 1) {
throw new IllegalStateException("perSchemaSearch must always be called with 1 schema, got: " + restrict.size());
}
- String schema = restrict.iterator().next();
int rerankCount = globalPhaseRanker != null ? globalPhaseRanker.getRerankCount(query, schema) : 0;
boolean useGlobalPhase = rerankCount > 0;
final int wantOffset = query.getOffset();
@@ -257,7 +255,7 @@ public class ClusterSearcher extends Searcher {
query.setOffset(0);
query.setHits(useHits);
}
- Result result = searcher.search(query, execution);
+ Result result = schema2Searcher.get(schema).search(schema, query);
if (useGlobalPhase) {
globalPhaseRanker.rerankHits(query, result, schema);
result.hits().trim(wantOffset, wantHits);
@@ -284,16 +282,17 @@ public class ClusterSearcher extends Searcher {
}
}
- private Result searchMultipleDocumentTypes(Searcher searcher, Query query, Execution execution) {
+ private Result searchMultipleDocumentTypes(Query query) {
Set<String> schemas = resolveSchemas(query);
- List<Query> queries = createQueries(query, schemas);
- if (queries.size() == 1) {
- return perSchemaSearch(searcher, queries.get(0), execution);
+ Map<String, Query> schemaQueries = createQueries(query, schemas);
+ if (schemaQueries.size() == 1) {
+ var entry = schemaQueries.entrySet().iterator().next();
+ return perSchemaSearch(entry.getKey(), entry.getValue());
} else {
Result mergedResult = new Result(query);
- List<FutureTask<Result>> pending = new ArrayList<>(queries.size());
- for (Query q : queries) {
- FutureTask<Result> task = new FutureTask<>(() -> perSchemaSearch(searcher, q, execution));
+ List<FutureTask<Result>> pending = new ArrayList<>(schemaQueries.size());
+ for (var entry : schemaQueries.entrySet()) {
+ FutureTask<Result> task = new FutureTask<>(() -> perSchemaSearch(entry.getKey(), entry.getValue()));
try {
executor.execute(task);
pending.add(task);
@@ -309,7 +308,7 @@ public class ClusterSearcher extends Searcher {
if (query.getOffset() > 0 || query.getHits() < mergedResult.hits().size()) {
if (mergedResult.getHitOrderer() != null) {
// Make sure we have the necessary data for sorting
- searcher.fill(mergedResult, VespaBackEndSearcher.SORTABLE_ATTRIBUTES_SUMMARY_CLASS, execution);
+ fill(mergedResult, VespaBackend.SORTABLE_ATTRIBUTES_SUMMARY_CLASS);
}
mergedResult.hits().trim(query.getOffset(), query.getHits());
query.setOffset(0); // Needed when doing a trim
@@ -326,7 +325,7 @@ public class ClusterSearcher extends Searcher {
candidates.addAll(cluster.schemas());
}
return (candidates.isEmpty() ? sources : candidates).stream()
- .filter(schemas::contains).collect(Collectors.toUnmodifiableSet());
+ .filter(schema2Searcher::containsKey).collect(Collectors.toUnmodifiableSet());
}
Set<String> resolveSchemas(Query query) {
@@ -334,7 +333,7 @@ public class ClusterSearcher extends Searcher {
if (restrict == null || restrict.isEmpty()) {
Set<String> sources = query.getModel().getSources();
return (sources == null || sources.isEmpty())
- ? schemas
+ ? schema2Searcher.keySet()
: resolveSourceSubset(sources);
} else {
return filterValidDocumentTypes(restrict);
@@ -344,34 +343,40 @@ public class ClusterSearcher extends Searcher {
private Set<String> filterValidDocumentTypes(Collection<String> restrict) {
Set<String> retval = new LinkedHashSet<>();
for (String docType : restrict) {
- if (docType != null && schemas.contains(docType)) {
+ if (docType != null && schema2Searcher.containsKey(docType)) {
retval.add(docType);
}
}
return retval;
}
- private List<Query> createQueries(Query query, Set<String> docTypes) {
+ private Map<String, Query> createQueries(Query query, Set<String> schemas) {
query.getModel().getQueryTree(); // performance: parse query before cloning such that it is only done once
- List<Query> retval = new ArrayList<>(docTypes.size());
- if (docTypes.size() == 1) {
- query.getModel().setRestrict(docTypes.iterator().next());
- retval.add(query);
- } else if ( ! docTypes.isEmpty() ) {
- for (String docType : docTypes) {
+ if (schemas.size() == 1) {
+ String schema = schemas.iterator().next();
+ query.getModel().setRestrict(schema);
+ return Map.of(schema, query);
+ } else if ( ! schemas.isEmpty() ) {
+ var schemaQueries = new HashMap<String, Query>();
+ for (String schema : schemas) {
Query q = query.clone();
q.setOffset(0);
q.setHits(query.getOffset() + query.getHits());
- q.getModel().setRestrict(docType);
- retval.add(q);
+ q.getModel().setRestrict(schema);
+ schemaQueries.put(schema, q);
}
+ return schemaQueries;
}
- return retval;
+ return Map.of();
}
@Override
public void deconstruct() {
- if (server != null) {
+ Map<String, VespaBackend> servers = new HashMap<>();
+ for (var server : schema2Searcher.values()) {
+ servers.put(server.getName(), server);
+ }
+ for (var server : servers.values()) {
server.shutDown();
}
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/BoolField.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/BoolField.java
index c0f42f6924b..6a980c37f4e 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/BoolField.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/BoolField.java
@@ -7,7 +7,6 @@
package com.yahoo.prelude.fastsearch;
import com.yahoo.data.access.Inspector;
-import com.yahoo.search.result.NanNumber;
/**
* @author bratseth
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/ClusterParams.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/ClusterParams.java
index c34187e576b..2987500fdb3 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/ClusterParams.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/ClusterParams.java
@@ -1,21 +1,40 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.fastsearch;
+import com.yahoo.search.schema.SchemaInfo;
+
/**
* Helper class for carrying around cluster-related
- * config parameters to the FastSearcher class.
+ * config parameters to the VespaBackend class.
*
* @author arnej27959
*/
public class ClusterParams {
- public final String searcherName;
+ private final String searcherName;
+ private final String serverId;
+ private final String defaultSummary;
+ private final DocumentdbInfoConfig documentdbInfoConfig;
+ private final SchemaInfo schemaInfo;
- /**
- * Make up full ClusterParams
- */
public ClusterParams(String name) {
+ this(name, "server.0", null, null, null);
+ }
+ public ClusterParams(String name, String serverId, String defaultSummary,
+ DocumentdbInfoConfig documentdbInfoConfig, SchemaInfo schemaInfo) {
this.searcherName = name;
+ this.serverId = serverId;
+ if (defaultSummary != null && defaultSummary.isEmpty())
+ this.defaultSummary = null;
+ else
+ this.defaultSummary = defaultSummary;
+ this.documentdbInfoConfig = documentdbInfoConfig;
+ this.schemaInfo = schemaInfo;
}
+ public String getServerId() { return serverId; }
+ public String getSearcherName() { return searcherName; }
+ public String getDefaultSummary() { return defaultSummary; }
+ public DocumentdbInfoConfig getDocumentdbInfoConfig() { return documentdbInfoConfig; }
+ public SchemaInfo getSchemaInfo() { return schemaInfo; }
}
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FastSearcher.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/IndexedBackend.java
index ddb36e007d3..9836934acc1 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/FastSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/IndexedBackend.java
@@ -1,8 +1,6 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.fastsearch;
-import com.yahoo.prelude.Ping;
-import com.yahoo.prelude.Pong;
import com.yahoo.prelude.querytransform.QueryRewrite;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
@@ -15,8 +13,6 @@ import com.yahoo.search.query.Ranking;
import com.yahoo.search.result.ErrorMessage;
import com.yahoo.search.result.Hit;
import com.yahoo.search.result.HitGroup;
-import com.yahoo.search.schema.SchemaInfo;
-import com.yahoo.search.searchchain.Execution;
import java.io.IOException;
import java.util.Optional;
@@ -33,7 +29,7 @@ import java.util.Optional;
// errors on results and returning them. It could be handy to create a QueryHandlingErrorException
// or similar which could wrap an error message, and then just always throw that and
// catch and unwrap into a results with an error in high level methods. -Jon
-public class FastSearcher extends VespaBackEndSearcher {
+public class IndexedBackend extends VespaBackend {
/** Used to dispatch directly to search nodes over RPC, replacing the old fnet communication path */
private final Dispatcher dispatcher;
@@ -41,34 +37,18 @@ public class FastSearcher extends VespaBackEndSearcher {
/**
* Creates a Fastsearcher.
*
- * @param serverId the resource pool used to create direct connections to the local search nodes when
- * bypassing the dispatch node
* @param dispatcher the dispatcher used (when enabled) to send summary requests over the rpc protocol.
* Eventually we will move everything to this protocol and never use dispatch nodes.
* At that point we won't need a cluster searcher above this to select and pass the right
* backend.
- * @param docSumParams document summary parameters
* @param clusterParams the cluster number, and other cluster backend parameters
- * @param documentdbInfoConfig document database parameters
*/
- public FastSearcher(String serverId,
- Dispatcher dispatcher,
- SummaryParameters docSumParams,
- ClusterParams clusterParams,
- DocumentdbInfoConfig documentdbInfoConfig,
- SchemaInfo schemaInfo) {
- init(serverId, docSumParams, clusterParams, documentdbInfoConfig, schemaInfo);
+ public IndexedBackend(ClusterParams clusterParams, Dispatcher dispatcher)
+ {
+ super(clusterParams);
this.dispatcher = dispatcher;
}
- /**
- * Pings the backend. Does not propagate to other searchers.
- */
- @Override
- public Pong ping(Ping ping, Execution execution) {
- throw new IllegalStateException("This ping should not have been called.");
- }
-
@Override
protected void transformQuery(Query query) {
QueryRewrite.rewriteSddocname(query);
@@ -83,11 +63,11 @@ public class FastSearcher extends VespaBackEndSearcher {
}
@Override
- public Result doSearch2(Query query, Execution execution) {
+ public Result doSearch2(String schema, Query query) {
if (dispatcher.allGroupsHaveSize1())
forceSinglePassGrouping(query);
try (SearchInvoker invoker = getSearchInvoker(query)) {
- Result result = invoker.search(query, execution);
+ Result result = invoker.search(query);
injectSource(result.hits());
if (query.properties().getBoolean(Ranking.RANKFEATURES, false)) {
@@ -97,7 +77,7 @@ public class FastSearcher extends VespaBackEndSearcher {
// contain the data we need. If we fetch the default
// one we end up fetching docsums twice unless the
// user also requested the default one.
- fill(result, query.getPresentation().getSummary(), execution); // ARGH
+ fill(result, query.getPresentation().getSummary()); // ARGH
}
return result;
} catch (TimeoutException e) {
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/SummaryParameters.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/SummaryParameters.java
deleted file mode 100644
index 8751a730229..00000000000
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/SummaryParameters.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.prelude.fastsearch;
-
-
-/**
- * Wrapper for document summary parameters and configuration.
- *
- * @author Steinar Knutsen
- */
-public class SummaryParameters {
-
- public final String defaultClass;
-
- public SummaryParameters(String defaultClass) {
- if (defaultClass != null && defaultClass.isEmpty())
- this.defaultClass = null;
- else
- this.defaultClass = defaultClass;
- }
-
-}
diff --git a/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java b/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackend.java
index 2e635d21f01..761cb22be57 100644
--- a/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackEndSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/fastsearch/VespaBackend.java
@@ -12,41 +12,37 @@ import com.yahoo.prelude.querytransform.QueryRewrite;
import com.yahoo.protect.Validator;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
-import com.yahoo.search.cluster.PingableSearcher;
import com.yahoo.search.schema.RankProfile;
import com.yahoo.search.grouping.vespa.GroupingExecutor;
import com.yahoo.search.result.ErrorMessage;
import com.yahoo.search.result.Hit;
-import com.yahoo.search.schema.SchemaInfo;
-import com.yahoo.search.searchchain.Execution;
import com.yahoo.searchlib.aggregation.Grouping;
import java.util.ArrayList;
import java.util.Iterator;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.logging.Logger;
+import java.util.stream.Collectors;
/**
* Superclass for backend searchers.
*
* @author baldersheim
*/
-public abstract class VespaBackEndSearcher extends PingableSearcher {
+public abstract class VespaBackend {
/** for vespa-internal use only; consider renaming the summary class */
public static final String SORTABLE_ATTRIBUTES_SUMMARY_CLASS = "attributeprefetch";
- private String serverId;
+ private final String serverId;
/** The set of all document databases available in the backend handled by this searcher */
- private final Map<String, DocumentDatabase> documentDbs = new LinkedHashMap<>();
- private DocumentDatabase defaultDocumentDb = null;
+ private final Map<String, DocumentDatabase> documentDbs;
+ private final DocumentDatabase defaultDocumentDb;
/** Default docsum class. null means "unset" and is the default value */
- private String defaultDocsumClass = null;
+ private final String defaultDocsumClass;
/** Returns an iterator which returns all hits below this result **/
private static Iterator<Hit> hitIterator(Result result) {
@@ -54,24 +50,36 @@ public abstract class VespaBackEndSearcher extends PingableSearcher {
}
/** The name of this source */
- private String name;
+ private final String name;
- public final String getName() { return name; }
- protected final String getDefaultDocsumClass() { return defaultDocsumClass; }
+ protected VespaBackend(ClusterParams clusterParams) {
+ this.serverId = clusterParams.getServerId();
+ this.name = clusterParams.getSearcherName();
+ this.defaultDocsumClass = clusterParams.getDefaultSummary();
- /** Sets default document summary class. Default is null */
- private void setDefaultDocsumClass(String docsumClass) { defaultDocsumClass = docsumClass; }
+ Validator.ensureNotNull("Name of Vespa backend integration", name);
+
+ List<DocumentDatabase> dbs = new ArrayList<>();
+ if (clusterParams.getDocumentdbInfoConfig() != null) {
+ for (DocumentdbInfoConfig.Documentdb docDb : clusterParams.getDocumentdbInfoConfig().documentdb()) {
+ DocumentDatabase db = new DocumentDatabase(clusterParams.getSchemaInfo().schemas().get(docDb.name()));
+ dbs.add(db);
+ }
+ }
+ this.defaultDocumentDb = dbs.isEmpty() ? null : dbs.get(0);
+ this.documentDbs = dbs.stream().collect(Collectors.toMap(db -> db.schema().name(), db -> db));
+ }
- public final Logger getLogger() { return super.getLogger(); }
+ public final String getName() { return name; }
+ protected final String getDefaultDocsumClass() { return defaultDocsumClass; }
/**
* Searches a search cluster
* This is an endpoint - searchers will never propagate the search to any nested searcher.
*
* @param query the query to search
- * @param execution the query execution context
*/
- protected abstract Result doSearch2(Query query, Execution execution);
+ protected abstract Result doSearch2(String schema, Query query);
protected abstract void doPartialFill(Result result, String summaryClass);
@@ -133,29 +141,9 @@ public abstract class VespaBackEndSearcher extends PingableSearcher {
}
}
- public final void init(String serverId, SummaryParameters docSumParams, ClusterParams clusterParams,
- DocumentdbInfoConfig documentdbInfoConfig, SchemaInfo schemaInfo) {
- this.serverId = serverId;
- this.name = clusterParams.searcherName;
-
- Validator.ensureNotNull("Name of Vespa backend integration", getName());
-
- setDefaultDocsumClass(docSumParams.defaultClass);
-
- if (documentdbInfoConfig != null) {
- for (DocumentdbInfoConfig.Documentdb docDb : documentdbInfoConfig.documentdb()) {
- DocumentDatabase db = new DocumentDatabase(schemaInfo.schemas().get(docDb.name()));
- if (documentDbs.isEmpty())
- defaultDocumentDb = db;
- documentDbs.put(docDb.name(), db);
- }
- }
- }
-
protected void transformQuery(Query query) { }
- @Override
- public Result search(Query query, Execution execution) {
+ public Result search(String schema, Query query) {
// query root should not be null here
Item root = query.getModel().getQueryTree().getRoot();
if (root == null || root instanceof NullItem) {
@@ -183,7 +171,7 @@ public abstract class VespaBackEndSearcher extends PingableSearcher {
if (root == null || root instanceof NullItem) // root can become null after resolving and transformation?
return new Result(query);
- Result result = doSearch2(query, execution);
+ Result result = doSearch2(schema, query);
if (query.getTrace().getLevel() >= 1)
query.trace(getName() + " dispatch response: " + result, false, 1);
@@ -191,7 +179,7 @@ public abstract class VespaBackEndSearcher extends PingableSearcher {
return result;
}
- private List<Result> partitionHits(Result result, String summaryClass) {
+ private static List<Result> partitionHits(Result result, String summaryClass) {
List<Result> parts = new ArrayList<>();
TinyIdentitySet<Query> queryMap = new TinyIdentitySet<>(4);
@@ -217,8 +205,8 @@ public abstract class VespaBackEndSearcher extends PingableSearcher {
return parts;
}
- @Override
- public void fill(Result result, String summaryClass, Execution execution) {
+ //TODO Add schema here too.
+ public void fill(Result result, String summaryClass) {
if (result.isFilled(summaryClass)) return; // TODO: Checked in the superclass - remove
List<Result> parts = partitionHits(result, summaryClass);
diff --git a/container-search/src/main/java/com/yahoo/prelude/searcher/BlendingSearcher.java b/container-search/src/main/java/com/yahoo/prelude/searcher/BlendingSearcher.java
index 1128ad9570d..634a16d1dee 100644
--- a/container-search/src/main/java/com/yahoo/prelude/searcher/BlendingSearcher.java
+++ b/container-search/src/main/java/com/yahoo/prelude/searcher/BlendingSearcher.java
@@ -8,7 +8,7 @@ import com.yahoo.component.chain.dependencies.After;
import com.yahoo.component.chain.dependencies.Before;
import com.yahoo.component.chain.dependencies.Provides;
import com.yahoo.container.QrSearchersConfig;
-import com.yahoo.prelude.fastsearch.VespaBackEndSearcher;
+import com.yahoo.prelude.fastsearch.VespaBackend;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
import com.yahoo.search.Searcher;
@@ -115,7 +115,7 @@ public class BlendingSearcher extends Searcher {
private Result sortAndTrimResults(Result result, Query q, int offset, int hits, Execution execution) {
if (q.getRanking().getSorting() != null) {
// TODO: remove or rename this internal summary class for Vespa 9
- execution.fill(result, VespaBackEndSearcher.SORTABLE_ATTRIBUTES_SUMMARY_CLASS);
+ execution.fill(result, VespaBackend.SORTABLE_ATTRIBUTES_SUMMARY_CLASS);
result.hits().sort();
}
result.hits().trim(offset, hits);
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/Dispatcher.java b/container-search/src/main/java/com/yahoo/search/dispatch/Dispatcher.java
index 8ec88bd7f45..1689f6d246e 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/Dispatcher.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/Dispatcher.java
@@ -6,7 +6,7 @@ import com.yahoo.component.ComponentId;
import com.yahoo.component.annotation.Inject;
import com.yahoo.compress.Compressor;
import com.yahoo.container.handler.VipStatus;
-import com.yahoo.prelude.fastsearch.VespaBackEndSearcher;
+import com.yahoo.prelude.fastsearch.VespaBackend;
import com.yahoo.processing.request.CompoundName;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
@@ -256,13 +256,13 @@ public class Dispatcher extends AbstractComponent {
}
}
- public FillInvoker getFillInvoker(Result result, VespaBackEndSearcher searcher) {
+ public FillInvoker getFillInvoker(Result result, VespaBackend searcher) {
try (var items = volatileItems()) { // Take a snapshot, and release it when we're done.
return items.register(items.get().invokerFactory.createFillInvoker(searcher, result));
}
}
- public SearchInvoker getSearchInvoker(Query query, VespaBackEndSearcher searcher) {
+ public SearchInvoker getSearchInvoker(Query query, VespaBackend searcher) {
try (var items = volatileItems()) { // Take a snapshot, and release it when we're done.
int maxHitsPerNode = dispatchConfig.maxHitsPerNode();
SearchInvoker invoker = getSearchPathInvoker(query, searcher, searchCluster.groupList(), items.get().invokerFactory, maxHitsPerNode)
@@ -277,7 +277,7 @@ public class Dispatcher extends AbstractComponent {
}
/** Builds an invoker based on searchpath */
- private static Optional<SearchInvoker> getSearchPathInvoker(Query query, VespaBackEndSearcher searcher, SearchGroups cluster,
+ private static Optional<SearchInvoker> getSearchPathInvoker(Query query, VespaBackend searcher, SearchGroups cluster,
InvokerFactory invokerFactory, int maxHitsPerNode) {
String searchPath = query.getModel().getSearchPath();
if (searchPath == null) return Optional.empty();
@@ -297,7 +297,7 @@ public class Dispatcher extends AbstractComponent {
}
}
- private static SearchInvoker getInternalInvoker(Query query, VespaBackEndSearcher searcher, SearchCluster cluster,
+ private static SearchInvoker getInternalInvoker(Query query, VespaBackend searcher, SearchCluster cluster,
LoadBalancer loadBalancer, InvokerFactory invokerFactory, int maxHitsPerNode) {
Optional<Node> directNode = cluster.localCorpusDispatchTarget();
if (directNode.isPresent()) {
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java b/container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java
index be8524bedd2..a246589ec7e 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/InterleavedSearchInvoker.java
@@ -111,9 +111,9 @@ public class InterleavedSearchInvoker extends SearchInvoker implements ResponseM
}
@Override
- protected InvokerResult getSearchResult(Execution execution) throws IOException {
+ protected InvokerResult getSearchResult() throws IOException {
InvokerResult result = new InvokerResult(query, query.getHits());
- List<LeanHit> merged = Collections.emptyList();
+ List<LeanHit> merged = List.of();
long nextTimeout = query.getTimeLeft();
var groupingResultAggregator = new GroupingResultAggregator();
try {
@@ -124,7 +124,7 @@ public class InterleavedSearchInvoker extends SearchInvoker implements ResponseM
coverageAggregator.getAnsweredNodes() + " responses received");
break;
} else {
- InvokerResult toMerge = invoker.getSearchResult(execution);
+ InvokerResult toMerge = invoker.getSearchResult();
merged = mergeResult(result.getResult(), toMerge, merged, groupingResultAggregator);
ejectInvoker(invoker);
}
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/InvokerFactory.java b/container-search/src/main/java/com/yahoo/search/dispatch/InvokerFactory.java
index f1d58122570..d7fad148c8c 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/InvokerFactory.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/InvokerFactory.java
@@ -2,7 +2,7 @@
package com.yahoo.search.dispatch;
import com.yahoo.concurrent.Timer;
-import com.yahoo.prelude.fastsearch.VespaBackEndSearcher;
+import com.yahoo.prelude.fastsearch.VespaBackend;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
import com.yahoo.search.dispatch.searchcluster.Group;
@@ -34,12 +34,12 @@ public abstract class InvokerFactory {
this.hitEstimator = new TopKEstimator(30.0, dispatchConfig.topKProbability(), SKEW_FACTOR);
}
- protected abstract Optional<SearchInvoker> createNodeSearchInvoker(VespaBackEndSearcher searcher,
+ protected abstract Optional<SearchInvoker> createNodeSearchInvoker(VespaBackend searcher,
Query query,
int maxHits,
Node node);
- public abstract FillInvoker createFillInvoker(VespaBackEndSearcher searcher, Result result);
+ public abstract FillInvoker createFillInvoker(VespaBackend searcher, Result result);
/**
* Creates a {@link SearchInvoker} for a list of content nodes.
@@ -52,7 +52,7 @@ public abstract class InvokerFactory {
* @return the invoker or empty if some node in the
* list is invalid and the remaining coverage is not sufficient
*/
- Optional<SearchInvoker> createSearchInvoker(VespaBackEndSearcher searcher,
+ Optional<SearchInvoker> createSearchInvoker(VespaBackend searcher,
Query query,
List<Node> nodes,
boolean acceptIncompleteCoverage,
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/SearchErrorInvoker.java b/container-search/src/main/java/com/yahoo/search/dispatch/SearchErrorInvoker.java
index b494b5b3819..74da2388155 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/SearchErrorInvoker.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/SearchErrorInvoker.java
@@ -35,7 +35,7 @@ public class SearchErrorInvoker extends SearchInvoker {
}
@Override
- protected Object sendSearchRequest(Query query, Object context) throws IOException {
+ protected Object sendSearchRequest(Query query, Object context) {
this.query = query;
if (monitor != null) {
monitor.responseAvailable(this);
@@ -44,7 +44,7 @@ public class SearchErrorInvoker extends SearchInvoker {
}
@Override
- protected InvokerResult getSearchResult(Execution execution) throws IOException {
+ protected InvokerResult getSearchResult() {
Result res = new Result(query, message);
if (coverage != null) {
res.setCoverage(coverage);
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/SearchInvoker.java b/container-search/src/main/java/com/yahoo/search/dispatch/SearchInvoker.java
index ad332494179..4ad89674b7b 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/SearchInvoker.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/SearchInvoker.java
@@ -31,9 +31,9 @@ public abstract class SearchInvoker extends CloseableInvoker {
* nodes, the provided {@link Execution} may be used to retrieve document summaries required
* for correct result windowing.
*/
- public Result search(Query query, Execution execution) throws IOException {
+ public Result search(Query query) throws IOException {
sendSearchRequest(query, null);
- InvokerResult result = getSearchResult(execution);
+ InvokerResult result = getSearchResult();
setFinalStatus(result.getResult().hits().getError() == null);
result.complete();
return result.getResult();
@@ -48,7 +48,7 @@ public abstract class SearchInvoker extends CloseableInvoker {
*/
protected abstract Object sendSearchRequest(Query query, Object context) throws IOException;
- protected abstract InvokerResult getSearchResult(Execution execution) throws IOException;
+ protected abstract InvokerResult getSearchResult() throws IOException;
protected void setMonitor(ResponseMonitor<SearchInvoker> monitor) {
this.monitor = monitor;
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java
index 9da4c91cd16..284b4a4fcbc 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/ProtobufSerialization.java
@@ -14,7 +14,7 @@ import com.yahoo.io.GrowableByteBuffer;
import com.yahoo.prelude.fastsearch.DocumentDatabase;
import com.yahoo.prelude.fastsearch.FastHit;
import com.yahoo.prelude.fastsearch.GroupingListHit;
-import com.yahoo.prelude.fastsearch.VespaBackEndSearcher;
+import com.yahoo.prelude.fastsearch.VespaBackend;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
import com.yahoo.search.dispatch.InvokerResult;
@@ -227,7 +227,7 @@ public class ProtobufSerialization {
return convertFromResult(searchResult).toByteArray();
}
- static InvokerResult deserializeToSearchResult(byte[] payload, Query query, VespaBackEndSearcher searcher, int partId, int distKey)
+ static InvokerResult deserializeToSearchResult(byte[] payload, Query query, VespaBackend searcher, int partId, int distKey)
throws InvalidProtocolBufferException {
var protobuf = SearchProtocol.SearchReply.parseFrom(payload);
return convertToResult(query, protobuf, searcher.getDocumentDatabase(query), partId, distKey);
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcInvokerFactory.java b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcInvokerFactory.java
index 8221391afe6..9fd602032e9 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcInvokerFactory.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcInvokerFactory.java
@@ -1,7 +1,7 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.search.dispatch.rpc;
-import com.yahoo.prelude.fastsearch.VespaBackEndSearcher;
+import com.yahoo.prelude.fastsearch.VespaBackend;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
import com.yahoo.search.dispatch.FillInvoker;
@@ -37,12 +37,12 @@ public class RpcInvokerFactory extends InvokerFactory {
}
@Override
- protected Optional<SearchInvoker> createNodeSearchInvoker(VespaBackEndSearcher searcher, Query query, int maxHits, Node node) {
+ protected Optional<SearchInvoker> createNodeSearchInvoker(VespaBackend searcher, Query query, int maxHits, Node node) {
return Optional.of(new RpcSearchInvoker(searcher, compressor, node, rpcResourcePool, maxHits));
}
@Override
- public FillInvoker createFillInvoker(VespaBackEndSearcher searcher, Result result) {
+ public FillInvoker createFillInvoker(VespaBackend searcher, Result result) {
Query query = result.getQuery();
boolean summaryNeedsQuery = searcher.summaryNeedsQuery(query);
diff --git a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java
index e34e5c97bc4..fb028358caf 100644
--- a/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java
+++ b/container-search/src/main/java/com/yahoo/search/dispatch/rpc/RpcSearchInvoker.java
@@ -2,14 +2,13 @@
package com.yahoo.search.dispatch.rpc;
import com.yahoo.compress.Compressor;
-import com.yahoo.prelude.fastsearch.VespaBackEndSearcher;
+import com.yahoo.prelude.fastsearch.VespaBackend;
import com.yahoo.search.Query;
import com.yahoo.search.dispatch.InvokerResult;
import com.yahoo.search.dispatch.SearchInvoker;
import com.yahoo.search.dispatch.rpc.Client.ProtobufResponse;
import com.yahoo.search.dispatch.searchcluster.Node;
import com.yahoo.search.result.ErrorMessage;
-import com.yahoo.search.searchchain.Execution;
import java.io.IOException;
import java.util.Optional;
@@ -26,7 +25,7 @@ public class RpcSearchInvoker extends SearchInvoker implements Client.ResponseRe
private static final String RPC_METHOD = "vespa.searchprotocol.search";
- private final VespaBackEndSearcher searcher;
+ private final VespaBackend searcher;
private final Node node;
private final RpcConnectionPool resourcePool;
private final BlockingQueue<Client.ResponseOrError<ProtobufResponse>> responses;
@@ -35,7 +34,7 @@ public class RpcSearchInvoker extends SearchInvoker implements Client.ResponseRe
private Query query;
- RpcSearchInvoker(VespaBackEndSearcher searcher, CompressPayload compressor, Node node, RpcConnectionPool resourcePool, int maxHits) {
+ RpcSearchInvoker(VespaBackend searcher, CompressPayload compressor, Node node, RpcConnectionPool resourcePool, int maxHits) {
super(Optional.of(node));
this.searcher = searcher;
this.node = node;
@@ -86,7 +85,7 @@ public class RpcSearchInvoker extends SearchInvoker implements Client.ResponseRe
}
@Override
- protected InvokerResult getSearchResult(Execution execution) throws IOException {
+ protected InvokerResult getSearchResult() throws IOException {
long timeLeftMs = query.getTimeLeft();
if (timeLeftMs <= 0) {
return errorResult(query, ErrorMessage.createTimeout("Timeout while waiting for " + getName()));
diff --git a/container-search/src/main/java/com/yahoo/search/searchchain/Execution.java b/container-search/src/main/java/com/yahoo/search/searchchain/Execution.java
index 0b3179f5ad6..6eb69c76afd 100644
--- a/container-search/src/main/java/com/yahoo/search/searchchain/Execution.java
+++ b/container-search/src/main/java/com/yahoo/search/searchchain/Execution.java
@@ -8,7 +8,7 @@ import com.yahoo.prelude.IndexFacts;
import com.yahoo.prelude.Ping;
import com.yahoo.prelude.Pong;
import com.yahoo.language.process.SpecialTokenRegistry;
-import com.yahoo.prelude.fastsearch.VespaBackEndSearcher;
+import com.yahoo.prelude.fastsearch.VespaBackend;
import com.yahoo.processing.Processor;
import com.yahoo.processing.Request;
import com.yahoo.processing.Response;
@@ -534,7 +534,7 @@ public class Execution extends com.yahoo.processing.execution.Execution {
*/
@Deprecated // TODO Remove on Vespa 9.
public void fillAttributes(Result result) {
- fill(result, VespaBackEndSearcher.SORTABLE_ATTRIBUTES_SUMMARY_CLASS);
+ fill(result, VespaBackend.SORTABLE_ATTRIBUTES_SUMMARY_CLASS);
}
/**
diff --git a/container-search/src/main/java/com/yahoo/search/yql/FieldFiller.java b/container-search/src/main/java/com/yahoo/search/yql/FieldFiller.java
index 0685a77d7a9..64a989fd0e7 100644
--- a/container-search/src/main/java/com/yahoo/search/yql/FieldFiller.java
+++ b/container-search/src/main/java/com/yahoo/search/yql/FieldFiller.java
@@ -5,7 +5,7 @@ import java.util.HashSet;
import java.util.Set;
import com.yahoo.component.chain.dependencies.After;
-import static com.yahoo.prelude.fastsearch.VespaBackEndSearcher.SORTABLE_ATTRIBUTES_SUMMARY_CLASS;
+import static com.yahoo.prelude.fastsearch.VespaBackend.SORTABLE_ATTRIBUTES_SUMMARY_CLASS;
import com.yahoo.processing.request.CompoundName;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
diff --git a/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/MetricsSearcher.java b/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/MetricsSearcher.java
index 5fef90c2012..e367bb58f80 100644
--- a/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/MetricsSearcher.java
+++ b/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/MetricsSearcher.java
@@ -15,7 +15,7 @@ import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Logger;
-import static com.yahoo.vespa.streamingvisitors.StreamingSearcher.STREAMING_STATISTICS;
+import static com.yahoo.vespa.streamingvisitors.StreamingBackend.STREAMING_STATISTICS;
/**
* Generates mail-specific query metrics.
diff --git a/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/StreamingSearcher.java b/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/StreamingBackend.java
index 180fdc389d8..6b81ab0fa97 100644
--- a/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/StreamingSearcher.java
+++ b/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/StreamingBackend.java
@@ -11,10 +11,11 @@ import com.yahoo.fs4.DocsumPacket;
import com.yahoo.messagebus.routing.Route;
import com.yahoo.prelude.Ping;
import com.yahoo.prelude.Pong;
+import com.yahoo.prelude.fastsearch.ClusterParams;
import com.yahoo.prelude.fastsearch.FastHit;
import com.yahoo.prelude.fastsearch.GroupingListHit;
import com.yahoo.prelude.fastsearch.TimeoutException;
-import com.yahoo.prelude.fastsearch.VespaBackEndSearcher;
+import com.yahoo.prelude.fastsearch.VespaBackend;
import com.yahoo.processing.request.CompoundName;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
@@ -44,8 +45,9 @@ import java.util.logging.Logger;
* @author baldersheim
* @author Ulf Carlin
*/
-public class StreamingSearcher extends VespaBackEndSearcher {
+public class StreamingBackend extends VespaBackend {
+ private static final Logger log = Logger.getLogger(StreamingBackend.class.getName());
private static final CompoundName streamingUserid = CompoundName.from("streaming.userid");
private static final CompoundName streamingGroupname = CompoundName.from("streaming.groupname");
private static final CompoundName streamingSelection = CompoundName.from("streaming.selection");
@@ -53,41 +55,35 @@ public class StreamingSearcher extends VespaBackEndSearcher {
static final String STREAMING_STATISTICS = "streaming.statistics";
private final VisitorFactory visitorFactory;
private final TracingOptions tracingOptions;
- private static final Logger log = Logger.getLogger(StreamingSearcher.class.getName());
- private Route route;
+ private final Route route;
/** The configId used to access the searchcluster. */
- private String searchClusterName = null;
+ private final String searchClusterName;
/** The route to the storage cluster. */
- private String storageClusterRouteSpec = null;
+ private final String storageClusterRouteSpec;
- StreamingSearcher(VisitorFactory visitorFactory) {
- this.visitorFactory = visitorFactory;
- tracingOptions = TracingOptions.DEFAULT;
+ StreamingBackend(ClusterParams clusterParams, String searchClusterName, VisitorFactory visitorFactory, String storageClusterRouteSpec) {
+ this(clusterParams, searchClusterName, visitorFactory, storageClusterRouteSpec, TracingOptions.DEFAULT);
}
- StreamingSearcher(VisitorFactory visitorFactory, TracingOptions tracingOptions) {
+ StreamingBackend(ClusterParams clusterParams, String searchClusterName, VisitorFactory visitorFactory, String storageClusterRouteSpec, TracingOptions tracingOptions) {
+ super(clusterParams);
this.visitorFactory = visitorFactory;
this.tracingOptions = tracingOptions;
+ this.searchClusterName = searchClusterName;
+ this.storageClusterRouteSpec = storageClusterRouteSpec;
+ this.route = Route.parse(storageClusterRouteSpec);
}
- public StreamingSearcher(VespaDocumentAccess access) {
- this(new VespaVisitorFactory(access));
+ public StreamingBackend(ClusterParams clusterParams, String searchClusterName, VespaDocumentAccess access, String storageClusterRouteSpec) {
+ this(clusterParams, searchClusterName, new VespaVisitorFactory(access), storageClusterRouteSpec);
}
private String getSearchClusterName() { return searchClusterName; }
- private String getStorageClusterRouteSpec() { return storageClusterRouteSpec; }
- public final void setSearchClusterName(String clusterName) { this.searchClusterName = clusterName; }
- public final void setStorageClusterRouteSpec(String storageClusterRouteSpec) {
- this.storageClusterRouteSpec = storageClusterRouteSpec;
- }
-
- @Override
- protected void doPartialFill(Result result, String summaryClass) {
- }
+ @Override protected void doPartialFill(Result result, String summaryClass) { }
private double durationInMillisFromNanoTime(long startTimeNanos) {
return (tracingOptions.getClock().nanoTimeNow() - startTimeNanos) / (double)TimeUnit.MILLISECONDS.toNanos(1);
@@ -126,7 +122,7 @@ public class StreamingSearcher extends VespaBackEndSearcher {
}
@Override
- public Result doSearch2(Query query, Execution execution) {
+ public Result doSearch2(String schema, Query query) {
if (query.getTimeLeft() <= 0)
return new Result(query, ErrorMessage.createTimeout(String.format("No time left for searching (timeout=%d)", query.getTimeout())));
@@ -135,8 +131,6 @@ public class StreamingSearcher extends VespaBackEndSearcher {
return new Result(query, ErrorMessage.createIllegalQuery("Streaming search requires either " +
"streaming.groupname or streaming.selection"));
}
- // Cluster searcher guarantees that there will be one, and only one schema here
- String schema = query.getModel().getRestrict().iterator().next();
if (query.getTrace().isTraceable(4))
query.trace("Routing to search cluster " + getSearchClusterName() + " and document type " + schema, 4);
@@ -167,11 +161,7 @@ public class StreamingSearcher extends VespaBackEndSearcher {
}
private void initializeMissingQueryFields(Query query) {
- lazyTrace(query, 7, "Routing to storage cluster ", getStorageClusterRouteSpec());
-
- if (route == null) {
- route = Route.parse(getStorageClusterRouteSpec());
- }
+ lazyTrace(query, 7, "Routing to storage cluster ", storageClusterRouteSpec);
lazyTrace(query, 8, "Route is ", route);
lazyTrace(query, 7, "doSearch2(): query docsum class=",
@@ -264,7 +254,7 @@ public class StreamingSearcher extends VespaBackEndSearcher {
lazyTrace(query, 8, "Returning result ", result);
if (skippedHits > 0) {
- getLogger().info("skipping " + skippedHits + " hits for query: " + result.getQuery());
+ log.info("skipping " + skippedHits + " hits for query: " + result.getQuery());
result.hits().addError(ErrorMessage.createTimeout("Missing hit summary data for " + skippedHits + " hits"));
}
@@ -366,8 +356,8 @@ public class StreamingSearcher extends VespaBackEndSearcher {
}
@Override
- public Visitor createVisitor(Query query, String searchCluster, Route route, String documentType, int traceLevelOverride) {
- return new StreamingVisitor(query, searchCluster, route, documentType, this, traceLevelOverride);
+ public Visitor createVisitor(Query query, String searchCluster, Route route, String schema, int traceLevelOverride) {
+ return new StreamingVisitor(query, searchCluster, route, schema, this, traceLevelOverride);
}
}
diff --git a/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/StreamingVisitor.java b/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/StreamingVisitor.java
index 658eea0b526..bb155e3f934 100644
--- a/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/StreamingVisitor.java
+++ b/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/StreamingVisitor.java
@@ -28,6 +28,7 @@ import com.yahoo.vdslib.VisitorStatistics;
import com.yahoo.vespa.objects.BufferSerializer;
import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -76,13 +77,13 @@ class StreamingVisitor extends VisitorDataHandler implements Visitor {
}
public StreamingVisitor(Query query, String searchCluster, Route route,
- String documentType, VisitorSessionFactory visitorSessionFactory,
+ String schema, VisitorSessionFactory visitorSessionFactory,
int traceLevelOverride)
{
this.query = query;
this.visitorSessionFactory = visitorSessionFactory;
this.traceLevelOverride = traceLevelOverride;
- setVisitorParameters(searchCluster, route, documentType);
+ setVisitorParameters(searchCluster, route, schema);
}
private int inferSessionTraceLevel(Query query) {
@@ -112,8 +113,8 @@ class StreamingVisitor extends VisitorDataHandler implements Visitor {
return query.properties().getString(streamingSelection);
}
- private void setVisitorParameters(String searchCluster, Route route, String documentType) {
- params.setDocumentSelection(createSelectionString(documentType, createQuerySelectionString()));
+ private void setVisitorParameters(String searchCluster, Route route, String schema) {
+ params.setDocumentSelection(createSelectionString(schema, createQuerySelectionString()));
params.setTimeoutMs(query.getTimeout()); // Per bucket visitor timeout
params.setSessionTimeoutMs(query.getTimeout());
params.setVisitorLibrary("searchvisitor");
@@ -146,7 +147,8 @@ class StreamingVisitor extends VisitorDataHandler implements Visitor {
encodeQueryData(query, 0, ed);
params.setLibraryParameter("query", ed.getEncodedData());
params.setLibraryParameter("querystackcount", String.valueOf(ed.getReturned()));
- params.setLibraryParameter("searchcluster", searchCluster.getBytes());
+ params.setLibraryParameter("searchcluster", searchCluster.getBytes(StandardCharsets.UTF_8));
+ params.setLibraryParameter("schema", schema.getBytes(StandardCharsets.UTF_8));
if (query.getPresentation().getSummary() != null) {
params.setLibraryParameter("summaryclass", query.getPresentation().getSummary());
} else {
@@ -265,7 +267,7 @@ class StreamingVisitor extends VisitorDataHandler implements Visitor {
log.log(Level.FINE, () -> "StreamingVisitor returned from waitUntilDone without being completed for " + query +
" with selection " + params.getDocumentSelection());
session.abort();
- throw new TimeoutException("Query timed out in " + StreamingSearcher.class.getName());
+ throw new TimeoutException("Query timed out in " + StreamingBackend.class.getName());
}
} finally {
session.destroy();
diff --git a/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/VisitorFactory.java b/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/VisitorFactory.java
index 10387065128..e33bbd206be 100644
--- a/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/VisitorFactory.java
+++ b/container-search/src/main/java/com/yahoo/vespa/streamingvisitors/VisitorFactory.java
@@ -11,6 +11,6 @@ import com.yahoo.search.Query;
*/
interface VisitorFactory {
- Visitor createVisitor(Query query, String searchCluster, Route route, String documentType, int traceLevelOverride);
+ Visitor createVisitor(Query query, String searchCluster, Route route, String schema, int traceLevelOverride);
}