# Filter parameter specification

`filter` parameter allows for scoping down queries. It consists of nodes which are used to build tree-like structure and generate correct SQL queries over underlying databases.

Each of JSON object (node) requires `"type"` key which determines logic that needs to be applied.

### Example

```json
{
  "type" => "and",
  "operations" => [
    { "type" => "equal", "field" => "grouping_type", "value" => "optin_channel" },
    { "type" => "equal", "field" => "grouping_value", "value" => "default" }
  ]
}
```
Adding following `filter` parameter to a query will scope it down to records/timeseries data which have both:
* `grouping_type` field with `optin_channel` value and
* `grouping_value` field with `default` value

## Logical node

Logical node joins several nodes with provided logic. JSON object needs to include:
* `"type"` - logical node type (see below) 
* `"operations"` - array with underlying nodes

| `"type"` key | Operation logic | Rate limiting cost |
| --- | --- | --- |
| `and` | Joins operations with `AND` | 1 |
| `or` | Joins operations with `OR` | 3 |

## Base operation node

Operation is a single operation which will be executed. JSON object needs to include:
* `"type"` - operation node type (see below)
* `"field"` - field which will be used for operation. Note that this field must be "filterable" for given report.
* `"value"` - value which will be used in operation


| `"type"` key | Operation logic  | Requirements | Additional notes |
| --- | --- | --- | --- |
| `equal` | Checks whether field equals to value | - | When `null` is provided as a value then `IS NULL` query will be executed |
| `not_equal` | Checks whether field is not equal to value | - | When `null` is provided as a value then `IS NOT NULL` query will be executed |
| `greater_than` | Checks whether field is greater than value | Field must be numerical or timestamp.  | - |
| `greater_or_equal_to` | Checks whether field is greater or equal to value | Field must be numerical or timestamp.  | - |
| `less_than` | Checks whether field is less than value | Field must be numerical or timestamp.  | - |
| `less_or_equal_to` | Checks whether field is less or equal to value | Field must be numerical or timestamp.  | - |
| `in` | Checks whether field equals to one of provided values | Value must be an array | When field is an array, then it will be returned when any elements are in common |
| `not_in` | Checks whether field not equals to one of provided values | Value must be an array | Logical opposite of `in` |

### Rate limiting

Each operation node adds `1` token to request cost.

## JSON operations node

This operation allows to query over JSON fields. JSON object needs to include:
* `"type"` - JSON operation node type (see below)
* `"field"` - field which will be used for operation. It needs to be formatted as `<report field>.<json_key>` (for example `consents.sms_consent`). Note that `<report's field>` must be filterable. 
* `"value"` - value which will be used in operation

| `"type"` key | Operation logic  | Requirements | Additional notes |
| --- | --- | --- | --- |
| `exists` | Checks whether JSON key exists | - | - |
| `not_exists` | Checks whether JSON key does not exist | - | - |
| `equal` | Checks whether JSON key value is equal to value | - | - |
| `not_equal` | Checks whether JSON key value is not equal to value | - | - |

### Rate limiting

Each operation node adds `2` tokens to request cost.

## Examples

```json
{
  "type": "and",
  "operations": [
    { "type": "equal", "field": "grouping_type", "value": "optin_channel" },
    { "type": "equal", "field": "grouping_value", "value": "default" }
  ]
}
```
This param will use 1 (`and` logical node) + 2x1 (`equal` operation nodes) = `3` tokens of rate limit cost.