/** * QuintStore - 五元组存储类型定义 * * Quint = (G)raph, (S)ubject, (P)redicate, (O)bject, (V)ector * * 核心能力: * - RDF 四元组存储与查询 * - 通用操作符查询($startsWith, $contains 等) * - 向量嵌入存储(搜索后续再做) */ import type { Term, Quad } from '@rdfjs/types'; import type { AsyncIterator } from 'asynciterator'; import type { PredicateObjectDataTypes } from './value-types'; /** * 五元组 - 扩展 RDF Quad,增加向量 */ export interface Quint extends Quad { vector?: number[]; } /** * Term 名称类型 */ export type TermName = 'subject' | 'predicate' | 'object' | 'graph'; /** * 操作符值类型 - 可以是 Term、string 或 number * 存储层会自动处理序列化 */ export type OperatorValue = Term | string | number; /** * Term 操作符 - 用于灵活查询 * 值可以是 Term、string 或 number,存储层自动处理序列化 */ export interface TermOperators { $eq?: OperatorValue; $ne?: OperatorValue; $gt?: OperatorValue; $gte?: OperatorValue; $lt?: OperatorValue; $lte?: OperatorValue; $in?: OperatorValue[]; $notIn?: OperatorValue[]; $startsWith?: string; $endsWith?: string; $contains?: string; $regex?: string; /** RDF term lexical string operators for STR(?object) pushdown. */ $strStartsWith?: string; $strEndsWith?: string; $strContains?: string; $strRegex?: string; $language?: string; $notLanguage?: string; $langMatches?: string; $datatype?: Term; $notDatatype?: Term; $termType?: 'iri' | 'blank' | 'literal' | 'numeric'; $isNull?: boolean; } /** * Term 匹配 - Term 精确匹配或操作符匹配 */ export type TermMatch = Term | TermOperators; /** * 判断是否为 Term(而非操作符) */ export declare function isTerm(value: TermMatch): value is Term; /** * 查询模式 */ export interface QuintPattern { subject?: TermMatch; predicate?: TermMatch; object?: TermMatch; graph?: TermMatch; } /** * 查询选项 */ export interface QueryOptions { limit?: number; offset?: number; order?: TermName[]; reverse?: boolean; } /** * 复合查询模式 - 多个 pattern 通过 subject 关联 * 用于多 pattern + FILTER 查询,由数据库内部做 JOIN */ export interface CompoundPattern { /** 多个 pattern,每个 pattern 对应一个三元组匹配 */ patterns: QuintPattern[]; /** JOIN 的字段,通常是 subject */ joinOn: TermName; /** 返回哪些字段的值 */ select?: { pattern: number; field: TermName; alias: string; }[]; } /** * 存储统计信息 */ export interface StoreStats { totalCount: number; vectorCount: number; graphCount: number; databaseBytes?: number; tableBytes?: number; indexBytes?: number; spaceObjects?: StoreSpaceObject[]; } export interface StoreSpaceObject { name: string; kind: 'table' | 'index' | 'internal' | 'unknown'; tableName?: string; bytes: number; pages: number; } /** * QuintStore 配置选项 */ export interface QuintStoreOptions { debug?: boolean; /** * Predicate-level RDF object data declarations. * * This declares schema value types, not query modes. The store derives * whether exact/range/prefix/search can be pushed down from the data type. */ predicateObjectDataTypes?: PredicateObjectDataTypes; /** * Maximum serialized byte length that can be indexed as text. * Longer undeclared text literals are stored as longText. */ textMaxBytes?: number; } /** * 复合查询结果 - 包含多个 pattern 的绑定值 */ export interface CompoundResult { /** JOIN 字段的值 */ joinValue: string; /** 各 pattern 的匹配结果,key 是 alias */ bindings: Record; /** 原始 quad 数据(可选,用于获取完整信息) */ quads?: Quint[]; } /** * 批量属性查询结果 * Map> */ export type AttributeMap = Map>; /** * QuintStore - 五元组存储抽象基类 */ export declare abstract class QuintStore { abstract get(pattern: QuintPattern, options?: QueryOptions): Promise; abstract match(subject?: Term | null, predicate?: Term | null, object?: Term | null, graph?: Term | null): AsyncIterator; abstract getByGraphPrefix(prefix: string, options?: QueryOptions): Promise; abstract count(pattern: QuintPattern): Promise; getCompound?(compound: CompoundPattern, options?: QueryOptions): Promise; /** * 批量获取多个 subject 的多个属性 * * 用于优化 OPTIONAL 查询:先用 WHERE 条件获取 subjects, * 然后一次性获取所有属性,避免每个 OPTIONAL 变成一次 LEFT JOIN * * SQL: SELECT subject, predicate, object FROM quints * WHERE subject IN (...) AND predicate IN (...) * * @param subjects - 要查询的 subject IRIs * @param predicates - 要获取的属性 predicate IRIs * @param graph - 可选,限定图 * @returns Map> */ getAttributes?(subjects: string[], predicates: string[], graph?: Term): Promise; abstract put(quint: Quint): Promise; abstract multiPut(quints: Quint[]): Promise; abstract updateEmbedding(pattern: QuintPattern, embedding: number[]): Promise; abstract del(pattern: QuintPattern): Promise; abstract multiDel(quints: Quint[]): Promise; abstract open(): Promise; abstract close(): Promise; abstract stats(): Promise; abstract clear(): Promise; }