aboutsummaryrefslogtreecommitdiffstats
path: root/container-search
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@yahooinc.com>2023-03-28 15:15:39 +0200
committerBjørn Christian Seime <bjorncs@yahooinc.com>2023-03-28 16:21:15 +0200
commitb55da928a113abb841e9acb403710bf03ecf9fa5 (patch)
tree3b3f28932e7f5e162de3423fb66e6b67b3f30ebb /container-search
parent75c59aad9977f0021001f823b36b791af954b662 (diff)
Enforce that sorting is not enabled when using global-phase
Diffstat (limited to 'container-search')
-rw-r--r--container-search/src/main/java/com/yahoo/prelude/cluster/ClusterSearcher.java20
-rw-r--r--container-search/src/main/java/com/yahoo/search/ranking/GlobalPhaseRanker.java31
2 files changed, 35 insertions, 16 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 409c0a2c973..f0e3e3f3e44 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
@@ -60,8 +60,7 @@ public class ClusterSearcher extends Searcher {
private final VespaBackEndSearcher server;
private final Executor executor;
- private final GlobalPhaseRanker globalPhaseHelper;
- private final boolean enableGlobalPhase;
+ private final GlobalPhaseRanker globalPhaseRanker;
@Inject
public ClusterSearcher(ComponentId id,
@@ -71,15 +70,15 @@ public class ClusterSearcher extends Searcher {
DocumentdbInfoConfig documentDbConfig,
SchemaInfo schemaInfo,
ComponentRegistry<Dispatcher> dispatchers,
- GlobalPhaseRanker globalPhaseHelper,
+ GlobalPhaseRanker globalPhaseRanker,
VipStatus vipStatus,
VespaDocumentAccess access) {
super(id);
this.executor = executor;
- this.globalPhaseHelper = globalPhaseHelper;
int searchClusterIndex = clusterConfig.clusterId();
searchClusterName = clusterConfig.clusterName();
QrSearchersConfig.Searchcluster searchClusterConfig = getSearchClusterConfigFromClusterName(qrsConfig, searchClusterName);
+ this.globalPhaseRanker = searchClusterConfig.globalphase() ? globalPhaseRanker : null;
this.schemaResolver = new SchemaResolver(documentDbConfig);
maxQueryTimeout = ParameterParser.asMilliSeconds(clusterConfig.maxQueryTimeout(), DEFAULT_MAX_QUERY_TIMEOUT);
@@ -98,7 +97,6 @@ public class ClusterSearcher extends Searcher {
server = searchDispatch(searchClusterIndex, searchClusterName, uniqueServerId,
docSumParams, documentDbConfig, schemaInfo, dispatchers);
}
- enableGlobalPhase = searchClusterConfig.globalphase();
}
private static QrSearchersConfig.Searchcluster getSearchClusterConfigFromClusterName(QrSearchersConfig config, String name) {
@@ -157,8 +155,7 @@ public class ClusterSearcher extends Searcher {
maxQueryCacheTimeout = DEFAULT_MAX_QUERY_CACHE_TIMEOUT;
server = searcher;
this.executor = executor;
- this.globalPhaseHelper = null;
- this.enableGlobalPhase = false;
+ this.globalPhaseRanker = null;
}
/** Do not use, for internal testing purposes only. **/
@@ -240,10 +237,13 @@ public class ClusterSearcher extends Searcher {
throw new IllegalStateException("perSchemaSearch must always be called with 1 schema, got: " + restrict.size());
}
String schema = restrict.iterator().next();
- Result result = searcher.search(query, execution);
- if (globalPhaseHelper != null && enableGlobalPhase) {
- globalPhaseHelper.process(query, result, schema);
+ boolean useGlobalPhase = globalPhaseRanker != null;
+ if (useGlobalPhase) {
+ var error = globalPhaseRanker.validateNoSorting(query, schema).orElse(null);
+ if (error != null) return new Result(query, error);
}
+ Result result = searcher.search(query, execution);
+ if (useGlobalPhase) globalPhaseRanker.rerankHits(query, result, schema);
return result;
}
diff --git a/container-search/src/main/java/com/yahoo/search/ranking/GlobalPhaseRanker.java b/container-search/src/main/java/com/yahoo/search/ranking/GlobalPhaseRanker.java
index 2c6ab9e9367..dd419d69315 100644
--- a/container-search/src/main/java/com/yahoo/search/ranking/GlobalPhaseRanker.java
+++ b/container-search/src/main/java/com/yahoo/search/ranking/GlobalPhaseRanker.java
@@ -4,11 +4,14 @@ package com.yahoo.search.ranking;
import com.yahoo.component.annotation.Inject;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
+import com.yahoo.search.query.Sorting;
import com.yahoo.search.ranking.RankProfilesEvaluator.GlobalPhaseData;
+import com.yahoo.search.result.ErrorMessage;
import com.yahoo.tensor.Tensor;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
import java.util.function.Supplier;
import java.util.logging.Logger;
@@ -20,14 +23,25 @@ public class GlobalPhaseRanker {
@Inject
public GlobalPhaseRanker(RankProfilesEvaluatorFactory factory) {
this.factory = factory;
- logger.info("using factory: " + factory);
+ logger.fine(() -> "Using factory: " + factory);
}
- public void process(Query query, Result result, String schema) {
- String rankProfile = query.getRanking().getProfile();
- GlobalPhaseData data = factory.evaluatorForSchema(schema)
- .flatMap(evaluator -> evaluator.getGlobalPhaseData(rankProfile))
- .orElse(null);
+ public Optional<ErrorMessage> validateNoSorting(Query query, String schema) {
+ var data = globalPhaseDataFor(query, schema).orElse(null);
+ if (data == null) return Optional.empty();
+ var sorting = query.getRanking().getSorting();
+ if (sorting == null || sorting.fieldOrders() == null) return Optional.empty();
+ for (var fieldOrder : sorting.fieldOrders()) {
+ if (!fieldOrder.getSorter().getName().equals("[rank]")
+ || fieldOrder.getSortOrder() != Sorting.Order.DESCENDING) {
+ return Optional.of(ErrorMessage.createIllegalQuery("Sorting is not supported with global phase"));
+ }
+ }
+ return Optional.empty();
+ }
+
+ public void rerankHits(Query query, Result result, String schema) {
+ var data = globalPhaseDataFor(query, schema).orElse(null);
if (data == null) return;
var functionEvaluatorSource = data.functionEvaluatorSource();
var prepared = findFromQuery(query, data.needInputs());
@@ -45,6 +59,11 @@ public class GlobalPhaseRanker {
ResultReranker.rerankHits(result, new HitRescorer(supplier), rerankCount);
}
+ private Optional<GlobalPhaseData> globalPhaseDataFor(Query query, String schema) {
+ return factory.evaluatorForSchema(schema)
+ .flatMap(evaluator -> evaluator.getGlobalPhaseData(query.getRanking().getProfile()));
+ }
+
record NameAndValue(String name, Tensor value) { }
/* do this only once per query: */