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

# 路由 (Routing)

> HeavenBase 跨后端的字段级存储放置与查询下发。

<Note>
  *Schema 说明是什么；路由决定放在哪里。*
</Note>

<br />

## 1. 路由做什么

路由将每个实体字段映射到一个或多个后端实例与存储策略。单个实体可把标量字段放在一个后端、向量放在另一个、可搜索文本放在第三个，而查询仍从 `ws.query(Entity)` 开始。

查询时，HeavenBase 为拥有该字段的后端编译每个 filter 或 `near` 子句，执行受支持的片段，再按 `object_id` 合并结果帧。

<Info>
  `object_id` 放置是固定的。HeavenBase 在需要处复制身份，使拆分字段仍能水合成一行逻辑行。
</Info>

<br />

## 2. 从自动放置开始

工作区 preset 选择实用默认值。在 `debug` 中，普通行去 `main`，向量字段可路由到 `vec`，面向搜索的字段可路由到 `search`。

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
import heavenbase as hb


class Document(hb.Entity):
    title = hb.field(hb.ShortText)
    body = hb.field(hb.LongText)
    embedding = hb.field(hb.Vector[2])


ws = hb.HeavenBase("core-routing-auto", preset="debug")
ws.register(Document)

ws.upsert_many(
    Document,
    [
        {"object_id": "d1", "name": "Agent routing", "title": "Agent routing", "body": "Agents query one surface.", "embedding": [1.0, 0.0]},
        {"object_id": "d2", "name": "Backend notes", "title": "Backend notes", "body": "Backends store fields.", "embedding": [0.0, 1.0]},
    ],
)

frame = ws.query(Document).near(Document.embedding, [1.0, 0.0], top_k=1).select("title", "score").execute()
print(frame.rows()[0]["title"])
```

<br />

## 3. 显式放置字段

字段必须落在特定后端时，使用 `.store(to=..., strategy=...)`。

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
class RoutedDocument(hb.Entity):
    title = hb.field(hb.ShortText).store(to="main")
    body = hb.field(hb.LongText).store(to="main")
    embedding = hb.field(hb.Vector[2]).store(to="vec", strategy=hb.VectorIndex)


ws = hb.HeavenBase(
    "core-routing-explicit",
    backends={
        "main": {"type": "inmem"},
        "vec": {"type": "inmem"},
    },
)
ws.register(RoutedDocument)

routes = (
    ws.query(hb.MetaSchema)
    .where(hb.MetaSchema.kind == "storage")
    .where(hb.MetaSchema.subject_id == "routed-document")
    .select("field", "backend", "strategy")
    .execute()
    .rows()
)

print([(row["field"], row["backend"]) for row in routes])
```

存储策略是面向后端的提示，例如 `InlineColumn`、`SideTable`、`VectorIndex`、`InvertedIndex`、`JsonField`、`GraphEdge` 与 `ExternalRef`。多数用户只需显式指定 `VectorIndex`。

<br />

## 4. 检查查询决策

需要查看查询将使用哪个后端与处理器时，用 `explain()`。

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
plan = (
    ws.query(RoutedDocument)
    .near(RoutedDocument.embedding, [1.0, 0.0], top_k=3)
    .explain()
)

print(plan["steps"][0]["backend"])
```

每一步报告所选后端、存储策略、处理器种类、处理器模式，以及原生路径不可用时的 unsupported 原因。

<br />

## 5. 保持心智模型简单

对应用代码，按此顺序思考：

1. 定义实体一次。
2. 让 preset 自动路由字段。
3. 仅对需要显式放置的字段添加 `.store(...)`。
4. 关心性能或后端选择时用 `explain()`。

<Warning>
  跨后端写入在多后端边界上是尽力而为。部署尚无清晰事务策略前，保持跨后端不变量简单。
</Warning>

<br />

## 进一步探索

<Tip>
  **相关资源：**

  * [实体](/zh/features/entities) - 声明类型化字段
  * [后端](/zh/features/backends) - 了解后端选择
  * [查询](/zh/features/query) - 执行并解释路由后的查询
  * [架构](/zh/introduction/architecture) - 路由背后的系统结构
</Tip>

<br />
