# Contains Checks if a string value contains a substring, or if an array contains an element. ## Overview The `contains` condition evaluates whether a field's value contains a specified substring (for strings) or element (for arrays). This is useful for partial matching scenarios where you need to find records containing specific text patterns or array elements. ## Use Cases - **Log Filtering**: Find log entries containing specific error messages or keywords - **Tag Matching**: Route records that have certain tags in an array - **Content Classification**: Identify records with specific content patterns - **Search-like Routing**: Route based on partial text matches ## Configuration | Setting | Type | Required | Description | | ------------------ | ------- | -------- | -------------------------------------------------------------------------------------------- | | `key` | string | Yes | The field path to check. Supports dot notation for nested fields. Use `*` to check all keys.| | `value` | string | Yes | The substring or element to search for. | | `case_insensitive` | boolean | No | If `true`, performs case-insensitive comparison. | | `raw` | boolean | No | If `true`, treats the entire field as a raw string and performs substring matching. | | `not` | boolean | No | If `true`, inverts the condition (matches if value is NOT contained). | ## Examples ### Basic Substring Check Check if a message contains "error": ```json { "type_id": "contains", "config": { "key": "message", "value": "error" } } ``` **Matches:** ```json {"message": "An error occurred during processing"} {"message": "error: connection timeout"} {"message": "Fatal error in module X"} ``` **Does not match:** ```json {"message": "Processing completed successfully"} {"message": "Warning: disk space low"} ``` ### Case-Insensitive Matching Match regardless of case: ```json { "type_id": "contains", "config": { "key": "status", "value": "fail", "case_insensitive": true } } ``` **Matches:** ```json {"status": "FAILED"} {"status": "failure"} {"status": "Fail"} ``` ### Array Element Check Check if an array contains a specific element: ```json { "type_id": "contains", "config": { "key": "tags", "value": "production" } } ``` **Matches:** ```json {"tags": ["production", "critical"]} {"tags": ["web", "production", "us-east"]} ``` **Does not match:** ```json {"tags": ["staging", "test"]} {"tags": []} ``` ### Nested Field Check Check substring in a nested field: ```json { "type_id": "contains", "config": { "key": "user.email", "value": "@company.com" } } ``` **Matches:** ```json {"user": {"email": "john@company.com"}} {"user": {"email": "admin@company.com"}} ``` **Does not match:** ```json {"user": {"email": "john@gmail.com"}} ``` ### Exclusion Check Match records that do NOT contain a value: ```json { "type_id": "contains", "config": { "key": "message", "value": "debug", "not": true } } ``` **Matches:** ```json {"message": "User logged in successfully"} {"message": "Order processed"} ``` **Does not match:** ```json {"message": "debug: entering function"} {"message": "DEBUG output enabled"} ``` ### Wildcard Key Check Check if any field contains a value: ```json { "type_id": "contains", "config": { "key": "*", "value": "sensitive" } } ``` **Matches:** ```json {"data": "contains sensitive information"} {"notes": "marked as sensitive"} ``` ### Object Value Check Check if any value in an object matches: ```json { "type_id": "contains", "config": { "key": "metadata", "value": "error" } } ``` **Matches:** ```json {"metadata": {"status": "error", "code": 500}} {"metadata": {"message": "success", "type": "error"}} ``` **Does not match (partial values don't match):** ```json {"metadata": {"status": "error_occurred"}} ``` ### Raw Mode - Substring in Arrays Use `raw` mode to find substrings within array elements: ```json { "type_id": "contains", "config": { "key": "results", "value": "error", "raw": true } } ``` **Matches:** ```json {"results": ["success - task completed", "error - connection failed"]} {"results": ["error_timeout", "warning"]} ``` **Without `raw`, this would NOT match** because no array element exactly equals "error". ### Raw Mode - Search in Complex Structures Search for text anywhere in a complex structure: ```json { "type_id": "contains", "config": { "key": "data", "value": "critical", "raw": true } } ``` **Matches:** ```json {"data": {"alerts": [{"level": "critical"}]}} {"data": ["warning", "critical", "info"]} {"data": "critical error occurred"} ``` ## Common Patterns ### Error Log Routing Route logs containing error indicators: ```json { "operator": "or", "conditions": [ {"type_id": "contains", "config": {"key": "message", "value": "error", "case_insensitive": true}}, {"type_id": "contains", "config": {"key": "message", "value": "exception", "case_insensitive": true}}, {"type_id": "contains", "config": {"key": "message", "value": "failed", "case_insensitive": true}} ] } ``` ### Domain-Based Routing Route emails by domain: ```json { "operator": "and", "conditions": [ {"type_id": "key_exists", "config": {"key": "email"}}, {"type_id": "contains", "config": {"key": "email", "value": "@internal.company.com"}} ] } ``` ### Tag-Based Filtering Route records with specific tags: ```json { "operator": "and", "conditions": [ {"type_id": "contains", "config": {"key": "tags", "value": "high-priority"}}, {"type_id": "contains", "config": {"key": "tags", "value": "customer-facing"}} ] } ``` ### Exclude Debug/Test Data Filter out debug and test records: ```json { "operator": "and", "conditions": [ {"type_id": "contains", "config": {"key": "message", "value": "debug", "case_insensitive": true, "not": true}}, {"type_id": "contains", "config": {"key": "source", "value": "test", "case_insensitive": true, "not": true}} ] } ``` ## Best Practices 1. **Use `case_insensitive` for text searches**: Log messages and user-generated content often have inconsistent casing. 2. **Be specific with substrings**: Short substrings like "a" or "in" will match many records unintentionally. 3. **Combine with other conditions**: Use with `key_exists` to handle missing fields gracefully. 4. **Consider `starts_with` or `ends_with`**: If you need to match at specific positions, use more specific conditions. 5. **Use `matches_regex` for complex patterns**: For patterns more complex than simple substring matching. ## Type Handling ### Default Behavior (`raw: false`) | Type | Behavior | |------|----------| | Strings | Substring matching | | Arrays | Exact element matching (checks if any element equals the value) | | Objects | Exact value matching (checks if any object value equals the value) | | Numbers/Booleans | Substring matching on string representation | | Missing fields | Returns `false` (or `true` if `not` is set) | ### Raw Mode (`raw: true`) When `raw` is enabled, the entire field value is treated as a raw string and substring matching is performed. This is useful for searching within arrays or objects without requiring exact matches. | Type | Behavior | |------|----------| | All types | Substring matching on the raw JSON representation | ## Limitations - Simple substring matching only (no wildcards or patterns) - Default array/object matching is exact (use `raw: true` for substring within elements) - `raw` mode matches against JSON representation, which includes syntax characters like `[`, `]`, `"`, `,` ## Troubleshooting **Not matching expected records:** - Check case sensitivity settings - Verify the exact substring (watch for spaces) - Ensure the field path is correct **Too many matches:** - Make the search string more specific - Add additional conditions to narrow results - Consider using `starts_with` or `ends_with` for positional matching **Array/Object matching not working as expected:** - Default behavior uses exact element/value matching - Use `raw: true` to search for substrings within array elements or object values - Example: `["error - failed"]` won't match `"error"` by default, but will with `raw: true` **Raw mode matching unexpected content:** - Raw mode searches the JSON representation, including syntax characters - Searching for `","` would match any array with multiple elements - Be specific with search terms to avoid false positives