Skip to content

Commit

Permalink
[Query Rules] Fix bug where combining the same metadata with text/num…
Browse files Browse the repository at this point in the history
…eric values leads to error (elastic#102891)

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

* Update docs/changelog/102891.yaml
  • Loading branch information
kderusso authored Dec 4, 2023
1 parent d3fefde commit 84dad02
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 4 deletions.
7 changes: 7 additions & 0 deletions docs/changelog/102891.yaml
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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' }


Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ public AppliedQueryRules applyRule(AppliedQueryRules appliedRules, Map<String, O
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;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,19 @@ public String toString() {
}

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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,16 @@ public boolean isMatch(Object input, Object criteriaValue) {
}
};

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);
Expand Down

0 comments on commit 84dad02

Please sign in to comment.