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

# 필터와 정렬

> POST /v1/data_sources/{id}/query의 filter와 sorts에 사용할 수 있는 조건을 정리합니다.

## 조건 묶기

조건 하나는 속성과 조건식으로 이루어집니다. `and`와 `or`로 2단계까지 묶을 수 있습니다.

```json theme={null}
{
  "filter": {
    "and": [
      {
        "property": "상태",
        "status": {
          "equals": "진행 중"
        }
      },
      {
        "or": [
          {
            "property": "담당 팀",
            "select": {
              "equals": "운영"
            }
          },
          {
            "property": "담당 팀",
            "select": {
              "is_empty": true
            }
          }
        ]
      }
    ]
  }
}
```

`property`에는 속성 이름이나 ID를 사용합니다. 배열마다 100개, 한 요청에 조건 1,000개까지입니다.

## 속성 조건

| 필터 키 | 조건 |
| - | - |
| `title` · `rich_text` · `url` · `email` · `phone_number` | `equals` · `does_not_equal` · `contains` · `does_not_contain` · `starts_with` · `ends_with` · `is_empty` · `is_not_empty` |
| `number` | `equals` · `does_not_equal` · `greater_than` · `less_than` · `greater_than_or_equal_to` · `less_than_or_equal_to` · `is_empty` · `is_not_empty` |
| `checkbox` | `equals` · `does_not_equal` |
| `select` · `status` | `equals` · `does_not_equal` · `is_empty` · `is_not_empty` |
| `multi_select` | `contains` · `does_not_contain` · `is_empty` · `is_not_empty` |
| `date` · `created_time` · `last_edited_time` | `equals` · `before` · `after` · `on_or_before` · `on_or_after` · `is_empty` · `is_not_empty` · `past_week` · `past_month` · `past_year` · `next_week` · `next_month` · `next_year` · `this_week` |
| `people` · `created_by` · `last_edited_by` · `relation` | `contains` · `does_not_contain` · `is_empty` · `is_not_empty` |
| `files` | `is_empty` · `is_not_empty` |
| `unique_id` | `equals` · `does_not_equal` · `greater_than` · `less_than` · `greater_than_or_equal_to` · `less_than_or_equal_to` |
| `formula` | `string` · `checkbox` · `number` · `date` 아래에 그 종류의 조건 |
| `rollup` | `any` · `every` · `none` · `number` · `date` |

`button` 속성에는 필터를 걸 수 없습니다. 400을 반환합니다.

속성과 필터 키가 맞지 않으면 400입니다. 다만 `title` · `rich_text` · `url` · `email` · `phone_number` 속성은 `rich_text` 키를, `created_by` · `last_edited_by` 속성은 `people` 키를, `created_time` · `last_edited_time` 속성은 `date` 키를 사용할 수 있습니다.

## 텍스트 조건

* 값의 앞뒤 공백을 지우고 비교합니다. 대소문자를 구분하지 않습니다. `equals`도 같습니다.
* 공백을 지운 값이 비어 있으면 그 조건은 모든 행과 일치합니다. `equals: ""`도 같습니다. `formula.string`에서는 수식 결과가 텍스트인 행과 일치합니다.

## 선택 조건

* 값은 이름 하나 또는 이름 배열입니다. 배열은 그중 하나에 맞으면 됩니다.
* 이름은 대소문자를 구분합니다. 없는 이름은 400 `select option "X" not found for property "P". Available options: ...`입니다.
* `status`는 그룹 이름 `To-do` · `In progress` · `Complete`도 받습니다. 그 그룹의 선택지 모두에 맞습니다.
* 빈 텍스트 하나는 조건이 없는 것과 같습니다.

## 날짜 조건

* 값은 ISO 8601 형식의 텍스트나 `today` · `tomorrow` · `yesterday` · `one_week_ago` · `one_week_from_now` · `one_month_ago` · `one_month_from_now`입니다.
* 시각이 없는 값은 그날 0시(UTC)로 처리합니다. `equals`는 그날 하루 전체, `after`는 다음 날부터입니다.
* 시각이 있고 오프셋이 없는 값은 UTC로 읽습니다. 범위 값은 시작 날짜로 비교합니다.
* `past_week` 같은 조건의 값은 빈 객체 `{}`입니다. `this_week`는 UTC 일요일부터 7일입니다. `past_week`와 `next_week`는 오늘을 포함합니다.

```json theme={null}
{ "property": "마감일", "date": { "on_or_after": "today" } }
```

```json theme={null}
{ "property": "마감일", "date": { "next_week": {} } }
```

## 사람과 관계 조건

값은 ID입니다. `people` · `created_by` · `last_edited_by`의 `"me"`는 어떤 값과도 일치하지 않습니다. 연동은 사람이 아니기 때문입니다.

자동화가 쓴 행은 `{ "property": "최종 편집자", "last_edited_by": { "contains": "00000000-0000-0000-0000-000000000003" } }`으로 찾을 수 있습니다.

## 시각으로 거르기

속성 없이 행의 만든 시각이나 고친 시각으로 거를 수 있습니다. 그 속성이 없는 데이터베이스에서도 가능합니다. 비교는 분 단위로 잘린 값으로 합니다.

```json theme={null}
{
  "filter": {
    "timestamp": "last_edited_time",
    "last_edited_time": { "on_or_after": "2026-01-15T00:00:00Z" }
  }
}
```

## 정렬

`sorts`는 100개까지의 배열입니다. 앞의 항목부터 적용합니다.

```json theme={null}
{
  "sorts": [
    {
      "property": "마감일",
      "direction": "ascending"
    },
    {
      "timestamp": "created_time",
      "direction": "descending"
    }
  ]
}
```

* `direction`은 `ascending` 또는 `descending`입니다.
* `timestamp`는 `created_time` 또는 `last_edited_time`입니다. 정렬은 분 단위가 아니라 저장된 시각으로 합니다.
* 정렬이 없거나 값이 같으면 최근에 만든 행부터 반환합니다.
* 빈 값은 오름차순과 내림차순 모두 뒤에 옵니다.
* 텍스트는 대소문자를 구분하지 않고, 같으면 대문자가 먼저입니다.
* `select`는 선택지 순서로 정렬합니다.

## 성능

필터나 정렬이 있으면 서버가 그 데이터베이스의 보이는 행을 모두 읽어 계산합니다. 필터와 정렬이 없으면 필요한 만큼만 읽습니다.

## 자주 발생하는 오류

| 메시지 | 원인 |
| - | - |
| `Could not find property with name or id: X` | 필터의 속성이 없습니다. |
| `Could not find sort property with name or id: X` | 정렬의 속성이 없습니다. |
| `The property type in the database does not match the property type of the filter provided: ...` | 속성과 필터 키가 다릅니다. |
| `body failed validation. Fix one: ...` | 없는 조건입니다. 사용할 수 있는 조건을 줄마다 보여 줍니다. |
| `... should be nested at most 2 levels deep.` | `and`와 `or`를 2단계 넘게 묶었습니다. |
| `body failed validation: body.filter should have at most 1000 conditions in total.` | 조건이 1,000개를 넘었습니다. |


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