diff options
2 files changed, 60 insertions, 18 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/significance/SignificanceSearcher.java b/container-search/src/main/java/com/yahoo/search/significance/SignificanceSearcher.java index 9c452a17c77..f6025dc6ba7 100644 --- a/container-search/src/main/java/com/yahoo/search/significance/SignificanceSearcher.java +++ b/container-search/src/main/java/com/yahoo/search/significance/SignificanceSearcher.java @@ -14,18 +14,16 @@ import com.yahoo.prelude.query.WordItem; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; -import com.yahoo.search.query.Ranking; +import com.yahoo.search.result.ErrorMessage; import com.yahoo.search.schema.RankProfile; import com.yahoo.search.schema.Schema; import com.yahoo.search.schema.SchemaInfo; import com.yahoo.search.searchchain.Execution; -import com.yahoo.vespa.config.search.RankProfilesConfig; -import java.util.Collection; -import java.util.HashMap; -import java.util.Objects; +import java.util.HashSet; import java.util.Optional; import java.util.logging.Logger; +import java.util.stream.Collectors; import static com.yahoo.prelude.querytransform.StemmingSearcher.STEMMING; @@ -54,22 +52,34 @@ public class SignificanceSearcher extends Searcher { @Override public Result search(Query query, Execution execution) { - // The query might apply to multiple schemas. - // If the rank profile name is present in multiple schemas we need to check if the configuration is consistent. var rankProfileName = query.getRanking().getProfile(); - var schemas = schemaInfo.newSession(query).schemas(); - var useSignficanceConfiguration = schemas.stream() - .map(schema -> schema.rankProfiles().get(rankProfileName)) - .filter(Objects::nonNull) - .map(RankProfile::useSignificanceModel) - .distinct().toList(); - if (useSignficanceConfiguration.size() != 1) { - log.fine(() -> "Inconsistent 'significance.use-model' configuration for rank profile '%s' in schemas %s. Fallback to disabled" - .formatted(rankProfileName, schemas.stream().map(Schema::name).toList())); - return execution.search(query); + + // Determine significance setup per schema for the given rank profile + var perSchemaSetup = schemaInfo.newSession(query).schemas().stream() + .collect(Collectors.toMap(Schema::name, schema -> + // Fallback to disabled if the rank profile is not found in the schema + // This will result in a failure later (in a "backend searcher") anyway. + Optional.ofNullable(schema.rankProfiles().get(rankProfileName)) + .map(RankProfile::useSignificanceModel).orElse(false))); + var uniqueSetups = new HashSet<>(perSchemaSetup.values()); + + // Fail if the significance setup for the selected schemas are conflicting + if (uniqueSetups.size() > 1) { + var result = new Result(query); + result.hits().addError( + ErrorMessage.createIllegalQuery( + ("Inconsistent 'significance' configuration for the rank profile '%s' in the schemas %s. " + + "Use 'restrict' to limit the query to a subset of schemas " + + "(https://docs.vespa.ai/en/schemas.html#multiple-schemas). " + + "Specify same 'significance' configuration for all selected schemas " + + "(https://docs.vespa.ai/en/reference/schema-reference.html#significance).") + .formatted(rankProfileName, perSchemaSetup.keySet()))); + return result; } - if (!useSignficanceConfiguration.get(0)) return execution.search(query); + if (perSchemaSetup.isEmpty()) return execution.search(query); + var useSignificanceModel = uniqueSetups.iterator().next(); + if (!useSignificanceModel) return execution.search(query); Language language = query.getModel().getParsingLanguage(); Optional<SignificanceModel> model = significanceModelRegistry.getModel(language); diff --git a/container-search/src/test/java/com/yahoo/search/significance/test/SignificanceSearcherTest.java b/container-search/src/test/java/com/yahoo/search/significance/test/SignificanceSearcherTest.java index abda1df473f..cb5722074ff 100644 --- a/container-search/src/test/java/com/yahoo/search/significance/test/SignificanceSearcherTest.java +++ b/container-search/src/test/java/com/yahoo/search/significance/test/SignificanceSearcherTest.java @@ -166,4 +166,36 @@ public class SignificanceSearcherTest { assertEquals(w0_1.getSignificance(), w1.getSignificance()); } + + @Test + public void failsOnConflictingSignificanceConfiguration() { + var musicSchema = new Schema.Builder("music") + .add(new DocumentSummary.Builder("default").build()) + .add(new RankProfile.Builder("significance-ranking") + .setUseSignificanceModel(true) + .build()) + .build(); + var albumSchema = new Schema.Builder("album") + .add(new DocumentSummary.Builder("default").build()) + .add(new RankProfile.Builder("significance-ranking") + .setUseSignificanceModel(false) + .build()) + .build(); + var searcher = new SignificanceSearcher( + significanceModelRegistry, new SchemaInfo(List.of(musicSchema, albumSchema), List.of())); + + var query = new Query(); + query.getRanking().setProfile("significance-ranking"); + + var result = createExecution(searcher).search(query); + assertEquals(1, result.hits().getErrorHit().errors().size()); + + var errorMessage = result.hits().getError(); + assertEquals("Inconsistent 'significance' configuration for the rank profile 'significance-ranking' in the schemas [music, album]. " + + "Use 'restrict' to limit the query to a subset of schemas " + + "(https://docs.vespa.ai/en/schemas.html#multiple-schemas). " + + "Specify same 'significance' configuration for all selected schemas " + + "(https://docs.vespa.ai/en/reference/schema-reference.html#significance).", + errorMessage.getDetailedMessage()); + } } |