From ba9c585fd0bf23ff4c1a581ceb9559716a40fcae Mon Sep 17 00:00:00 2001 From: Kathleen DeRusso Date: Mon, 18 Mar 2024 14:51:50 -0400 Subject: [PATCH] Synonyms work with hardcoded index name --- .../xpack/application/rules/QueryRule.java | 4 +- .../application/rules/QueryRuleCriteria.java | 14 +++--- .../rules/QueryRuleCriteriaType.java | 44 +++++++------------ .../rules/QueryRulesAnalysisConfig.java | 24 ++++------ .../rules/QueryRulesAnalysisService.java | 40 +++++++++++------ .../application/rules/RuleQueryBuilder.java | 2 +- 6 files changed, 58 insertions(+), 70 deletions(-) diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRule.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRule.java index 9a7bd28533c13..7fa8554ebb93c 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRule.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRule.java @@ -278,7 +278,7 @@ public String toString() { } @SuppressWarnings("unchecked") - public AppliedQueryRules applyRule(Client client, AppliedQueryRules appliedRules, Map matchCriteria) { + public AppliedQueryRules applyRule(Client client, String index, AppliedQueryRules appliedRules, Map matchCriteria) { if (type != QueryRule.QueryRuleType.PINNED) { throw new UnsupportedOperationException("Only pinned query rules are supported"); } @@ -295,7 +295,7 @@ public AppliedQueryRules applyRule(Client client, AppliedQueryRules appliedRules final String criteriaMetadata = criterion.criteriaMetadata(); if (criteriaType == ALWAYS || (criteriaMetadata != null && criteriaMetadata.equals(match))) { - boolean singleCriterionMatches = criterion.isMatch(client, matchValue, criteriaType, false); + boolean singleCriterionMatches = criterion.isMatch(client, index, matchValue, criteriaType, false); isRuleMatch = (isRuleMatch == null) ? singleCriterionMatches : isRuleMatch && singleCriterionMatches; } } diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRuleCriteria.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRuleCriteria.java index f2dd9066bbbc8..4dfbbfbc02dbe 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRuleCriteria.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRuleCriteria.java @@ -18,8 +18,6 @@ import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.core.Nullable; -import org.elasticsearch.logging.LogManager; -import org.elasticsearch.logging.Logger; import org.elasticsearch.xcontent.ConstructingObjectParser; import org.elasticsearch.xcontent.ParseField; import org.elasticsearch.xcontent.ToXContentObject; @@ -48,8 +46,6 @@ public class QueryRuleCriteria implements Writeable, ToXContentObject { private final List criteriaValues; private final Map criteriaProperties; - private static final Logger logger = LogManager.getLogger(QueryRuleCriteria.class); - /** * * @param criteriaType The {@link QueryRuleCriteriaType}, indicating how the criteria is matched @@ -82,7 +78,7 @@ public QueryRuleCriteria( this.criteriaType = criteriaType; this.criteriaProperties = criteriaProperties == null ? Map.of() : criteriaProperties; - // TODO criteriaType.validateProperties(criteriaProperties); + // TODO validate properties } @@ -225,11 +221,11 @@ public String toString() { return Strings.toString(this); } - public boolean isMatch(Client client, Object matchValue, QueryRuleCriteriaType matchType) { - return isMatch(client, matchValue, matchType, true); + public boolean isMatch(Client client, String index, Object matchValue, QueryRuleCriteriaType matchType) { + return isMatch(client, index, matchValue, matchType, true); } - public boolean isMatch(Client client, Object matchValue, QueryRuleCriteriaType matchType, boolean throwOnInvalidInput) { + public boolean isMatch(Client client, String index, Object matchValue, QueryRuleCriteriaType matchType, boolean throwOnInvalidInput) { if (matchType == ALWAYS) { return true; } @@ -240,7 +236,7 @@ public boolean isMatch(Client client, Object matchValue, QueryRuleCriteriaType m return false; } QueryRulesAnalysisService analysisService = new QueryRulesAnalysisService(client); - boolean matchFound = matchType.isMatch(analysisService, matchString, criteriaValue, criteriaProperties); + boolean matchFound = matchType.isMatch(analysisService, index, matchString, criteriaValue, criteriaProperties); if (matchFound) { return true; } diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRuleCriteriaType.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRuleCriteriaType.java index 212a154920bf4..7702e9aa9603b 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRuleCriteriaType.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRuleCriteriaType.java @@ -27,35 +27,8 @@ public boolean isMatch(Object input, Object criteriaValue, Map c EXACT { @Override public boolean isMatch(Object input, Object criteriaValue, Map criteriaProperties) { - throw new UnsupportedOperationException("[" + this + "] criteria type requires analysis service"); - } - - @Override - public boolean isMatch( - QueryRulesAnalysisService analysisService, - Object input, - Object criteriaValue, - Map criteriaProperties - ) { if (input instanceof String && criteriaValue instanceof String) { - - if (criteriaProperties.containsKey("analysis")) { - @SuppressWarnings("unchecked") - List> analysisChain = (List>) criteriaProperties.get("analysis"); - String analyzedInput = (String) input; - String analyzedCriteriaValue = (String) criteriaValue; - for (Map analysisConfig : analysisChain) { - String tokenizer = analysisConfig.containsKey("tokenizer") ? (String) analysisConfig.get("tokenizer") : "keyword"; - String filter = analysisConfig.containsKey("filter") ? (String) analysisConfig.get("filter") : "lowercase"; - QueryRulesAnalysisConfig config = new QueryRulesAnalysisConfig(null, tokenizer, List.of(filter)); - analyzedInput = analysisService.analyze(analyzedInput, config); - analyzedCriteriaValue = analysisService.analyze(analyzedCriteriaValue, config); - } - return analyzedInput.equals(analyzedCriteriaValue); - } else { - return input.equals(criteriaValue); - } - + return input.equals(criteriaValue); } else { return parseDouble(input) == parseDouble(criteriaValue); } @@ -131,11 +104,24 @@ public void validateInput(Object input) { public boolean isMatch( QueryRulesAnalysisService analysisService, + String index, Object input, Object criteriaValue, Map criteriaProperties ) { - return isMatch(input, criteriaValue, criteriaProperties); + if (criteriaProperties.containsKey("analysis")) { + @SuppressWarnings("unchecked") + List> analysisChain = (List>) criteriaProperties.get("analysis"); + QueryRulesAnalysisService.AnalyzedContent analyzedContent = analysisService.analyzeContent( + analysisChain, + index, + (String) input, + (String) criteriaValue + ); + return isMatch(analyzedContent.analyzedInput(), analyzedContent.analyzedCriteriaValue(), criteriaProperties); + } else { + return isMatch(input, criteriaValue, criteriaProperties); + } } public static QueryRuleCriteriaType type(String criteriaType) { diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRulesAnalysisConfig.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRulesAnalysisConfig.java index 2cfec219e6939..bcc64835e9a33 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRulesAnalysisConfig.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRulesAnalysisConfig.java @@ -8,29 +8,23 @@ package org.elasticsearch.xpack.application.rules; import java.util.List; +import java.util.Map; -public class QueryRulesAnalysisConfig { - - private final String analyzer; - private final String tokenizer; - private final List filters; +public record QueryRulesAnalysisConfig(String analyzer, String tokenizer, List filters) { public QueryRulesAnalysisConfig(String analyzer, String tokenizer, List filters) { this.analyzer = analyzer; this.tokenizer = tokenizer; - this.filters = filters; - } - - public String analyzer() { - return analyzer; + this.filters = filters == null ? List.of() : filters; } - public String tokenizer() { - return tokenizer; - } + public static QueryRulesAnalysisConfig fromMap(Map configurationAttributes) { + String analyzer = (String) configurationAttributes.get("analyzer"); + String tokenizer = (String) configurationAttributes.get("tokenizer"); + @SuppressWarnings("unchecked") + List filters = (List) configurationAttributes.getOrDefault("filters", List.of()); + return new QueryRulesAnalysisConfig(analyzer, tokenizer, filters); - public List filters() { - return filters; } } diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRulesAnalysisService.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRulesAnalysisService.java index 491c582e24baa..91f082ef1cfe3 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRulesAnalysisService.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRulesAnalysisService.java @@ -15,6 +15,8 @@ import org.elasticsearch.logging.Logger; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import static org.elasticsearch.xpack.core.ClientHelper.ENT_SEARCH_ORIGIN; @@ -30,27 +32,37 @@ public QueryRulesAnalysisService(Client client) { this.clientWithOrigin = new OriginSettingClient(client, ENT_SEARCH_ORIGIN); } - public String analyze(String text, QueryRulesAnalysisConfig analysisConfig) { - - logger.info("Analyzing original text [" + text + "]"); - + public String analyze(String index, String text, QueryRulesAnalysisConfig analysisConfig) { String analyzer = analysisConfig.analyzer(); String tokenizer = analysisConfig.tokenizer(); List filters = analysisConfig.filters(); - - AnalyzeAction.Request analyzeRequest = new AnalyzeAction.Request().analyzer(analyzer) - .tokenizer(tokenizer) - .addTokenFilters(filters) - .text(text); + AnalyzeAction.Request analyzeRequest = new AnalyzeAction.Request().text(text).index(index); + if (analyzer != null) { + analyzeRequest.analyzer(analyzer); + } + if (tokenizer != null) { + analyzeRequest.tokenizer(tokenizer); + } + if (filters != null) { + analyzeRequest.addTokenFilters(filters); + } AnalyzeAction.Response analyzeResponse = clientWithOrigin.execute(AnalyzeAction.INSTANCE, analyzeRequest).actionGet(TIMEOUT_MS); List analyzeTokens = analyzeResponse.getTokens(); - StringBuilder sb = new StringBuilder(); - for (AnalyzeAction.AnalyzeToken analyzeToken : analyzeTokens) { - logger.info("Analyzed term: [" + analyzeToken.getTerm() + "]"); - sb.append(analyzeToken.getTerm()).append(" "); + return analyzeTokens.stream().map(AnalyzeAction.AnalyzeToken::getTerm).collect(Collectors.joining(" ")); + } + public AnalyzedContent analyzeContent(List> analysisChain, String index, String input, String criteriaValue) { + String analyzedInput = input; + String analyzedCriteriaValue = criteriaValue; + for (Map analysisConfig : analysisChain) { + QueryRulesAnalysisConfig analysisConfigObj = QueryRulesAnalysisConfig.fromMap(analysisConfig); + analyzedInput = analyze(index, analyzedInput, analysisConfigObj); + analyzedCriteriaValue = analyze(index, analyzedCriteriaValue, analysisConfigObj); + logger.info("analyzedInput: " + analyzedInput + "; analyzedCriteriaValue: " + analyzedCriteriaValue); } - return sb.toString().trim(); + return new AnalyzedContent(analyzedInput, analyzedCriteriaValue); } + public record AnalyzedContent(String analyzedInput, String analyzedCriteriaValue) {} + } diff --git a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/RuleQueryBuilder.java b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/RuleQueryBuilder.java index 5208921a93426..876a3829c4867 100644 --- a/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/RuleQueryBuilder.java +++ b/x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/RuleQueryBuilder.java @@ -213,7 +213,7 @@ protected QueryBuilder doRewrite(QueryRewriteContext queryRewriteContext) { QueryRuleset queryRuleset = QueryRuleset.fromXContentBytes(rulesetId, getResponse.getSourceAsBytesRef(), XContentType.JSON); for (QueryRule rule : queryRuleset.rules()) { - rule.applyRule(client, appliedRules, matchCriteria); + rule.applyRule(client, "test", appliedRules, matchCriteria); } pinnedIdsSetOnce.set(appliedRules.pinnedIds().stream().distinct().toList()); pinnedDocsSetOnce.set(appliedRules.pinnedDocs().stream().distinct().toList());