# `Ash.Filter`
[🔗](https://github.com/ash-project/ash/blob/v3.17.0/lib/ash/filter/filter.ex#L5)

The representation of a filter in Ash.

## Security Concerns

Do not pass user input directly to `Ash.Query.filter/2`, it will not be sanitised. Instead use
`Ash.Filter.parse_input/2` or `Ash.Query.filter_input/2`.

Refer to those functions for more information on how to safely work with user input.

## Writing a filter

### Built In Predicates

* `is_nil`
* `==`
* `!=`
* `in`
* `<`
* `>`
* `<=`
* `>=`
* `&&`
* `||`
* `<>`
* `/`
* `-`
* `*`
* `+`
* `equals` (alias
  for `==`)
* `not_equals` (alias
  for `!=`)
* `gt` (alias
  for `>`)
* `lt` (alias
  for `<`)
* `gte` (alias
  for `>=`)
* `lte` (alias
  for `<=`)
* `eq` (alias
  for `==`)
* `not_eq` (alias
  for `!=`)
* `less_than` (alias
  for `<`)
* `greater_than` (alias
  for `>`)
* `less_than_or_equal` (alias
  for `<=`)
* `greater_than_or_equal` (alias
  for `>=`)
* `and` (alias
  for `&&`)
* `or` (alias
  for `||`)
* `concat` (alias
  for `<>`)
* `div` (alias
  for `/`)
* `minus` (alias
  for `-`)
* `times` (alias
  for `*`)
* `plus` (alias
  for `+`)

### BooleanExpression syntax

The expression syntax ultimately just builds the keyword list style filter,
but with lots of conveniences that would be very annoying to do manually.

Examples

```elixir
Ash.Query.filter(resource, name == "Zardoz")
Ash.Query.filter(resource, first_name == "Zar" and last_name == "Doz")
Ash.Query.filter(resource, first_name == "Zar" and last_name in ["Doz", "Daz"] and high_score > 10)
Ash.Query.filter(resource, first_name == "Zar" or last_name == "Doz" or (high_score > 10 and high_score < -10))
```

### Expressions

More complex filters can be built using Ash Expressions.

Examples

```elixir
# Filter based on the contents of a string attribute
Ash.Query.filter(Helpdesk.Support.Ticket, contains(subject, "2"))
# Filter based on the attribute of a joined relationship:
Ash.Query.filter(Helpdesk.Support.Ticket, representative.name == ^name)
```

See the [Expressions guide](/documentation/topics/reference/expressions.md)
guide for more information.

### Keyword list syntax

A filter is a nested keyword list (with some exceptions, like `true` for
everything and `false` for nothing).

The key is the "predicate" (or "condition") and the value is the parameter.
You can use `and` and `or` to create nested filters. Data layers can expose
custom predicates. Eventually, you will be able to define your own custom
predicates, which will be a mechanism for you to attach complex filters
supported by the data layer to your queries.

** Important ** In a given keyword list, all predicates are considered to be
"ands". So `[or: [first_name: "Tom", last_name: "Bombadil"]]` doesn't mean
'First name == "tom" or last_name == "bombadil"'. To say that, you want to
provide a list of filters, like so: `[or: [[first_name: "Tom"], [last_name:
"Bombadil"]]]`

Some example filters:

```elixir
Ash.Query.filter(resource, [name: "Zardoz"])
Ash.Query.filter(resource, [first_name: "Zar", last_name: "Doz"])
Ash.Query.filter(resource, [first_name: "Zar", last_name: [in: ["Doz", "Daz"]], high_score: [greater_than: 10]])
Ash.Query.filter(resource, [or: [
  [first_name: "Zar"],
  [last_name: "Doz"],
  [or: [
    [high_score: [greater_than: 10]],
    [high_score: [less_than: -10]]
  ]
]]])
```

### Other formats

Maps are also accepted, as are maps with string keys. Technically, a list of
`[{"string_key", value}]` would also work.

# `t`

```elixir
@type t() :: %Ash.Filter{expression: term(), resource: term()}
```

# `add_to_filter`

# `add_to_filter!`

# `builtin_functions`

# `builtin_operators`

# `builtin_predicate_operators`

# `builtins`

# `custom_expression`

# `do_hydrate_refs`

# `fetch_simple_equality_predicate`

```elixir
@spec fetch_simple_equality_predicate(Ash.Expr.t(), atom()) :: {:ok, term()} | :error
```

Can be used to find a simple equality predicate on an attribute

Use this when your attribute is configured with `filterable? :simple_equality`, and you want to
to find the value that it is being filtered on with (if any).

# `find`

Find an expression inside of a filter that matches the provided predicate

# `find_simple_equality_predicate`

Can be used to find a simple equality predicate on an attribute

Prefer `fetch_simple_equality_predicate/2`.

# `find_value`

# `flat_map`

# `get_filter`

Returns a filter statement that would find a single record based on the input.

For example:

    iex> get_filter(MyApp.Post, 1)
    {:ok, %{id: 1}} #using primary key
    iex> get_filter(MyApp.Post, id: 1)
    {:ok, %{id: 1}} #using primary key
    iex> get_filter(MyApp.Post, author_id: 1, publication_id: 2, first_name: "fred")
    {:ok, %{author_id: 1, publication_id: 1}} # using a unique identity
    iex> get_filter(MyApp.Post, first_name: "fred")
    :error # not enough information

# `get_function`

# `get_operator`

# `get_predicate_function`

# `hydrate_refs`

# `list_predicates`

# `list_refs`

# `map`

# `move_exprs_to_relationship_path`

# `move_to_relationship_path`

# `parse`

Parses a filter statement

See the module documentation for more information on the supported formats for filter
statements.

### Important

If you are trying to validate a filter supplied from an external/untrusted source,
be sure to use `parse_input/2` instead!

# `parse!`

Parses a filter statement

See `parse/2` for more

# `parse_input`

Parses a filter statement, accepting *only public attributes/relationships* and
honoring field policies & related resource policies, raising on errors.

See `parse/2` for more on filter parsing, and the [policies guide](/documentation/topics/security/policies.md)
for more on input references.

# `parse_input!`

Parses a filter statement, accepting *only public attributes/relationships* and
honoring field policies & related resource policies, raising on errors.

See `parse_input/2` for more

# `prefix_refs`

# `put_at_path`

# `relationship_paths`

# `run_other_data_layer_filters`

# `strict_subset`

```elixir
@spec strict_subset(t(), t()) :: boolean() | :maybe
```

Returns true if the candidate filter returns the same or less data than the filter

# `strict_subset_of`

Returns true if the second argument is a strict subset (always returns the same or less data) of the first

# `strict_subset_of?`

# `to_simple_filter`

Transform an expression based filter to a simple filter, which is just a list of predicates

Options:

* `:skip_invalid?` (`t:boolean/0`) - If an invalid filter expression is reached that can't be used with a simple filter (like an `or` statement, or a non-predicate expression), it will be ignored instead of raising an error. The default value is `false`.

# `used_aggregates`

# `used_calculations`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
