Skip to content

Multi-Valued Field Evaluation

The evaluation engine handles fields that contain lists or nested lists of values.

  • Comparison operators (==, >, <, etc.) use "any" semantics: True if any value in the list meets the criteria.
  • Inequality (!=) uses "none" semantics: True if no value in the list meets the criteria.

Examples

from therismos import F, unwind_data

tags = F("tags")
scores = F("scores", int)

# Equality: True if "python" is ANY of the tags
expr_eq = tags == "python"
assert expr_eq.evaluate(unwind_data({"tags": ["java", "python", "rust"]})) is True

# Inequality: True if "python" is NONE of the tags
expr_ne = tags != "python"
assert expr_ne.evaluate(unwind_data({"tags": ["java", "rust"]})) is True
assert expr_ne.evaluate(unwind_data({"tags": ["java", "python"]})) is False

# Greater Than: True if ANY score is > 80
expr_gt = scores > 80
assert expr_gt.evaluate(unwind_data({"scores": [60, 75, 90]})) is True

# Nested lists are flattened automatically
assert expr_gt.evaluate(unwind_data({"scores": [[60, 75], [90, 40]]})) is True

Membership and Regex on Multi-Valued Fields

is_in and matches return True if any value in the field's list satisfies the condition:

import re

status = F("status")
expr = status.is_in("active", "pending", "approved")
result = expr.evaluate(unwind_data({"status": "active"}))  # True

log_messages = F("logs")
expr = log_messages.matches(r"ERROR:", re.IGNORECASE)
data = {"logs": ["INFO: User logged in", "ERROR: Connection failed"]}
result = expr.evaluate(unwind_data(data))  # True — one message matches

phone = F("phone")
expr = phone.is_null()
result = expr.evaluate(unwind_data({"phone": None}))  # True