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

# Filtering

> Build filters using the Layers SDK filter DSL, configure filter aliases at client initialization, and combine boolean groups with comparison operators.

Build filters using the DSL:

```typescript theme={null}
import { filter, and, or, eq, gte, lte, inValues } from '@commerce-blocks/sdk'

await collection.execute({
  filters: filter(and(eq('options.color', 'Red'), eq('options.size', 'Medium'))),
})

// Price range
filter(and(gte('price', 50), lte('price', 200)))

// Multiple values
filter(or(eq('vendor', 'Nike'), eq('vendor', 'Adidas')))
```

## Filter operators

| Operator                       | Description             |
| ------------------------------ | ----------------------- |
| `eq(property, value)`          | Equals                  |
| `notEq(property, value)`       | Not equals              |
| `inValues(property, values[])` | In list                 |
| `notIn(property, values[])`    | Not in list             |
| `gt(property, number)`         | Greater than            |
| `gte(property, number)`        | Greater than or equal   |
| `lt(property, number)`         | Less than               |
| `lte(property, number)`        | Less than or equal      |
| `exists(property)`             | Property exists         |
| `notExists(property)`          | Property does not exist |

## Filter types

The DSL produces `FilterGroup` and `FilterExpression` objects. You typically do not construct these manually, but the types are exported if you need to build filters programmatically:

```typescript theme={null}
import type { FilterGroup, FilterExpression } from '@commerce-blocks/sdk'

interface FilterExpression {
  property: string
  operator: FilterOperator
  values: (string | number | boolean)[]
}

interface FilterGroup {
  conditional: 'AND' | 'OR'
  expressions: (FilterExpression | FilterGroup)[]
}
```

The `filter()` function wraps a single expression in a `FilterGroup` automatically, so you can pass either an expression or a group:

```typescript theme={null}
// Single expression (wrapped in AND group automatically)
filter(eq('vendor', 'Nike'))

// Explicit group
filter(and(eq('vendor', 'Nike'), gte('price', 50)))

// Nested groups
filter(and(
  eq('options.color', 'Red'),
  or(eq('vendor', 'Nike'), eq('vendor', 'Adidas'))
))
```

## Filter aliases

Configure once at init. Aliases are applied automatically to all results:

```typescript theme={null}
import { createClient } from '@commerce-blocks/sdk'

const { data: client } = createClient({
  // ...config
  filterAliases: {
    color: 'options.color',
    size: 'options.size',
    brand: { property: 'vendor', values: { nike: 'Nike', adidas: 'Adidas' } },
  },
})

// Aliases resolve automatically
await collection.execute({ filters: { color: 'Red', brand: 'nike' } })
```

### Alias types

An alias can be a simple string mapping or an object with value mappings:

```typescript theme={null}
type FilterAlias =
  | string // Simple: 'color' maps to 'options.color'
  | { property: string; values?: Record<string, string> } // With value mapping

type FilterAliases = Record<string, FilterAlias>
```

With value mappings, the alias `brand: { property: 'vendor', values: { nike: 'Nike' } }` lets you write `{ brand: 'nike' }` and the SDK resolves it to `eq('vendor', 'Nike')`.

## Next steps

* [Client methods](/sdk/api-reference/client-methods)
* [Response types and error handling](/sdk/api-reference/responses-and-errors)
