# Equals Any Checks if a field's value matches any of the provided values. ## Overview The `equals_any` condition evaluates whether a specific field in a record contains one of several acceptable values. It's ideal for routing based on categories, statuses, regions, or any field with a defined set of possible values. ## Use Cases - **Status-based Routing**: Route records based on order status, user state, or processing stage - **Geographic Distribution**: Direct data to regional endpoints based on country or region codes - **Priority Handling**: Route high-priority items to dedicated processing queues - **Customer Segmentation**: Handle different customer tiers or types separately - **Environment Separation**: Keep production, staging, and test data in separate streams ## Configuration | Setting | Type | Required | Description | | ------------------ | -------- | -------- | -------------------------------------------------------------------------------------------- | | `key` | string | Yes | The field path to check. Supports dot notation for nested fields. Use `*` to check all keys.| | `values` | array | Yes | Array of acceptable values. The condition matches if the field equals any of these values. | | `case_insensitive` | boolean | No | If `true`, performs case-insensitive string comparison. | | `not` | boolean | No | If `true`, inverts the condition (matches if value is NOT in the list). | ### Values Format Internally, all values are stored as strings. This means `123` matches both the number `123` and the string `"123"` in your data. To match only a specific type, wrap the value in quotes: | Input | Matches | |-------|---------| | `hello` | `"hello"` | | `123` | `123` (number) and `"123"` (string) | | `"123"` | `"123"` (string only, not the number `123`) | | `true` | `true` (boolean) and `"true"` (string) | | `"true"` | `"true"` (string only, not the boolean `true`) | | `["a","b"]` | `["a","b"]` or `["b","a"]` (order-independent) | | `{"k":"v"}` | `{"k":"v"}` | Use quotes when you need to distinguish between a string and its numeric or boolean equivalent. ## Examples ### Simple Value Matching Route based on status: ```json { "type_id": "equals_any", "config": { "key": "status", "values": ["active", "pending"] } } ``` **Matches:** ```json {"status": "active", "user_id": "123"} {"status": "pending", "user_id": "456"} ``` **Does not match:** ```json {"status": "inactive", "user_id": "789"} {"status": "deleted", "user_id": "012"} {"user_id": "345"} ``` ### Nested Field Matching Check values in nested objects: ```json { "type_id": "equals_any", "config": { "key": "user.account.type", "values": ["premium", "enterprise"] } } ``` **Matches:** ```json { "user": { "account": { "type": "premium" } } } ``` ### Multiple Values Route records from multiple regions: ```json { "type_id": "equals_any", "config": { "key": "region", "values": ["us-east", "us-west", "us-central"] } } ``` **Matches any of:** ```json {"region": "us-east", "data": "..."} {"region": "us-west", "data": "..."} {"region": "us-central", "data": "..."} ``` ### Case-Insensitive Matching Match status values regardless of case: ```json { "type_id": "equals_any", "config": { "key": "status", "values": ["active", "pending"], "case_insensitive": true } } ``` **Matches:** ```json {"status": "Active", "id": "1"} {"status": "PENDING", "id": "2"} {"status": "active", "id": "3"} ``` ### Exclusion Matching Route records that are NOT in a specific set: ```json { "type_id": "equals_any", "config": { "key": "environment", "values": ["test", "staging", "development"], "not": true } } ``` **Matches:** ```json {"environment": "production", "data": "..."} ``` **Does not match:** ```json {"environment": "test", "data": "..."} {"environment": "staging", "data": "..."} ``` ### Numeric Values Match specific numeric values: ```json { "type_id": "equals_any", "config": { "key": "priority", "values": ["1", "2"] } } ``` **Note**: Numbers in the record are converted to strings for comparison, so this will match `{"priority": 1}` as well as `{"priority": "1"}`. ## Common Patterns ### Status-Based Routing Route different order statuses to appropriate handlers: ```json { "operator": "and", "conditions": [ {"type_id": "equals_any", "config": {"key": "type", "values": ["order"]}}, {"type_id": "equals_any", "config": {"key": "status", "values": ["paid", "processing"]}} ] } ``` ### Multi-Region Distribution Route data to region-specific endpoints: ```json { "operator": "or", "conditions": [ {"type_id": "equals_any", "config": {"key": "country", "values": ["GB", "FR", "DE", "IT", "ES"]}}, {"type_id": "equals_any", "config": {"key": "region", "values": ["eu-west", "eu-central"]}} ] } ``` ### Environment Filtering Separate production from non-production data: ```json { "operator": "and", "conditions": [ {"type_id": "equals_any", "config": {"key": "environment", "values": ["production"]}}, {"type_id": "equals_any", "config": {"key": "severity", "values": ["error", "critical", "warning"]}} ] } ``` ### Exclude Non-Production Data Filter out test and development records: ```json { "operator": "and", "conditions": [ { "type_id": "equals_any", "config": { "key": "environment", "values": ["test", "development", "staging"], "not": true } } ] } ``` ## Best Practices 1. **Use `case_insensitive` when appropriate**: If your data may have inconsistent casing, enable case-insensitive matching to avoid missed matches. 2. **Handle Missing Fields**: If the field doesn't exist in the record, the condition returns `false` (or `true` if `not` is set). Consider combining with `key_exists` if you need to handle missing fields differently. 3. **Minimize Value Lists**: Very long lists of values can impact readability. Consider restructuring your data if you need many values. 4. **Use Consistent Formats**: Standardize value formats (e.g., always lowercase status values) to simplify matching. 5. **Use `not` for exclusions**: Instead of listing all values you DO want, sometimes it's easier to list the ones you DON'T want with `not: true`. ## Type Handling The condition handles different value types as follows: - **Strings**: Direct comparison (case-sensitive by default) - **Numbers**: Converted to strings for comparison - **Booleans**: Compared against "true" or "false" strings - **Nulls**: Field exists but won't match any value in the list - **Arrays/Objects**: Supported with deep equality comparison ## Limitations - No wildcard or pattern matching (use `matches_regex` for patterns) - No numeric range comparisons (use `greater_than`/`less_than`) ## Troubleshooting **Values not matching:** - Check for exact case matching (use `case_insensitive: true` if needed) - Verify the field path is correct - Look for trailing spaces or hidden characters **Numeric comparisons failing:** - Numbers are converted to strings: "10" and "10.0" may differ - Leading zeros matter: "01" ≠ "1" - Use consistent number formats **Boolean fields not matching:** - Use "true" and "false" as string values - Check your data serialization format