# Data API: chọn cột, lọc và phân trang

Truy vấn có giới hạn và quyền theo từng bảng/cột/dòng. Cú pháp gần Django nhưng dùng object JavaScript.

Nguồn: https://whypik.com/docs/data-queries
Nhóm: Lập trình viên
Phiên bản tài liệu: 2026-10-14.10
Ngôn ngữ: vi

## Đọc cơ bản

Liên kết mục: https://whypik.com/docs/data-queries#section-0

select(...columns) trả mảng của một trang; first(...columns) trả object hoặc null khi đọc thành công nhưng không có dòng. Lỗi quyền/mạng vẫn throw. Không dùng filter(id=1) hoặc order_by.

```
const versions = await client.from("versions").select();
const player = await client.from("players").filter({id: "1"}).first();
const players = await client.from("players")
  .filter({server__id: "1", nickname__icontains: "tcn"})
  .orderBy("-modified", "id").limit(50).select("id", "nickname");
```


## Toán tử filter

Liên kết mục: https://whypik.com/docs/data-queries#section-1

| Toán tử | Ví dụ | Ý nghĩa |
| --- | --- | --- |
| eq (mặc định) | {nickname:"TCN"} / {nickname__eq:"TCN"} | Bằng; null thành IS NULL |
| gt / gte | {id__gt:"10"} | Lớn hơn / lớn hơn hoặc bằng |
| lt / lte | {modified__lte:"2026-10-08T00:00:00Z"} | Nhỏ hơn / nhỏ hơn hoặc bằng |
| in | {id__in:["1","2"]} | 1–100 giá trị khác null |
| icontains | {nickname__icontains:"tcn"} | Text chứa chuỗi, không phân biệt hoa thường; ký tự wildcard là dữ liệu |
| isnull | {server_id__isnull:true} | true hoặc false |


## Kết hợp và kiểu

Liên kết mục: https://whypik.com/docs/data-queries#section-2

Các điều kiện kết hợp AND. .filter() nhiều lần gộp object; khóa lặp lấy giá trị sau. Chưa có OR/NOT tùy ý, regex do người dùng nhập hay lọc sâu JSONB; JSONB chỉ kiểm tra null. bigint/numeric dùng chuỗi. Không thể lọc/sort bằng cột không được quyền đọc.


## Cursor và page

Liên kết mục: https://whypik.com/docs/data-queries#section-3

page() trả {data,page:{limit,next_cursor,revision},request_id}. Mặc định 50, limit tối đa kỹ thuật 1000 và còn chịu quota/response cap. Chỉ tải trang sau khi có next_cursor; giữ nguyên điều kiện/order/limit. Cursor có hạn và không phải snapshot khi dữ liệu đổi.

```
const query = client.from("players").orderBy("id").limit(50);
const firstPage = await query.page();
if (firstPage.page.next_cursor) {
  const nextPage = await query.cursor(firstPage.page.next_cursor).page();
}
```


## Hủy và vòng đời

Liên kết mục: https://whypik.com/docs/data-queries#section-4

abortSignal(signal) hủy request đang chờ; đọc không tự tải trang sau. Client hủy dữ liệu đang tải khi phiên thay đổi để tránh hiển thị dữ liệu user cũ. Mỗi modifier tạo snapshot độc lập.

```
const controller = new AbortController();
const pending = client.from("players").abortSignal(controller.signal).select("id");
// Khi rời màn hình: controller.abort();
await pending;
```


## Đọc tiếp

- [Quan hệ: include và lọc qua bảng liên kết](https://whypik.com/docs/data-relations)
- [Thêm, sửa, xóa bằng SDK](https://whypik.com/docs/data-writes)
- [Lỗi, timeout và chẩn đoán SDK](https://whypik.com/docs/sdk-errors)
- [Admin SDK: Database của Project](https://whypik.com/docs/data-admin)
