Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

简介

本书另有英文原版(English)。

PurRDF 是一个 RDF 1.2 工具包:图原语、编解码器、SPARQL、SHACL、ShEx、蕴涵与图传输,以 Rust 实现一次,并原样带入 Python、WebAssembly/JavaScript 与 C,但有一处例外须先行说明:GTS 容器可从 Rust、CLI(作为输入格式)、Python 与 C 访问,而 wasm/JavaScript 包并不公开它。每一个已发布的 crate 都能构建到 wasm32-unknown-unknown,因此在服务器上回答某条查询的引擎,也会在浏览器标签页中逐字节地给出同一答案。它由黑猫信息科技(Blackcat Informatics® Inc.)开发,以 MIT OR Apache-2.0 OR MulanPSL-2.0 发布。

译注:本书为英文文档的中文译本;未翻译或标为待确认的段落保留英文原文。运行时字符串——命令行 --help、诊断消息与 Python __doc__——不作本地化;稳定诊断代码的中文说明见诊断代码参考。

同一个 RDF 引擎。同一套行为。每一种语言。

它从架构中移除了什么。 通常让一个 PostgreSQL 实例伴随三元组存储运行的三项工作——带排名的全文检索、空间谓词与向量相似度——都在 PurRDF 内部得到回答:进程内、同一数据集、同一条 SPARQL 查询,没有第二个数据库,也没有同步作业。数值契约是明确的:精确的文本得分、经过认证的地理结果,以及确定的 binary64 向量得分。见下文一个引擎取代三个数据库。

PurRDF 为何存在?

RDF 工具沿两条轴线碎片化。

跨语言:每个生态都有自己的解析器,带着自己的缺陷、自己对边界情况的解读,以及自己所实现的规范子集。把一张图从 Rust 服务搬到 Python 流水线再搬到浏览器,数据的含义就已被悄悄改变了三次。

跨时间:RDF 1.2——三元组项、具体化节点(reifier)、基础方向字面量——是标准的现行修订版,而几乎没有哪个现存的库承载它。

PurRDF 之所以存在,是为了让一张图在任何地方都是同一张图。它是一个从零实现、依赖极简的 Rust 核心——从解析器到 SPARQL 引擎到 SHACL 验证器再到二进制传输——经由原生绑定公开,而不是逐语言重新实现。

里面有什么

  • RDF 1.2 图原语——一个不可变的、按值驻留的数据集 IR(TermId 空间、字符串存储区、写时复制的变更),带有宾语位置的三元组项、具体化节点/注解侧表(side table),以及基础方向字面量。参见驻留数据集 IR。
  • 原生编解码器——Turtle、TriG、N-Triples、N-Quads、RDF/XML、TriX、HexTuples、JSON-LD (star) 与 YAML-LD 的第一方解析器/序列化器,输出逐字节确定。参见编解码器与确定性。每种语法都经由同一个 RFC 3986 层解析相对 IRI(国际化资源标识符)引用,而作用域内没有基准的相对引用是硬错误。参见基准 IRI 与相对引用。
  • 规范化——在 RDF 1.1 子集上是 W3C RDFC-1.0;在 RDF 1.2 构造之上,则是扁平形式(在 rdf:reifies 三元组上运行 RDFC-1.0)或第一方的 purrdf-rdfc12 profile 二者之一,以不同的名字区分——外加数据集 diff 与同构判定。参见规范化与 Diff。
  • 投影与载体——确定性的 LPG、CSVW、OBO Graphs、数据集描述与 Research Object(RO)投影,每一种都带有定位到具体位置的损失台账。参见图、表格与 Research Object 投影。
  • SPARQL 1.1/1.2——原生解析器 → 代数 → 多重集求值器,带有完整的 Update、SEP-0002 时间算术、LATERAL(SEP-0006)、SEP-0008 的 SHA-3 哈希内建函数(SHA3-224/256/384/512)、能 CONSTRUCT 进命名图的四元组模板(这是第一方扩展,并非 SPARQL 1.2 特性)、SEP-0009 复合数据类型(cdt:List/cdt:Map、FOLD、UNFOLD——并有一处明确陈述的分歧:PurRDF 允许 RDF 1.2 三元组项与带方向的语言标签字面量作为复合元素,这是一个词法超集,符合 SEP-0009 的读取器会将其判为格式错误)、调用方注册的聚合函数与属性函数(包括逐跳绑定遍历过程的路径见证(path witness))、带逐节点解释回执的受调控执行,以及一个 SERVICE 扩展点——一个宿主注入的、携带逐服务上下文的服务解析器(resolver);不附带 HTTP 客户端,也不附带服务解析器,因此在每个随库发布的接口上,SERVICE 与 LOAD 都会按名称失败,除非写作 SILENT——全部由 W3C 一致性套件把关。参见 SPARQL。
  • 核心 crate purrdf-core 之外的 SPARQL 扩展——采用精确定点 BM25 的确定性全文检索(全文检索)、保留精确坐标输入并提供数值认证的 GeoSPARQL 1.1(GeoSPARQL),以及在 PURREMB 嵌入空间上的最近邻搜索(嵌入最近邻)——每一个都是扩展点(extension seam)的使用方,在调用方提供的 IRI 之下注册。
  • SHACL 与 ShEx——两种形状语言的原生验证器;SHACL 引擎实现了 SHACL 1.2 Core、SPARQL 扩展、节点表达式与推理规则,以及 SPARQL 1.2 RL 规则语言。参见验证。
  • 蕴涵——Simple/RDF/RDFS/OWL-RL/D 物化(全部 78 条 OWL 2 RL 规则均已实现——这是规则表覆盖率,有别于蕴涵一致性;在这份随库固化(vendored)的 W3C 语料上,OWL 2 RL 蕴涵测试的成绩是正例 27/27、负例 23/23)、一个 OWL-Direct tableau,以及 RIF-Core 规则,每次求推理闭包都附带推理报告。参见蕴涵,其求值基于 Datalog 不动点引擎。
  • GTS 图传输——面向 RDF 1.2 图与二进制载荷的单文件、内容寻址、仅追加的容器。参见 GTS 图传输。
  • 切片、映射与溯源——切片目录、显式的 RDF↔GTS 损失台账、SSSOM 与 FnO。参见切片、映射与溯源。

一个引擎取代三个数据库

需要带排名的文本检索、空间谓词或最近邻搜索的 RDF 项目,通常正是为了这三项工作而在三元组存储旁边运行一个 PostgreSQL。PurRDF 直接在已加载到内存的数据集上、通过求值器提供的、以调用方为键的扩展点,用 SPARQL 回答全部三项——下面每个页面都以「它的接口取代了什么、止步于何处」开篇。

所需能力通常来自如今在 PurRDF 之内止步于何处
带排名的全文检索PostgreSQL tsvector/tsquery全文检索:purrdf-text,一个覆盖 RDF 1.2 字面量的倒排索引,以精确的 i128 定点数做 BM25 排名,crate 内没有浮点。精确 BM25F、显式词干提取与词典分析,以及独立的汉字检索;没有停用词表或查询方言;检索冻结数据集的内存索引。
空间谓词PostGISGeoSPARQL:通过 purrdf-geo 使用 purrdf-geo-kernel,包括精确的 WKT/GeoJSON 坐标、DE-9IM 关系、地理度量、缓冲区及显式坐标操作;不依赖 GEOS 或 PROJ。参考系、单位、操作链、数值上限及容差均须显式指定。不支持栅格;凹包及叠加集合运算仍按名称返回拒绝错误。具体函数覆盖范围见该章。
向量相似度pgvector嵌入最近邻:在 PURREMB 嵌入空间上的精确 top-k,binary64 且累加顺序固定。由调用方提供的 KnnGuard 限定的精确扫描,三种度量,没有近似索引;PurRDF 不计算嵌入——向量来自由调用方填充的 PURREMB 工件,该工件由 PurRDF 自身写出(EmbeddingBuilder、EmbeddingStreamWriter;仅限 Rust),并以失败即关闭(fail-closed)的方式打开。

文本排名使用精确定点数;嵌入搜索使用固定的 binary64 累加顺序和规范的并列判定。地理请求保留精确的输入坐标,并采用显式数值认证。原生测试固定数值与序列化的预期结果。make wasm 为 wasm32-unknown-unknown 构建这些功能的发布 crate;针对性的可移植测试实际执行分派、内核与宿主接口。文本索引与嵌入空间通过 Rust 宿主的注册扩展点接入,使用调用方提供的 IRI,宿主也可编译到 wasm32。打包后的地理宿主入口见 GeoSPARQL。

第一天就值得知道的两条设计规则

没有语义性的 Cargo feature。 每个使用方得到同样的、逐字节相同的语义。唯一的 feature 声明是 cargo-c 所需的空兼容性标记 purrdf-capi:capi = [];它不控制任何代码。CI 拒绝其他 feature、可选依赖及受 feature 控制的行为。

应用词汇表必须显式指定。 PurRDF 是工具包,不是本体。结构化 Markdown 与有序 JSON 提供具名的标准 profile;调用方须有意选择它们,或自行提供词汇表。其他应用词汇表均由调用方配置,没有杜撰的默认值。在缺少其词汇表的情况下使用某项功能,要么硬错误,要么保持未激活。测试夹具使用 example.org。

完整的不变量清单见设计规则与不变量。

版本号所承诺的内容

自 1.0.0 起,整套软件完整遵循语义化版本:破坏性变更递增主版本号,次版本递增仅作增补,补丁版本递增仅修复缺陷,而 crates.io、PyPI 与 npm 上的包以同一个工作区版本同步发布。唯一的例外是 C ABI(purrdf.h),它带有自己的 0.x ABI 版本,每当导出签名变更时递增,且并未冻结。参见版本与发布。

为什么是 RDF 1.2?

RDF 1.2(以及 SPARQL 1.2)为数据模型加入了一等的陈述级元数据:可出现在宾语位置的三元组项、为三元组的某次出现命名的具体化节点,以及用于双向文本的基础方向字面量(rdf:dirLangString)。PurRDF 把它们当作核心数据模型而非扩展:它们贯穿 IR、编解码器、SPARQL、SHACL 1.2(具体化节点形状与三元组项节点类型)、RDF/JS 接口以及 GTS 传输。参见 RDF 1.2 特性。

PurRDF 的位置

PurRDF 是一小族关联数据项目的库层:它是 GMEOW 技术栈的数据骨干,也是 Rust 版 GTS 引擎的参考实现所在——但它对调用方的本体或应用不作任何假设。

如何阅读本书

API 参考文档位于 docs.rs/purrdf;仓库是 github.com/Blackcat-Informatics/purrdf。