# Manticore Search 29.9.0：分块自动嵌入和 mmap 列式访问

Manticore Search 29.9.0 新增了分块和多向量自动嵌入、嵌入输入限制、UTF-8 标识符、默认 mmap 列式访问，并修复了混合搜索、KNN、批量写入和分组相关问题。

[Manticore Search 29.9.0](/install/) 已发布。最大的变化在自动嵌入：长文档现在可以拆分为可搜索的块，一个文档也可以保留多个向量，而不是把全部内容压缩成一个向量。本版本还将 `mmap` 设为列式属性的默认访问模式，新增了更安全的嵌入工作负载控制、UTF-8 标识符、更好的备份支持，并修复了混合搜索、KNN、批量写入、分组搜索和模式变更中的问题。

本文涵盖 **29.0.3 到 29.9.0** 之间，也就是 29.0.2 之后发布的全部内容。

❤️ 感谢 [@tudorvasinca](https://github.com/tudorvasinca) 在 [PR #4857](https://github.com/manticoresoftware/manticoresearch/pull/4857)、[PR #4859](https://github.com/manticoresoftware/manticoresearch/pull/4859) 和 [PR #4873](https://github.com/manticoresoftware/manticoresearch/pull/4873) 中所做的工作。

---

## 升级说明

本版本没有覆盖整个发布的强制数据迁移。现有表和配置可以正常升级，但如果早期行为已经影响了你的数据，下面几项修复需要后续处理：

- 德语 sharp-s 规范化需要显式启用。将现有表切换到 `lemmatize_de_v2` 或 `lemmatize_de_v2_all` 会改变已索引的词项，因此需要重建普通表，或将文档重新写入新的 RT 表。
- 经过认证的 `BACKUP` 引入了 `backup` 授权操作。降级到 29.3.12 或更早版本之前，请移除所有 `backup` 授权。
- 列式属性现在默认使用 `mmap`，而不是缓冲式 `file` 读取。如果需要保留之前的访问模式，请显式设置 `access_columnar_attrs='file'`。

---

## 长文档可以保留多个嵌入

旧的自动嵌入路径会为每个文档生成一个向量，并截断无法放入模型输入窗口的文本。这对标题和短描述有效，但也意味着长文章末尾附近的相关段落可能永远进不了索引。

Manticore Search 现在支持五种[分块策略](https://manual.manticoresearch.com/Searching/KNN#Chunking-strategies)：

- `truncate` 保留之前的行为，并仍然是默认值。
- `mean` 会嵌入每个块，并将结果平均为一个向量。
- `fixed` 按固定大小的词元窗口拆分文本。
- `recursive` 会按段落、行、句子和空格的顺序优先选择边界。
- `sentence` 将完整句子分组到配置的限制以内。

多向量策略使用 [`float_vector_array`](https://manual.manticoresearch.com/Creating_a_table/Data_types#Float-vector-array)。每个块在 KNN 搜索中独立竞争，但 Manticore 只返回一次文档，并用其最近的块计算 `knn_dist()`：

```sql
CREATE TABLE articles (
  title text,
  content text,
  chunks float_vector_array knn_type='hnsw' hnsw_similarity='cosine'
    model_name='Xenova/all-MiniLM-L6-v2' from='title,content'
    chunk_strategy='sentence' max_tokens='256' overlap_tokens='32'
);

INSERT INTO articles (id, title, content)
VALUES (1, 'Rotating certificates', 'A long guide with many sections ...');

SELECT id, knn_dist()
FROM articles
WHERE knn(chunks, 5, 'how do I rotate a certificate');
```

`MAX_TOKENS`、`OVERLAP_TOKENS` 和 `MAX_CHUNKS` 分别控制块大小、边界处共享的上下文以及最大向量数量。创建表时请声明由模型支持的 `float_vector_array`：目前还不支持之后通过 `ALTER TABLE ... ADD COLUMN` 添加并重建其嵌入。

## 为本地嵌入工作设置上限

长上下文模型可能让单个大输入的成本意外升高，尤其是在 CPU 上。新的 [`MAX_INPUT_TOKENS`](https://manual.manticoresearch.com/Searching/KNN#Auto-Embeddings-%28Recommended%29) 列选项可以限制发送给本地嵌入模型的每个输入的规模：

```sql
ALTER TABLE articles
MODIFY COLUMN chunks MAX_INPUT_TOKENS='512';
```

该变更适用于之后生成的嵌入；现有向量保持不变。可以在 `CREATE TABLE` 时设置，也可以之后修改而不重新嵌入整张表。值为 `0` 或省略该选项时，会使用模型自身的限制。

本版本还修复了这一路径上两个不太明显的问题。修改嵌入列后，模型不再继续保留在缓存中；不同 `API_TIMEOUT` 或 `MAX_INPUT_TOKENS` 值的配置也不再发生冲突并复用错误的缓存模型。

---

## UTF-8 标识符和更好的德语匹配

表名、字段名和属性名现在遵循统一的[安全 UTF-8 标识符语法](https://manual.manticoresearch.com/Creating_a_table/Data_types#Table-and-field-name-syntax)。RT、percolate、分布式、模板和普通表都可以在 DDL、表达式、字段选择器和推断的源模式中使用本地化名称，例如中文或西里尔字母标识符。

德语 AOT 词形还新增了可选的 sharp-s 规范化。使用 `charset_table=non_cont,german`，并设置 `morphology=lemmatize_de_v2` 或 `lemmatize_de_v2_all` 时，`Straße`、`Strasse` 和 `STRAẞE` 等形式会在普通整词搜索中匹配。如果启用了 `index_exact_words=1`，精确词查询仍然可以区分 `ß` 和 `ss` 形式。

---

## 更好的负载测试和备份

[`manticore-load`](https://github.com/manticoresoftware/manticore-load) 现在可以通过 HTTP JSON API 使用 `--http` 进行基准测试。写入使用 `/bulk`，搜索使用 `/search`，`--table` 选择目标表。其报告现在会包含运行期间本地 `searchd` RSS，以及结束时的峰值 RSS、磁盘和 CPU 统计信息，并支持多命令工作负载的聚合监控。

[Manticore Backup](https://github.com/manticoresoftware/manticoresearch-backup) 现在可以通过用户名/密码或 bearer token 凭据，在启用认证的 Manticore Search 安装中工作。SQL [`BACKUP`](https://manual.manticoresearch.com/Securing_and_compacting_a_table/Backup_and_restore#General-syntax-of-BACKUP) 拥有专用的授权操作，并会检查所选表的读取权限。

当未设置静态密钥时，S3 备份和恢复也可以使用 AWS SDK 凭据提供者链。这包括 IRSA、共享凭据、ECS 任务角色和 EC2 实例配置文件。临时凭据可以提供 `AWS_SESSION_TOKEN`。

## 列式属性默认使用 mmap

Manticore Search 现在将 [`access_columnar_attrs`](https://manual.manticoresearch.com/Creating_a_table/Local_tables/Plain_and_real-time_table_settings#Accessing-table-files) 默认设为 `mmap`。操作系统会按需映射并缓存 `*.spc` 列式属性文件，而不需要在启动时预读整个文件。之前的缓冲路径仍可通过 `access_columnar_attrs='file'` 使用。

`ALTER TABLE` 也会使用配置的访问模式重新打开被替换的列式存储，因此修改后的表不再回退到与请求不一致的读取器。

---

## 向量和分组搜索修复

多项修复针对的是原本有效、但在特定表布局下可能返回不完整结果或失败的查询：

- 带有本地分片的分布式和分片 KNN 查询不再对合并后的 1-bit 量化结果重复重新打分，避免协调节点崩溃或返回错误的最近邻。([Issue #4791](https://github.com/manticoresoftware/manticoresearch/issues/4791))
- 带有额外过滤器的 KNN 查询会避免在 HNSW 已经排除没有向量的文档时再执行冗余的 `knn_dist` 预过滤。([PR #4861](https://github.com/manticoresoftware/manticoresearch/pull/4861))
- 对 `float_vector_array` 使用 `LENGTH()` 时，现在返回向量数量，而不是其内部存储词数量。([PR #4879](https://github.com/manticoresoftware/manticoresearch/pull/4879))
- 带 `GROUP BY` 的混合搜索会保留所有分桶，包括 MVA 分组，并同时遵循最终排序和组内排序。([Issue #4639](https://github.com/manticoresoftware/manticoresearch/issues/4639))
- 针对 `weight()` 以及由其派生的表达式或别名的混合过滤器，现在会在融合后基于最终文本权重执行，而不是被忽略。`OR` 树内部依赖权重的过滤器仍不受支持，并会返回明确错误。([Issue #4889](https://github.com/manticoresoftware/manticoresearch/issues/4889))
- 多块 RT 分组不再有重复分组、错误拆分计数，或在对 `COUNT(DISTINCT ...)` 结果排序时挂起的风险。([Issue #4856](https://github.com/manticoresoftware/manticoresearch/issues/4856))
- 有符号表示为负数的文档 ID 过滤器，现在会遵循查找索引的无符号排序。([Issue #4774](https://github.com/manticoresoftware/manticoresearch/issues/4774))

这里也包含崩溃修复：多语句请求中的第二条混合搜索语句（[PR #4864](https://github.com/manticoresoftware/manticoresearch/pull/4864)）、按字符串属性排序的分布式 JSON 聚合（[Issue #4822](https://github.com/manticoresoftware/manticoresearch/issues/4822)），以及在自动嵌入预提交期间删除表（[Issue #4860](https://github.com/manticoresoftware/manticoresearch/issues/4860)）现在都能安全处理。

## 批量写入行为更可预测

Elasticsearch 兼容的 `/_bulk` 请求现在会在批次处理完成后返回 HTTP `200`，而单项失败仍可通过 `errors: true` 和逐项状态查看。重复的 `create` 操作会返回逐项 `409` `version_conflict_engine_exception` 错误，包括同一批次内的重复项。这可以防止 Fluent Bit 等客户端重试已经成功的写入。

固定长度、gzip 压缩的 `/bulk` 请求体在跨多次 socket 读取到达时也能正确解码。此外，如果原生批量处理因目标表不存在而失败，请求可以再次携带有效 NDJSON 进入 Manticore 的自动模式回退，同时保留预期的批量响应封装。

---

## 更多可靠性修复

本版本其余部分修复了一系列运维和兼容性问题：

- 节点重新加入后，分片表正在重新均衡时，`searchd --stopwait` 不再挂起。([Issue #3905](https://github.com/manticoresoftware/manticoresearch/issues/3905))
- 升级期间兼容的旧 binlog 可以安全重放，已完成的 RT 块会在干净关闭前发布。([Issue #4808](https://github.com/manticoresoftware/manticoresearch/issues/4808)) 致命重放诊断也会指出相关的恢复标志。([Issue #4811](https://github.com/manticoresoftware/manticoresearch/issues/4811))
- 当最近的现有父目录可写时，`indexer` 会为普通表路径创建缺失的父目录。([Issue #4793](https://github.com/manticoresoftware/manticoresearch/issues/4793))
- UUID 文档 ID 不再导致存储的文本字段返回为空。([Issue #4833](https://github.com/manticoresoftware/manticoresearch/issues/4833))
- `ALTER TABLE ... RENAME` 会保留隐藏的远程嵌入 API 密钥，并且不会在 `SHOW CREATE TABLE` 中暴露。([Issue #4842](https://github.com/manticoresoftware/manticoresearch/issues/4842))
- Sequel Ace 5.3.1+ 兼容性探测恢复正常。([Issue #4828](https://github.com/manticoresoftware/manticoresearch/issues/4828))
- JSON `/search` 会为否定的 `NEAR` 和邻近操作符保留距离。([Issue #4784](https://github.com/manticoresoftware/manticoresearch/issues/4784))
- 内部字符串排序辅助列不再从 `LEFT JOIN` 结果中泄漏。([Issue #4788](https://github.com/manticoresoftware/manticoresearch/issues/4788))
- 格式错误的二进制 API `SEARCH` 元素数量现在会被拒绝，而不是终止 `searchd`。([PR #4790](https://github.com/manticoresoftware/manticoresearch/pull/4790))

完整列表请参阅 [Version 29.9.0 changelog](https://manual.manticoresearch.com/Changelog#Version-29.9.0)。

---

## 获取 Manticore Search 29.9.0

按照[安装指南](/install/)安装或升级 Manticore Search。如果你使用列式属性、德语 AOT 词形或经过认证的备份，请查看上面的升级说明。

## 需要帮助或想交流？

- 加入我们的 [Slack](https://slack.manticoresearch.com)
- 访问[论坛](https://forum.manticoresearch.com)
- 在 [GitHub](https://github.com/manticoresoftware/manticoresearch/issues) 上报告问题或建议功能
- 发送邮件至 `contact@manticoresearch.com`
