> ## Documentation Index
> Fetch the complete documentation index at: https://www.nestjs-query.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Filtering

Filtering in `nestjs-query` has an object based syntax.

For a full reference of filter operations [see filter reference](https://www.nestjs-query.dev/concepts/queries.md#filter-reference)

The following example filters for all todoItems that are marked completed.

> [tab] GraphQL
>
> ```graphql theme={null}
> {
>   todoItems(filter: { completed: { is: true } }) {
>     pageInfo {
>       hasNextPage
>       hasPreviousPage
>       startCursor
>       endCursor
>     }
>     edges {
>       node {
>         id
>         title
>         completed
>         created
>         updated
>       }
>       cursor
>     }
>   }
> }
> ```

> [tab] Response
>
> ```json theme={null}
> {
>   "data": {
>     "todoItems": {
>       "pageInfo": {
>         "hasNextPage": false,
>         "hasPreviousPage": false,
>         "startCursor": "YXJyYXljb25uZWN0aW9uOjA=",
>         "endCursor": "YXJyYXljb25uZWN0aW9uOjE="
>       },
>       "edges": [
>         {
>           "node": {
>             "id": "3",
>             "title": "Create Many Todo Items - 2",
>             "completed": true,
>             "created": "2020-01-14T07:00:34.111Z",
>             "updated": "2020-01-14T07:00:34.111Z"
>           },
>           "cursor": "YXJyYXljb25uZWN0aW9uOjA="
>         },
>         {
>           "node": {
>             "id": "5",
>             "title": "Create Many Todo Items - 4",
>             "completed": true,
>             "created": "2020-01-14T07:01:27.805Z",
>             "updated": "2020-01-14T07:01:27.805Z"
>           },
>           "cursor": "YXJyYXljb25uZWN0aW9uOjE="
>         }
>       ]
>     }
>   }
> }
> ```

## Setting the generated filter-type depth

When querying the default filter is one level deep. You can specify the generated filter-type depth by using the `QueryOptions` decorator on your DTO.

You can find the documentation and an example in the [`QueryOptions` reference](../dtos#generated-filter-type-depth).

## Setting a default filter

When querying the default filter is empty. You can specify a default filter by using the `QueryOptions` decorator on your DTO.

You can find the documentation and an example in the [`QueryOptions` reference](../dtos#setting-a-default-filter).

## Setting allowed boolean expressions

When filtering you can provide `and` and `or` expressions to provide advanced filtering. You can turn off either by using the `QueryOptions` decorator on your DTO.

You can find the documentation and an example in the [`QueryOptions` reference](../dtos#allowed-boolean-expressions).

## How Filters Are Applied

Filters in `nestjs-query` come from multiple sources and combine differently depending on the source.

### Filter Sources

| Source | When Applied | How Combined |
| - | - | - |
| User filter (GraphQL args) | Always | Base filter |
| Default filter (`@QueryOptions`) | Only when user provides NO filter | Replaces empty filter |
| Auth filter (`@Authorize`) | Always | ANDed with user filter |

### Default Filter Behavior

The `defaultFilter` from `@QueryOptions` is used as the GraphQL field's `defaultValue`. This means:

* ✅ If user provides NO filter → defaultFilter is used
* ❌ If user provides ANY filter → defaultFilter is completely ignored

```ts theme={null}
@QueryOptions({ defaultFilter: { archived: { is: false } } })
```

> [!WARNING]
>
> Default filter is NOT merged - it's a fallback. Use [authorization](https://www.nestjs-query.dev/graphql/authorization.md) for filters that must always apply.

### Authorization Filter Behavior

Filters from `@Authorize` are **always merged** with the user's filter using AND logic:

```ts theme={null}
// User query
filter: {
  title: {
    like: '%todo%'
  }
}

// @Authorize returns
{
  ownerId: {
    eq: currentUserId
  }
}

// Actual filter applied
{
  and: [{ title: { like: '%todo%' } }, { ownerId: { eq: currentUserId } }]
}
```

For more details, see [Authorization](https://www.nestjs-query.dev/graphql/authorization.md).

### Filter Flow

```text theme={null}
GraphQL Query (filter arg)
    ↓
Default filter applied if user filter empty
    ↓
Resolver receives query
    ↓
Auth filter merged (AND)
    ↓
QueryService.query()
    ↓
ORM (TypeORM/Sequelize/Mongoose)
    ↓
Database
```

### Relation Filters

When querying relations, authorization filters are resolved in order (first non-empty wins):

1. **Custom authorizer's `authorizeRelation()` method** - if returns a filter, used exclusively
2. **Relation's `auth` option** - if defined on the relation decorator
3. **Related DTO's `@Authorize` decorator** - fallback to the related type's auth

> [!NOTE]
>
> Relation auth filters are NOT merged - the first non-empty result is used.

See [Relation Filtering](https://www.nestjs-query.dev/graphql/authorization.md#relation-filtering) for details.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.