Feedback:

where

Use the where operator to filter results.

Syntax

Note: AQL boolean arguments are case-insensitive, that is, all the following boolean arguments are valid:

Positive caseTrue, true, t

Negative caseFalse, false, f

|where <Boolean expression>

Typically, the where operator specifies a logical expression to evaluate field-value matching:

|where <field> <operator> <value>

|where [<field>] [earliest|latest]=[period], [earliest|latest]=[period]

|where [<field>] [earliest|latest]=[period] AND [earliest|latest]=[period]

|where timerange([period], [period], [field])

|where isnotnull(<field>)

|where isnull(<field>)

|where isnum(<field>)

|where isoutlier(<field>, [param], [uselower])

|where like(<field>, <pattern>)

|where match(<field>, <regex>)

|where mvfind(<field>, <regex>)

For subsearch| where [<field>] | [your_subsearch]

<field>
<operator>
  • You can use the following operators to match event fields with string values: !=, =, ==, contains, contains_ci, not contains, startswith, not startswith, endswith.

    • Use contains_ci to perform case insensitive matching for partial strings. If you need to match an event field with any value, you can use an asterisk.

      The following syntax is supported:

      |where contains_ci (*)

      Example:

      |where sourcetype contains_ci (*)

    • Use contains, contains_ci, startswith, and endswith to match an event field with multiple string values.

      The following syntax is supported:

      |where contains ('<string1>', '<string2>', ..., '<stringN>')

      Example:

      |where sourcetype contains ('aws', 'carbon', 'for', 'vpc')

  • You can use the REGEXP_LIKE operator to match a regular expression. Example:

    |where regexp_like(sourcetype, '^ts_*')

  • You can use the following operators to match event fields with date or numeric values (bytes_in, bytes_out, event_time, dest_port, src_port, and timestamp): >=, <=, >, <, !=, =, ==.

  • You can use the Boolean operator in to check if one of the values in the list matches a value that you specify.

    The following syntax is supported:

    |where in(<value>, [<list>])
    |where <value> in([<field list>])

    Example:

    |where status in("400", "401", "403", "404")
    |where "203.0.113.255" in(ipaddress, clientip)

  • You can use the insubnet operator to match IPv4 addresses that belong to the specified IPv4 subnet. For example:
    |where not src contains ":" |where src insubnet "192.168.0.0/16"

    The insubnet operator does not support IPv6 subnets.

  • You can use the is null operator to show results having null values and the is not null operator to exclude results having null values.

<value> The event log value.
[your_subsearch] The subsearch embedded within the primary search, inside square brackets ( [] ). See Subsearch documentation for more information.

[earliest|latest]

Specify a time range expression in the AQL query instead of passing the time range selected with the Search user interface.

  • <field>: Typically, you use earliest/latest functions at the end of a query when you want to apply date filtering relative to the event_time field. If no field is specified, event_time is the implicit default. However, you can use earliest/latest functions with any date type field having Unix epoch timestamps.

  • [earliest|latest]=[period]: The functionality differs depending on which functions are set:

    • earliest only: Returns events starting at the specified period.

    • latest only: Returns events ending at the specified period.

    • both: Returns events in the range of the two specified periods.

  • period: Must be one of the following:

    • A relative time string, which can be provided without quotes.

    • An absolute time string, which must be enclosed in quotes.

    • now string, which can be provided without quotes.

  • Relative time strings:

    • Must be a string in the format: < + | - ><number><time unit>@<snap_to_specifier>

    • + denotes a future time.

    • - denotes a past time.

    • No sign being provided is semantically the same as providing -, meaning strings without a sign are assumed to be past relative times. In other words, 2d is the same as -2d.

    • About snap_to_specifier:

      • @<snap_to_specifier> is an optional specifier that rounds down to the earliest or latest time by the amount you specify, in your timezone. To do so, insert the "@" character between the time amount and the snap-to specifier.

      • Supported specifiers are: @s, @m, @h, @d, @mon, for seconds, minutes, hours, days, and months respectively.

      • By default, the search uses seconds as the snap time unit.

Absolute time strings must be in the format: "%Y-%m-%d %H:%M:%S"

now string: Specifies the current time (the time at which the search is being executed).

Examples:

|where event_time earliest=1d, latest=now --Get all events from the range of 1d back up to now

|where event_time earliest=-1d --Get all events prior to 1d back from now

|where event_time earliest='2023-11-05 12:00:00' --Get all events starting at: '2023-11-05 12:00:00'

|where event_time latest=1d --Get all events ending at 1d back from now

|where event_time latest='2023-11-05 12:00:00'--Get all events ending at: '2023-11-05 12:00:00'

|where event_time earliest=-2d@d --On April 28th, the search looks for events starting from 12:00 AM on April 26th

|where event_time earliest=-30d@mon, latest=@mon --Get all events from the start of the previous month to the end of that month. For example, running this on Nov 1st will look for events between Oct 1st and Oct 31st.

Subsearch:

You can define a time range for subsearch that is different from the range for the primary search. See Subsearch documentation for more information.

| aggr count by sourcetype | appendtable [| where earliest=10d and latest=5d | aggr count by sourcetype]

|where timerange([period], [period], [field])

Specify a time range expression in the AQL query instead of passing the time range selected with the Search user interface.

  • [period], [period]: At least one period argument must be specified. The first period refers to the start point of the time range; the second period refers to the end point. If only one period argument is specified, it is assumed to be the start point and the current time is the end point.

    period can be specified in the following formats:

    • A relative time string, which can be provided without quotes.

    • An absolute time string, which must be enclosed in quotes.

    • now string, which can be provided without quotes.

    Relative time strings:

    • Must be a string in the format: < + | - ><number><time unit>

    • + denotes a future time.

    • - denotes a past time.

    • No sign being provided is semantically the same as providing -, meaning strings without a sign are assumed to be past relative times. In other words, 2d is the same as -2d.

    Absolute time strings must be in the format: "%Y-%m-%d %H:%M:%S"

    now string: Specifies the current time (the time at which the search is being executed).

  • [field]: Typically, you use the timerange function at the end of a query when you want to apply date filtering relative to the event_time field. If no field is specified, event_time is the implicit default. However, you can use the timereange function with any date type field having Unix epoch timestamps.

Examples:

|where timerange('1d', 'now', event_time) --Get all events from the range of 1d back up to now

|where timerange('1d') -- Functionally the same as the above example, ‘now’ is assumed for the second period, event_time is assumed for the field

|where timerange ('2023-11-05 12:00:00') -- Get all events from '2023-11-05 12:00:00' up to now

|where timerange ('2023-11-05 12:00:00', '1d') -- Get all events from '2023-11-05 12:00:00' up to 1d back from the current time the search is executed at

isnotnull(<field>)

isnull(<field>)

Filter results to exclude logs having null values for the specified field; or to return only logs having null values for the specified field.

Example:

|where isnotnull(src)|fields sourcetype, src

isnum(<field>)

Filter results to include only logs having number values for the specified field.

Example:

|where isnum(user)

isoutlier(<field>, [param], [uselower])

Filter results to include those where values for the specified field are outliers.

Optional:

  • param: Specify a floating point value. This parameter multiplies the interquartile range (IQR) in the evaluation. Increasing the value yields fewer outliers; decreasing the value yields a larger number of outliers. If this parameter is not specified, the implicit default is 2.5.

  • uselower: Specify true to detect outliers below the median. If this parameter is not specified, the implicit default is false.

Examples:

|where isoutlier(bytes_in)

|where isoutlier(bytes_out, true)

like(<field>, <pattern>)

not like(<field>, <pattern>)

<field> like <pattern>

<field> not like <pattern>

Filter results to include only logs having values for the specified field that match the specified pattern. The pattern can specify an exact match or a wildcard match:

  • Use the percent ( % ) symbol as a wildcard for matching multiple characters.

  • Use the underscore ( _ ) character as a wildcard to match a single character.

Refer to the Examples section below.

|where match(<field>, <regex>)

Filter results to include only logs having values for the specified field that match the specified regex.

Example:

|where match(event_name, 'Hello W..ld')

|where mvfind(<field>, <regex>)

Filter results to include only logs having values that match the mvfind() evaluation. The mvfind() function returns the index for the first value in a multivalue field that matches a regular expression. The index begins with zero. If no values match, returns NULL.

Example:

|where mvfind(ports, "8080") >= 0

Usage

Use the where operator to build complex filters to focus on data that impacts your business.

Evaluation of logical operators

You can create compound filters with use of parentheses, Boolean NOT, Boolean AND, or Boolean OR clauses.

Search evaluates the logical operator in the following descending order (first to last evaluation): 

  1. Parentheses ()

  2. Comparison operators (=, !=, <, >, <=, >=)

  3. Logical NOT (NOT)

  4. Logical AND (AND)

  5. Logical OR (OR)

Example 1: Search with AND and OR

The Search query

Copy
| where category != '' or src = '50.1.114.34' and sourcetype = 'ts_cloud'

during evaluation becomes

Copy
| where (category != '') or (src = '50.1.114.34' and sourcetype = 'ts_cloud')

This means that the condition src = '50.1.114.34' and sourcetype = 'ts_cloud' will be evaluated first, and then the result will be combined with category != '' using the OR operator.

Example 2: Search with NOT, AND and OR

The Search query

Copy
| where event_time NOT IN (9, 10) AND sourcetype contains_ci ('aws') or sourcetype contains_ci ('fortinet') and sourcetype = 'abc'

during evaluation becomes

Copy
| where (event_time NOT IN (9, 10) AND sourcetype contains_ci('aws')) or (sourcetype contains_ci ('fortinet') and sourcetype = 'abc')

This means that the condition event_time NOT IN (9, 10) AND sourcetype contains_ci('aws') will be evaluated first, and then the result will be combined with (sourcetype contains_ci ('fortinet') and sourcetype = 'abc') using the OR operator.

Examples

Example 1: Filters events to CrowdStrike logs where the process image is pnputil.exe, a Windows utility sometimes abused for malicious driver installation.

Copy
|where sourcetype contains "CrowdStrike" and image endswith "\pnputil.exe"

Example 2: Filters events to internal traffic originating from the 192.168.0.0/16 subnet where the destination is both non-null and non-empty — effectively guarding against incomplete or malformed network flow records.

Copy
|where (src insubnet '192.168.0.0/16' and dest is not null) AND (src insubnet '192.168.0.0/16' and dest !='')

Example 3: Filters events to Cisco logs that have a non-null source IP.

Copy
|where sourcetype contains "cisco" and src_ip is not null

Example 4: Filters OCSF events to Fortigate products, takes the first 20, splits the product name into a multi-value field on spaces, then calculates how many words are in each product name.

Copy
ocsf | fields metadata.product.name | where metadata.product.name contains 'Fortigate' | limit 20 | makemv delim = ' ' metadata.product.name | calc mv_len = array_len(metadata.product.name_mv)