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

# Filter Operations

> Filter queries using comparison operators (eq, neq, gt, gte, lt, lte, like, in)

Filter operations allow you to query entities based on specific conditions. ChameleonDB supports a rich set of comparison operators.

## Current API (v0.1)

<Note>
  v0.1 uses string-based filters. The target API will use generated typed accessors for better type safety.
</Note>

**Current syntax:**

```go theme={null}
db.Users().Filter("email", "eq", "ana@mail.com")
```

**Target API (with code generation):**

```go theme={null}
db.Users().Filter(User.Email.Eq("ana@mail.com"))
```

## Filter by Equality

Match records where a field equals a specific value:

<CodeGroup>
  ```go Go theme={null}
  users, err := db.Users().
      Filter("email", "eq", "ana@mail.com").
      Execute()
  ```

  ```sql Generated SQL theme={null}
  SELECT id, email, name, age, created_at
  FROM users
  WHERE email = 'ana@mail.com';
  ```
</CodeGroup>

## Comparison Operators

ChameleonDB supports these comparison operators:

| Operator | Meaning               | Example                              |
| -------- | --------------------- | ------------------------------------ |
| `eq`     | Equal                 | `Filter("age", "eq", 25)`            |
| `neq`    | Not equal             | `Filter("status", "neq", "deleted")` |
| `gt`     | Greater than          | `Filter("age", "gt", 18)`            |
| `gte`    | Greater than or equal | `Filter("age", "gte", 18)`           |
| `lt`     | Less than             | `Filter("total", "lt", 100)`         |
| `lte`    | Less than or equal    | `Filter("total", "lte", 100)`        |
| `like`   | Contains (pattern)    | `Filter("name", "like", "ana")`      |
| `in`     | In list               | `Filter("status", "in", [...])`      |

## Greater Than or Equal

<CodeGroup>
  ```go Go theme={null}
  users, err := db.Users().
      Filter("age", "gte", 18).
      Execute()
  ```

  ```sql Generated SQL theme={null}
  SELECT id, email, name, age, created_at
  FROM users
  WHERE age >= 18;
  ```
</CodeGroup>

## Multiple Filters (AND)

Multiple `.Filter()` calls are combined with `AND`:

<CodeGroup>
  ```go Go theme={null}
  users, err := db.Users().
      Filter("age", "gte", 18).
      Filter("age", "lte", 65).
      Execute()
  ```

  ```sql Generated SQL theme={null}
  SELECT id, email, name, age, created_at
  FROM users
  WHERE age >= 18 AND age <= 65;
  ```
</CodeGroup>

<Tip>
  You can chain as many filters as needed. They will all be combined with `AND` logic.
</Tip>

## Like (Pattern Matching)

Match strings using `like`. Wildcards (`%`) are added automatically:

<CodeGroup>
  ```go Go theme={null}
  users, err := db.Users().
      Filter("name", "like", "ana").
      Execute()
  ```

  ```sql Generated SQL theme={null}
  SELECT id, email, name, age, created_at
  FROM users
  WHERE name LIKE '%ana%';
  ```
</CodeGroup>

<Note>
  ChameleonDB automatically wraps the search term with `%` wildcards for convenient substring matching.
</Note>

## In (Multiple Values)

Match against a list of values:

<CodeGroup>
  ```go Go theme={null}
  users, err := db.Users().
      Filter("status", "in", []string{"active", "pending"}).
      Execute()
  ```

  ```sql Generated SQL theme={null}
  SELECT id, email, name, age, created_at
  FROM users
  WHERE status IN ('active', 'pending');
  ```
</CodeGroup>

## Filter on Related Entity

Filter the main entity based on a condition on a related entity:

<CodeGroup>
  ```go Go theme={null}
  users, err := db.Users().
      Filter("orders.total", "gt", 100).
      Execute()
  ```

  ```sql Generated SQL theme={null}
  SELECT DISTINCT users.id, users.email, users.name, users.age, users.created_at
  FROM users
  INNER JOIN orders ON orders.user_id = users.id
  WHERE orders.total > 100;
  ```
</CodeGroup>

<Warning>
  **Important:** When filtering on a relation, ChameleonDB uses a JOIN automatically. `DISTINCT` is added to avoid duplicates when a user has multiple matching orders.
</Warning>

## Filter on Relation + Include

You can filter on a relation and also include it. The filter affects **which users** are returned; the include loads **all their orders** (not just matching ones):

<CodeGroup>
  ```go Go theme={null}
  users, err := db.Users().
      Filter("orders.total", "gt", 100).
      Include("orders").
      Execute()
  ```

  ```sql Generated SQL theme={null}
  -- 1. Main query (filtered via JOIN)
  SELECT DISTINCT users.id, users.email, users.name, users.age, users.created_at
  FROM users
  INNER JOIN orders ON orders.user_id = users.id
  WHERE orders.total > 100;

  -- 2. Eager load ALL orders for matched users
  SELECT id, total, status, created_at, user_id
  FROM orders
  WHERE user_id IN (...);
  ```
</CodeGroup>

<Note>
  The filter determines **which users** match. The include loads **all related data** for those users, not just the filtered subset.
</Note>

## Not Equal

<CodeGroup>
  ```go Go theme={null}
  users, err := db.Users().
      Filter("status", "neq", "deleted").
      Execute()
  ```

  ```sql Generated SQL theme={null}
  SELECT id, email, name, age, created_at
  FROM users
  WHERE status != 'deleted';
  ```
</CodeGroup>

## Less Than

<CodeGroup>
  ```go Go theme={null}
  orders, err := db.Orders().
      Filter("total", "lt", 100).
      Execute()
  ```

  ```sql Generated SQL theme={null}
  SELECT id, total, status, created_at, user_id
  FROM orders
  WHERE total < 100;
  ```
</CodeGroup>

## Type Safety

<Warning>
  Filters are validated against your schema. Type mismatches will be caught:

  ```go theme={null}
  // ❌ This will fail - age is an integer
  db.Users().Filter("age", "eq", "not a number")

  // ✅ Correct
  db.Users().Filter("age", "eq", 25)
  ```
</Warning>

## What's Next?

<CardGroup cols={2}>
  <Card title="Relations" icon="diagram-project" href="/queries/relations">
    Learn about eager loading with Include()
  </Card>

  <Card title="Advanced Queries" icon="wand-magic-sparkles" href="/queries/advanced">
    OrderBy, Limit, Offset, and complex queries
  </Card>
</CardGroup>
