浏览代码

[Query Rules] Fix bug where combining the same metadata with text/numeric values leads to error (#102891)

* Fix issue where query rule criteria with matching metadata but different types returns error

* Update docs/changelog/102891.yaml
Kathleen DeRusso 1 年之前
父节点
当前提交
84dad0279c

+ 7 - 0
docs/changelog/102891.yaml

@@ -0,0 +1,7 @@
+pr: 102891
+summary: "[Query Rules] Fix bug where combining the same metadata with text/numeric\
+  \ values leads to error"
+area: Application
+type: bug
+issues:
+ - 102827

+ 42 - 0
x-pack/plugin/ent-search/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/entsearch/260_rule_query_search.yml

@@ -194,4 +194,46 @@ setup:
   - match: { hits.hits.0._id: 'doc2' }
   - match: { hits.hits.1._id: 'doc3' }
 
+---
+"Perform a rule query over a ruleset with combined numeric and text rule matching":
+
+  - do:
+      query_ruleset.put:
+        ruleset_id: combined-ruleset
+        body:
+          rules:
+            - rule_id: rule1
+              type: pinned
+              criteria:
+                - type: fuzzy
+                  metadata: foo
+                  values: [ bar ]
+              actions:
+                ids:
+                  - 'doc1'
+            - rule_id: rule2
+              type: pinned
+              criteria:
+                - type: lte
+                  metadata: foo
+                  values: [ 100 ]
+              actions:
+                ids:
+                  - 'doc2'
+  - do:
+      search:
+        body:
+          query:
+            rule_query:
+              organic:
+                query_string:
+                  default_field: text
+                  query: blah blah blah
+              match_criteria:
+                foo: baz
+              ruleset_id: combined-ruleset
+
+  - match: { hits.total.value: 1 }
+  - match: { hits.hits.0._id: 'doc1' }
+
 

+ 1 - 1
x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRule.java

@@ -294,7 +294,7 @@ public class QueryRule implements Writeable, ToXContentObject {
                 final String criteriaMetadata = criterion.criteriaMetadata();
 
                 if (criteriaType == ALWAYS || (criteriaMetadata != null && criteriaMetadata.equals(match))) {
-                    boolean singleCriterionMatches = criterion.isMatch(matchValue, criteriaType);
+                    boolean singleCriterionMatches = criterion.isMatch(matchValue, criteriaType, false);
                     isRuleMatch = (isRuleMatch == null) ? singleCriterionMatches : isRuleMatch && singleCriterionMatches;
                 }
             }

+ 8 - 1
x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRuleCriteria.java

@@ -191,12 +191,19 @@ public class QueryRuleCriteria implements Writeable, ToXContentObject {
     }
 
     public boolean isMatch(Object matchValue, QueryRuleCriteriaType matchType) {
+        return isMatch(matchValue, matchType, true);
+    }
+
+    public boolean isMatch(Object matchValue, QueryRuleCriteriaType matchType, boolean throwOnInvalidInput) {
         if (matchType == ALWAYS) {
             return true;
         }
         final String matchString = matchValue.toString();
         for (Object criteriaValue : criteriaValues) {
-            matchType.validateInput(matchValue);
+            boolean isValid = matchType.validateInput(matchValue, throwOnInvalidInput);
+            if (isValid == false) {
+                return false;
+            }
             boolean matchFound = matchType.isMatch(matchString, criteriaValue);
             if (matchFound) {
                 return true;

+ 7 - 2
x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/rules/QueryRuleCriteriaType.java

@@ -86,11 +86,16 @@ public enum QueryRuleCriteriaType {
         }
     };
 
-    public void validateInput(Object input) {
+    public boolean validateInput(Object input, boolean throwOnInvalidInput) {
         boolean isValid = isValidForInput(input);
-        if (isValid == false) {
+        if (isValid == false && throwOnInvalidInput) {
             throw new IllegalArgumentException("Input [" + input + "] is not valid for CriteriaType [" + this + "]");
         }
+        return isValid;
+    }
+
+    public boolean validateInput(Object input) {
+        return validateInput(input, true);
     }
 
     public abstract boolean isMatch(Object input, Object criteriaValue);