Data Types
Data adapters assign types to extracted fields. Understanding these types helps you write correct queries and transformations.
string Text of any length "hello", "user@example.com" number Integers and floats 42, 3.14, -7 boolean True or false values true, false null Missing or undefined values null object Nested objects with properties {"key": "value"} array Arrays of mixed types ["a", "b", "c"] regex Regular expression patterns `^Error:.*` Literal Syntax
Section titled “Literal Syntax”| Type | Syntax | Example |
|---|---|---|
| String | Double quotes | "hello world" |
| Number | Bare numeric literal | 42, 3.14 |
| Boolean | Bare keyword | true, false |
| Regex | Backticks | `^Error:.*` |
| Column name with spaces | Single quotes | 'user name' |
| Null | Bare keyword | null |
Single-quoted strings ('...') are column name references, not string values. Use them when a field name contains spaces, dots, or reserved words:
| where 'user name' == "alice"
| eval 'http.status' = status
Backtick strings are regex literals and are only valid in positions that accept a regex (e.g., match(), controller param values, regex command):
| where match(message, `^Error:.*`)
namespace=`^prod-.*`
Null Handling
Section titled “Null Handling”Missing fields are represented as null. Null propagates through arithmetic and comparisons:
null + 5→nullnull == "x"→false(not an error)null == null→true
Use isNull() and isNotNull() in where to explicitly test for missing values:
| where isNotNull(user)
| where isNull(optional_field)
Type Coercion
Section titled “Type Coercion”QQL does not implicitly coerce types across categories. Arithmetic on a string field produces null:
| eval result = stringField / 1000 // → null if stringField is a string
To convert types, use the appropriate eval functions (e.g., toNumber(), toString()):
| eval duration_ms = toNumber(duration_str)
| eval duration_sec = duration_ms / 1000
Type Inference
Section titled “Type Inference”Adapters assign types to fields at ingestion time. The type assigned depends on the adapter and the underlying data:
- JSON fields with numeric values become
number. - JSON fields with
true/falsebecomeboolean. - Everything else defaults to
string. - Nested JSON objects become the
objecttype and can be flattened withunpack.
Type Conversion in Queries
Section titled “Type Conversion in Queries”When you evaluate expressions, result types depend on the operands:
| eval duration_sec = duration / 1000
If duration is a number, duration_sec is also a number. If duration is a string, duration_sec will be null.
| eval label = "status: " + status
String concatenation with + works when both sides are strings. If status is a number it will be coerced to string automatically in this context.
Types in where Expressions
Section titled “Types in where Expressions”Comparisons are type-aware:
| where duration > 1000 // numeric comparison
| where level == "error" // string equality
| where is_active == true // boolean comparison
| where match(msg, `^Err`) // regex test on string field
Comparing a string field with a number (e.g., stringField > 1000) will not match any records because the types differ.
Types in stats and timechart
Section titled “Types in stats and timechart”Aggregation functions require numeric fields:
sum(field),avg(field),min(field),max(field)— field must be numeric;nullvalues are ignored.count()— works on any type; counts non-null records.
| stats avg(duration) by service // duration must be numeric
| stats count() by level // level can be any type