Skip to content

Commit

Permalink
Treat nil values as empty predicate
Browse files Browse the repository at this point in the history
  • Loading branch information
acerbusace committed Oct 30, 2024
1 parent 0e5352a commit b59c2fc
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,6 @@ def to_s

def process_filter_hash(bool_node, filter_hash, field_path)
filter_hash.each do |field_or_op, expression|
# `nil` filter predicates should be ignored, so we can safely `compact` them out.
# It also is simpler to handle them once here instead of the different branches
# below having to be aware of possible `nil` predicates.
expression = expression.compact if expression.is_a?(::Hash)

case filter_node_interpreter.identify_node_type(field_or_op, expression)
when :empty
# This is an "empty" filter predicate and we can ignore it.
Expand Down Expand Up @@ -313,7 +308,7 @@ def process_list_count_expression(bool_node, expression, field_path)
# While we index an explicit count of 0, the count field will be missing from documents indexed before
# the list field was defined on the ElasticGraph schema. To properly match those documents, we need to
# convert this into an OR (using `any_of`) to also match documents that lack the field entirely.
unless excludes_zero?(expression)
if filters_to_range_including_zero?(expression)
expression = {schema_names.any_of => [
expression,
{schema_names.equal_to_any_of => [nil]}
Expand All @@ -337,23 +332,31 @@ def build_bool_hash(&block)
{bool: bool_node}
end

# Determines if the given filter expression excludes the value `0`.
def excludes_zero?(expression)
expression.any? do |operator, operand|
case operator
when schema_names.equal_to_any_of then !operand.include?(0)
when schema_names.lt then operand <= 0
when schema_names.lte then operand < 0
when schema_names.gt then operand >= 0
when schema_names.gte then operand > 0
else
# :nocov: -- all operators are covered above. But simplecov complains about an implicit `else` branch being uncovered, so here we've defined it to wrap it with `:nocov:`.
false
# :nocov:
end
# Determines if the given expression filters to a range that includes `0`.
# If it does not do any filtering (e.g. an empty expression) it will return `false`.
def filters_to_range_including_zero?(expression)
expression = expression.compact

expression.size > 0 && expression.none? do |operator, operand|
operator_excludes_zero?(operator, operand)
end
end

# Determines if the given operator and operand exclude 0 as a matched value.
def operator_excludes_zero?(operator, operand)
case operator
when schema_names.equal_to_any_of then !operand.include?(0)
when schema_names.lt then operand <= 0
when schema_names.lte then operand < 0
when schema_names.gt then operand >= 0
when schema_names.gte then operand > 0
else
# :nocov: -- all operators are covered above. But simplecov complains about an implicit `else` branch being uncovered, so here we've defined it to wrap it with `:nocov:`.
false
# :nocov:
end
end

# Counts how many clauses in `bool_query` are required to match for a document to be a search hit.
def required_matching_clause_count(bool_query)
bool_query.reduce(0) do |count, (occurrence, clauses)|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ module ElasticGraph
def process_sub_field_expression: (stringOrSymbolHash, stringHash, FieldPath) -> void
def process_list_count_expression: (stringOrSymbolHash, stringHash, FieldPath) -> void
def build_bool_hash: () { (stringOrSymbolHash) -> void } -> stringOrSymbolHash?
def excludes_zero?: (stringHash) -> bool
def filters_to_range_including_zero?: (stringHash) -> bool
def operator_excludes_zero?: (::String, untyped) -> bool
def required_matching_clause_count: (stringOrSymbolHash) -> ::Integer
end
end
Expand Down

0 comments on commit b59c2fc

Please sign in to comment.