> ## 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.

# project-keep

> This page explains how to use the project-keep operator function in APL.

The `project-keep` operator in APL is a powerful tool for field selection. It allows you to explicitly keep specific fields from a dataset, discarding any others not listed in the operator’s parameters. This is useful when you only need to work with a subset of fields in your query results and want to reduce clutter or improve performance by eliminating unnecessary fields.

You can use `project-keep` when you need to focus on particular data points, such as in log analysis, security event monitoring, or extracting key fields from traces.

## 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 `table` command performs a similar task to APL’s `project-keep`. It selects only the fields you specify and excludes any others.

    <CodeGroup>
      ```splunk Splunk example theme={null}
      index=main | table _time, status, uri
      ```

      ```kusto APL equivalent theme={null}
      ['sample-http-logs'] 
      | project-keep _time, status, uri
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="ANSI SQL users">
    In ANSI SQL, the `SELECT` statement combined with field names performs a task similar to `project-keep` in APL. Both allow you to specify which fields to retrieve from the dataset.

    <CodeGroup>
      ```sql SQL example theme={null}
      SELECT _time, status, uri FROM sample_http_logs
      ```

      ```kusto APL equivalent theme={null}
      ['sample-http-logs'] 
      | project-keep _time, status, uri
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

## Usage

### Syntax

```kusto theme={null}
| project-keep FieldName1, FieldName2, ...
```

### Parameters

* `FieldName`: The field you want to keep in the result set.

### Returns

`project-keep` returns a dataset with only the specified fields. All other fields are removed from the output. The result contains the same number of rows as the input table.

## Use case examples

<Tabs>
  <Tab title="Log analysis">
    For log analysis, you might want to keep only the fields that are relevant to investigating HTTP requests.

    **Query**

    ```kusto theme={null}
    ['sample-http-logs'] 
    | project-keep _time, status, uri, method, 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%20%7C%20project-keep%20_time%2C%20status%2C%20uri%2C%20method%2C%20req_duration_ms%22%7D)

    **Output**

    | \_time              | status | uri                | method | req\_duration\_ms |
    | ------------------- | ------ | ------------------ | ------ | ----------------- |
    | 2024-10-17 10:00:00 | 200    | /index.html        | GET    | 120               |
    | 2024-10-17 10:01:00 | 404    | /non-existent.html | GET    | 50                |
    | 2024-10-17 10:02:00 | 500    | /server-error      | POST   | 300               |

    This query filters the dataset to show only the request timestamp, status, URI, method, and duration, which can help you analyze server performance or errors.
  </Tab>

  <Tab title="OpenTelemetry traces">
    For OpenTelemetry trace analysis, you may want to focus on key tracing details such as service names and trace IDs.

    **Query**

    ```kusto theme={null}
    ['otel-demo-traces'] 
    | project-keep _time, trace_id, span_id, ['service.name'], duration
    ```

    [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27otel-demo-traces%27%5D%20%7C%20project-keep%20_time%2C%20trace_id%2C%20span_id%2C%20%5B%27service.name%27%5D%2C%20duration%22%7D)

    **Output**

    | \_time              | trace\_id | span\_id | service.name    | duration |
    | ------------------- | --------- | -------- | --------------- | -------- |
    | 2024-10-17 10:03:00 | abc123    | xyz789   | frontend        | 500ms    |
    | 2024-10-17 10:04:00 | def456    | mno345   | checkoutservice | 250ms    |

    This query extracts specific tracing information, such as trace and span IDs, the name of the service, and the span’s duration.
  </Tab>

  <Tab title="Security logs">
    In security log analysis, focusing on essential fields like user ID and HTTP status can help track suspicious activity.

    **Query**

    ```kusto theme={null}
    ['sample-http-logs'] 
    | project-keep _time, id, status, uri, ['geo.city'], ['geo.country']
    ```

    [Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27sample-http-logs%27%5D%20%7C%20project-keep%20_time%2C%20id%2C%20status%2C%20uri%2C%20%5B%27geo.city%27%5D%2C%20%5B%27geo.country%27%5D%22%7D)

    **Output**

    | \_time              | id      | status | uri    | geo.city      | geo.country |
    | ------------------- | ------- | ------ | ------ | ------------- | ----------- |
    | 2024-10-17 10:05:00 | user123 | 403    | /admin | New York      | USA         |
    | 2024-10-17 10:06:00 | user456 | 200    | /login | San Francisco | USA         |

    This query narrows down the data to track HTTP status codes by users, helping identify potential unauthorized access attempts.
  </Tab>
</Tabs>

## List of related operators

* [project](/apl/tabular-operators/project-operator): Use `project` to explicitly specify the fields you want in your result, while also allowing transformations or calculations on those fields.
* [extend](/apl/tabular-operators/extend-operator): Use `extend` to add new fields or modify existing ones without dropping any fields.
* [summarize](/apl/tabular-operators/summarize-operator): Use `summarize` when you need to perform aggregation operations on your dataset, grouping data as necessary.

## Wildcard

Wildcard refers to a special character or a set of characters that can be used to substitute for any other character in a search pattern. Use wildcards to create more flexible queries and perform more powerful searches.

The syntax for wildcard can either be `data*` or `['data.fo']*`.

Here’s how you can use wildcards in `project-keep`:

```kusto theme={null}
['sample-http-logs']
| project-keep resp*, content*,  ['geo.']*
```

[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%20project-keep%20resp%2A%2C%20content%2A%2C%20%20%5B%27geo.%27%5D%2A%22%2C%22queryOptions%22%3A%7B%22quickRange%22%3A%2230d%22%7D%7D)

```kusto theme={null}
['github-push-event']
| project-keep size*, repo*, ['commits']*, id*
```

[Run in Playground](https://play.axiom.co/axiom-play-qf1k/query?initForm=%7B%22apl%22%3A%22%5B%27github-push-event%27%5D%5Cn%7C%20project-keep%20size%2A%2C%20repo%2A%2C%20%5B%27commits%27%5D%2A%2C%20id%2A%22%2C%22queryOptions%22%3A%7B%22quickRange%22%3A%2230d%22%7D%7D)
