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

# 查询 (Query)

> 类型化与 JSON 查询面，含后端路由、ResultFrame 输出与 explain 诊断。

<Note>
  *问一次；HeavenBase 决定由谁回答。*
</Note>

<br />

## 1. 构建查询 (Query)

从 `ws.query(Entity)` 开始，再添加 filter、向量搜索、投影、排序、分页与执行。

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


class Article(hb.Entity):
    title = hb.field(hb.ShortText)
    body = hb.field(hb.LongText)
    tags = hb.field(hb.Array[hb.ShortText]).default([])
    embedding = hb.field(hb.Vector[2])


ws = hb.HeavenBase("core-query", preset="debug")
ws.register(Article)
ws.upsert_many(
    Article,
    [
        {"object_id": "a1", "name": "Agent memory", "title": "Agent memory", "body": "Agents need searchable memory.", "tags": ["agent"], "embedding": [1.0, 0.0]},
        {"object_id": "a2", "name": "Backend plan", "title": "Backend plan", "body": "Backends store physical fields.", "tags": ["storage"], "embedding": [0.0, 1.0]},
    ],
)

frame = (
    ws.query(Article)
    .where(Article.body.match("agent"))
    .near(Article.embedding, [1.0, 0.0], top_k=3)
    .select("title", "score")
    .limit(2)
    .execute()
)

print(frame.rows())
```

`execute()` 返回 `ResultFrame`，而非后端 cursor。

<br />

## 2. 读取 ResultFrame

`ResultFrame` 即使只投影少量列，也保留 `object_id`。

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
rows = frame.rows()
print(rows[0]["object_id"])
print(frame.ids)
print(frame.col_names())
```

这对 Agent 是刻意的：它们可展示紧凑行，之后用同一身份调用 `get`、`set`、`delete`、`query` 或 `explain`。

<br />

## 3. 使用 Filter

字段引用构建类型化 filter 表达式。可用 `&`、`|`、`~` 组合。

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
not_storage = ws.query(Article).where(Article.title != "Backend plan").execute()
tagged = ws.query(Article).where(Article.tags.array_contains("agent")).execute()
combined = ws.query(Article).where((Article.body.match("agent")) & (Article.title != "Draft")).execute()

print(len(not_storage), len(tagged), len(combined))
```

Agent 或外部客户端需要可序列化查询 spec 时，用 `query_json`。

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
json_frame = ws.query_json(
    Article,
    {
        "filter": {
            "body": {"$match": "agent"},
            "tags": {"$array_contains": "agent"},
        },
        "select": ["title"],
        "limit": 5,
    },
).execute()

print(json_frame.rows())
```

<br />

## 4. Mongo 风格 JSON 查询

`where()` 也接受 Mongo 风格 filter 字典。运算符键使用 `$` 前缀，裸值表示 `$eq`，`$and`、`$or` 与 `$not` 组合子句。

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
mongo_frame = (
    ws.query(Article)
    .where(
        {
            "$and": [
                {"body": {"$match": "agent"}},
                {"title": {"$in": ["Agent memory", "Backend plan"]}},
            ]
        }
    )
    .execute()
)

print(mongo_frame.rows())
```

支持的 `$` 运算符映射到已注册的逻辑运算：`$eq`、`$ne`、`$lt`、`$lte`、`$gt`、`$gte`、`$in`、`$match`、`$like`、`$ilike`、`$wildcard`、`$regex`、`$contains`、`$array_contains`、`$exists` 与 `$all`。在 Array 字段上，`$contains` 会自动规范化为 `array_contains`。同一 filter 形状可作为 `query_json` spec 的 `filter` 键使用。

<br />

## 5. 检查 Explain 计划

需要路由诊断时，在执行前调用 `explain()`。

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
plan = ws.query(Article).where(Article.body.match("agent")).explain()
print(plan["steps"][0]["backend"])
print(plan["steps"][0]["handler_mode"])
```

计划报告存储放置、所选后端、策略、处理器 (Handler) 种类、处理器 (Handler) 模式，以及回退路径的 unsupported 原因。

<br />

## 6. 在查询外变更行

查询 (Query) 用于读行。写入、更新与删除用 CRUD 方法。

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
object_id = ws.upsert(
    Article,
    {
        "name": "Query note",
        "title": "Query note",
        "body": "Keep the returned object_id.",
        "tags": ["docs"],
        "embedding": [1.0, 0.0],
    },
)

ws.set(object_id, {"title": "Updated query note"}, entity=Article)
print(ws.get(object_id, entity=Article)["title"])
print(ws.delete((Article, object_id)))
```

当 `object_id` 可能存在于多种实体 (Entity) 类型下时，传入 `entity=...`。

<br />

## 进一步探索

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

  * [实体 (Entity)](/features/entities) - 定义可查询字段
  * [路由 (Routing)](/features/routing) - 了解查询片段如何下发
  * [目录 (Catalog)](/features/catalog) - 类型化查询前发现对象
  * [HeavenBase MCP](/quickstart/heavenbase-mcp) - 向 Agent 暴露查询
</Tip>

<br />
