# JSON 文件

本頁說明 ToriiDB 如何儲存 JSON 值，以及如何以點記法路徑讀取巢狀欄位。

## 儲存表示

值為合法 JSON 且最外層是 object 或 array 時，型別為 `json`。Entry 保留原始字串，解析後的副本快取在未導出的 `parsed` 欄位。

| 方法 | 角色 | 鎖 |
|---|---|---|
| `Value()` | 原始序列化字串 | 任意 |
| `parseAndCache()` | 快取未命中時解碼並儲存 | 寫鎖，或單執行緒重播 |
| `cached()` | 回傳已預熱的快取，不做修改 | 讀鎖即可 |
| `setValue(v)` | 取代原始字串並清除快取 | 寫鎖 |
| `setParsed(obj)` | 序列化 `obj` 並同時保存兩種形式 | 寫鎖 |

若在讀鎖路徑混用 `parseAndCache()`，兩個讀取者（例如兩個 `Query`）會在快取上 race。因此每個 JSON 寫入都在寫鎖下預熱快取，讀取者只使用 `cached()`。

## 點記法路徑

`Exec` 在第一個 `.` 切開鍵；其餘部分以 `.` 分割並丟棄空段：

```text
user.profile.level   → key "user", path [profile level]
user.tags.0          → key "user", path [tags 0]
user.                → key "user", no path
```

Object 以欄位名稱定位，array 以十進位索引定位。在 REPL 中，含 `.` 的頂層鍵因此無法用點記法存取；Go API 與 daemon 則分開接收鍵與路徑。

## 讀取欄位

```text
GET user.profile.level
EXIST user.profile.level
TYPE user.profile.level
```

`GetField` 在讀鎖下走訪 object 與 array（含頂層 array）。值以 `utils.Vtoa` 呈現：整數不帶小數點、object 與 array 為壓縮 JSON、`null` 為 `(nil)`。`TypeField` 對呈現後的文字執行一般型別偵測。

## 相關頁面

- [寫入 JSON 欄位](/zh/json-documents-writes)
- [QUERY 運算式](/zh/querying-query)
- [值型別](/zh/core-concepts-value-types)
