> ## Documentation Index
> Fetch the complete documentation index at: https://axiom.co/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# where

> This page explains how to use the where operator in APL.

The `where` operator in APL is used to filter rows based on specified conditions. You can use the `where` operator to return only the records that meet the criteria you define. It’s a foundational operator in querying datasets, helping you focus on specific data by applying conditions to filter out unwanted rows. This is useful when working with large datasets, logs, traces, or security events, allowing you to extract meaningful information quickly.

## For users of other query languages

If you come from other query languages, this section explains how to adjust your existing queries to achieve the same results in APL.

<AccordionGroup>
  <Accordion title="Splunk SPL users">
    In Splunk SPL, the `where` operator filters events based on boolean expressions. APL’s `where` operator functions similarly, allowing you to filter rows that satisfy a condition.

    <CodeGroup>
      ```sql Splunk example theme={null}
      index=main | where status="200"
      ```

      ```kusto APL equivalent theme={null}
      ['sample-http-logs']
      | where status == '200'
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="ANSI SQL users">
    In ANSI SQL, the `WHERE` clause filters rows in a `SELECT` query based on a condition. APL’s `where` operator behaves similarly, but the syntax reflects APL’s specific dataset structures.

    <CodeGroup>
      ```sql SQL example theme={null}
      SELECT * FROM sample_http_logs WHERE status = '200'
      ```

      ```kusto APL equivalent theme={null}
      ['sample-http-logs']
      | where status == '200'
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

## Usage

### Syntax

```kusto theme={null}
| where condition
```

### Parameters

* `condition`: A Boolean expression that specifies the filtering condition. The `where` operator returns only the rows that satisfy this condition.

### Returns

The `where` operator returns a filtered dataset containing only the rows where the condition evaluates to true.

## Use case examples

<Tabs>
  <Tab title="Log analysis">
    In this use case, you filter HTTP logs to focus on records where the HTTP status is 404 (Not Found).

    **Query**

    ```kusto theme={null}
    ['sample-http-logs']
    | where status == '404'
    ```

    [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20where%20status%20%3D%3D%20'404'%22%7D)

    **Output**

    | \_time              | id    | status | method | uri            | req\_duration\_ms | geo.city | geo.country |
    | ------------------- | ----- | ------ | ------ | -------------- | ----------------- | -------- | ----------- |
    | 2024-10-17 10:20:00 | 12345 | 404    | GET    | /notfound.html | 120               | Seattle  | US          |

    This query filters out all HTTP requests except those that resulted in a 404 error, making it easy to investigate pages that were not found.
  </Tab>

  <Tab title="OpenTelemetry traces">
    Here, you filter OpenTelemetry traces to retrieve spans where the `duration` exceeded 500 milliseconds.

    **Query**

    ```kusto theme={null}
    ['otel-demo-traces']
    | where duration > 500ms
    ```

    [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'otel-demo-traces'%5D%20%7C%20where%20duration%20%3E%20500ms%22%7D)

    **Output**

    | \_time              | span\_id | trace\_id | duration | service.name | kind   | status\_code |
    | ------------------- | -------- | --------- | -------- | ------------ | ------ | ------------ |
    | 2024-10-17 11:15:00 | abc123   | xyz789    | 520ms    | frontend     | server | OK           |

    This query helps identify spans with durations longer than 500 milliseconds, which might indicate performance issues.
  </Tab>

  <Tab title="Security logs">
    In this security use case, you filter logs to find requests from users in a specific country, such as Germany.

    **Query**

    ```kusto theme={null}
    ['sample-http-logs']
    | where ['geo.country'] == 'Germany'
    ```

    [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B'sample-http-logs'%5D%20%7C%20where%20%5B'geo.country'%5D%20%3D%3D%20'Germany'%22%7D)

    **Output**

    | \_time              | id    | status | method | uri    | req\_duration\_ms | geo.city | geo.country |
    | ------------------- | ----- | ------ | ------ | ------ | ----------------- | -------- | ----------- |
    | 2024-10-17 09:45:00 | 54321 | 200    | POST   | /login | 100               | Berlin   | Germany     |

    This query helps filter logs to investigate activity originating from a specific country, useful for security and compliance.
  </Tab>
</Tabs>

## where \* has

The `* has` pattern in APL is a dynamic and powerful tool within the `where` operator. It offers you the flexibility to search for specific substrings across all fields in a dataset without the need to specify each field name individually. This becomes especially advantageous when dealing with datasets that have numerous or dynamically named fields.

`where * has` is an expensive operation because it searches all fields. For a more efficient query, explicitly list the fields in which you want to search. For example: `where firstName has "miguel" or lastName has "miguel"`.

### Basic where \* has usage

Find events where any field contains a specific substring.

```kusto theme={null}
['sample-http-logs'] 
| where * has "GET"
```

[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20where%20%2A%20has%20%5C%22GET%5C%22%22%7D\&queryOptions=%7B%22quickRange%22%3A%2230d%22%7D)

### Combine multiple substrings

Find events where any field contains one of multiple substrings.

```kusto theme={null}
['sample-http-logs'] 
| where * has "GET" or * has "text"
```

[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20where%20%2A%20has%20%5C%22GET%5C%22%20or%20%2A%20has%20%5C%22text%5C%22%22%7D\&queryOptions=%7B%22quickRange%22%3A%2230d%22%7D)

### Use \* has with other operators

Find events where any field contains a substring, and another specific field equals a certain value.

```kusto theme={null}
['sample-http-logs'] 
| where * has "css" and req_duration_ms == 1
```

[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20where%20%2A%20has%20%5C%22css%5C%22%20and%20req_duration_ms%20%3D%3D%201%22%7D\&queryOptions=%7B%22quickRange%22%3A%2230d%22%7D)

### Advanced chaining

Filter data based on several conditions, including fields containing certain substrings, then summarize by another specific criterion.

```kusto theme={null}
['sample-http-logs']
| where * has "GET" and * has "css"
| summarize Count=count() by method, content_type, server_datacenter
```

[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20where%20%2A%20has%20%5C%22GET%5C%22%20and%20%2A%20has%20%5C%22css%5C%22%5Cn%7C%20summarize%20Count%3Dcount%28%29%20by%20method%2C%20content_type%2C%20server_datacenter%22%7D\&queryOptions=%7B%22quickRange%22%3A%2230d%22%7D)

### Use with aggregations

Find the average of a specific field for events where any field contains a certain substring.

```kusto theme={null}
['sample-http-logs']
| where * has "Japan"
| summarize avg(req_duration_ms)
```

[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20where%20%2A%20has%20%5C%22Japan%5C%22%5Cn%7C%20summarize%20avg%28req_duration_ms%29%22%7D\&queryOptions=%7B%22quickRange%22%3A%2230d%22%7D)

### String case transformation

The `has` operator is case insensitive. Use `has` if you’re unsure about the case of the substring in the dataset. For the case-sensitive operator, use `has_cs`.

```kusto theme={null}
['sample-http-logs']
| where * has "mexico"
| summarize avg(req_duration_ms)
```

[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%5Cn%7C%20where%20%2A%20has%20%5C%22mexico%5C%22%5Cn%7C%20summarize%20avg%28req_duration_ms%29%22%7D\&queryOptions=%7B%22quickRange%22%3A%2230d%22%7D)

## List of related operators

* [count](/apl/tabular-operators/count-operator): Use `count` to return the number of records that match specific criteria.
* [distinct](/apl/tabular-operators/distinct-operator): Use `distinct` to return unique values in a dataset, complementing filtering.
* [take](/apl/tabular-operators/take-operator): Use `take` to return a specific number of records, typically in combination with `where` for pagination.
