
LlamaIndex Key-Value Stores 存储抽象全解析Simple、MongoDB 与 Tablestore 的实现原理与实战【免费下载链接】llama_indexLlamaIndex is the document processing platform for AI项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index导读本文围绕 LlamaIndex 框架中支撑 Document Store 与 Index Store 的底层存储抽象——Key-Value StoreKV Store展开系统梳理其抽象接口设计、内置的三种实现内存版 SimpleKVStore、MongoDB 版与 Tablestore 版以及它们如何被上层存储组件消费。读完本文你将掌握 KV Store 的统一操作语义put/get/delete及异步变体、持久化与序列化机制、三种实现的选型依据以及如何用 KV Store 自定义底层存储来构建可复用的文档与索引存储。关联文档docs/src/content/docs/framework/module_guides/storing/kv_stores.md一、KV Store 在 LlamaIndex 存储体系中的定位在 LlamaIndex 的存储体系中KV Store 是最底层的键值存取抽象它是 Document Store 与 Index Store 的存储底座。也就是说节点Node内容的存取、索引结构IndexStruct的序列化最终都会落到 KV Store 的key - dict操作上。从 核心存储目录结构 可以看到清晰的分层storage/ ├── kvstore/ # KV Store 抽象与实现本文主题 │ ├── types.py # BaseKVStore 抽象基类与常量 │ ├── simple_kvstore.py # 内存版实现 │ └── __init__.py ├── docstore/ # 文档/节点存储依赖 kvstore │ ├── keyval_docstore.py # KVDocumentStore │ └── simple_docstore.py # SimpleDocumentStore ├── index_store/ # 索引结构存储依赖 kvstore │ ├── keyval_index_store.py # KVIndexStore │ └── simple_index_store.py # SimpleIndexStore └── storage_context.py # StorageContext 统一装配入口文档明确指出KV Store 是驱动 Document Store 和 Index Store 的底层存储抽象。原文档同时强调目前这些存储抽象并非面向外部用户的公开 API因此本文把它当作理解 LlamaIndex 存储机制的内部知识来深入讲解。注意原文档列出三种 KV Store——内存版Simple Key-Value Store、MongoDB 版与 Tablestore 版。其中后两种以独立集成包的形式维护在 llama-index-integrations/storage/kvstore/ 目录下读者可按需单独安装。二、统一抽象BaseKVStore 接口设计所有 KV Store 实现都继承自 BaseKVStore 抽象基类。它定义了一套统一的操作契约每个方法都同时提供同步与异步带a前缀两个版本方法作用说明put(key, val, collection)/aput(...)写入键值对每个实现都必须支持put_all(kv_pairs, collection, batch_size)/aput_all(...)批量写入基类默认仅支持batch_size1即逐个调用put不支持批量的实现会抛出NotImplementedErrorget(key, collection)/aget(...)读取单个值不存在时返回Noneget_all(collection)/aget_all(...)读取整个 collection 的全部键值返回Dict[str, dict]delete(key, collection)/adelete(...)删除键返回布尔值表示是否删除成功基类还定义了两个重要常量types.pyDEFAULT_COLLECTION data默认 collection 名称。collection 是 KV Store 中用于逻辑分区的命名空间类似 MongoDB 中的集合collection或关系型数据库中的表——不同用途的数据如节点正文、ref_doc 信息、索引结构会写入不同的 collection。DEFAULT_BATCH_SIZE 1批量写入的默认批次大小。除BaseKVStore外抽象层还提供两个中间基类BaseInMemoryKVStoretypes.py#L77-L89在BaseKVStore之上补充persist(persist_path, fs)与from_persist_path(persist_path)两个持久化相关的抽象方法是可落盘内存型 KV Store的契约。MutableMappingKVStoretypes.py#L95-L183泛型实现内部用_collections_mappings: Dict[str, MutableMappingT]把collection - 可变映射组织起来通过mapping_factory工厂函数创建每个 collection 的实际映射容器。它实现了大部分读写逻辑但persist/from_persist_path默认抛NotImplementedError提示请使用SimpleKVStore等子类——这正是SimpleKVStore存在的原因。从源码结构看这套抽象刻意把接口契约BaseKVStore、通用内存映射逻辑MutableMappingKVStore与具体后端SimpleKVStore、MongoDBKVStore、TablestoreKVStore三层分离使得上层KVDocumentStore/KVIndexStore无需关心底层是内存、MongoDB 还是 Tablestore。三、Simple Key-Value Store内存实现与持久化SimpleKVStore 是 LlamaIndex 内置的纯内存 KV Store继承自MutableMappingKVStore[dict]数据格式为Dict[str, Dict[str, dict]]即collection - (key - value)。3.1 核心能力初始化SimpleKVStore(dataNone)可选传入已有数据字典进行恢复。持久化persist(persist_path, fsNone)将整个 store 以 JSON 形式写入磁盘fs使用 fsspec 文件系统抽象默认fsspec.filesystem(file)因此天然支持传 S3、GCS 等 fsspec 兼容文件系统。写入前会自动创建目录。从磁盘加载类方法from_persist_path(persist_path, fsNone)读取 JSON 并构造新实例。字典互转to_dict()/from_dict()支持把整个 store 导出为普通字典或在SimpleKVStore与字典之间互转。由于它完全驻留内存进程退出后数据即丢失只有显式调用persist才会落盘——这是它与 MongoDB / Tablestore 版本最本质的区别适用于原型验证、单机小规模场景。3.2 序列化细节persist直接执行json.dumps(self._collections_mappings)即把collection - {key: value_dict}的嵌套结构整体序列化。这要求 value 必须是可 JSON 序列化的字典上层KVDocumentStore在写入前会通过doc_to_json把 Node 转为 JSON 字典恰好满足这一前提。四、MongoDB Key-Value Store服务化后端MongoDBKVStore 将 MongoDB 作为 KV Store 后端包名为llama-index-storage-kvstore-mongodb。它直接继承BaseKVStore是面向生产环境的分布式存储方案。4.1 构造与连接参数类型说明mongo_clientAny必填外部传入的 pymongoMongoClientmongo_aclientOptional可选的 pymongoAsyncMongoClient用于异步操作uri/host/portOptional连接信息用于记录实际连接由 client 建立db_nameOptional数据库名默认db_docstore两种推荐的构造方式# 方式一URI 连接 from llama_index.storage.kvstore.mongodb import MongoDBKVStore kvstore MongoDBKVStore.from_uri(mongodb://localhost:27017, db_namemy_kvstore) # 方式二主机与端口连接 kvstore MongoDBKVStore.from_host_and_port(localhost, 27017, db_namemy_kvstore)源码中两类工厂方法都会同时创建同步MongoClient与异步AsyncMongoClient异步客户端用于aget/aput等异步 API并以appnameLlama-Index-KVStore-Python标识应用。若系统缺少pymongo会抛出提示pip install pymongo的ImportError。4.2 存储映射与读写实现MongoDBKVStore 的映射策略非常直接base.py#L186-L298collection 映射到 MongoDB 的 collectionself._db[collection]key 映射到文档的_id字段写入时构造{_id: key, **value}即 value 的所有字段平铺到文档中写入使用UpdateOne(..., upsertTrue)批量执行put_all按batch_size分片对每个文档执行 upsert保证幂等写入读取时剥离_idget/get_all取出文档后pop(_id)将剩余字段作为 value 返回对上层透明删除按_id执行delete_one({_id: key})返回deleted_count 0作为成功标志。异步版本aput_all/aget/aget_all/adelete依赖异步客户端若未传入mongo_aclient会抛出ValueError提示未使用异步客户端初始化。MongoDB 版本支持真正的batch_size批量写入这是它相对基类默认行为的重要增强并原生具备数据持久化、副本集与分布式能力适合对数据可靠性要求高的场景。五、Tablestore Key-Value Store阿里云表格存储后端TablestoreKVStore 以阿里云 Tablestore表格存储OTS为后端包名为llama-index-storage-kvstore-tablestore。5.1 构造参数参数类型说明tablestore_clientOptional[OTSClient]外部传入的 OTS 客户端一旦传入以下四个参数全部被忽略endpointOptional[str]Tablestore 实例端点instance_nameOptional[str]Tablestore 实例名access_key_id/access_key_secretOptional[str]阿里云访问密钥当不传客户端时内部自动构造tablestore.OTSClient(endpoint, access_key_id, access_key_secret, instance_name, retry_policytablestore.WriteRetryPolicy(), **kwargs)其中显式启用了写入重试策略。5.2 Tablestore 特有的表管理与序列化与 MongoDB 不同Tablestore 是表 主键列 属性列模型因此实现上有两个显著特色collection 映射为表表不存在时自动创建base.py#L71-L93_create_collection_if_not_exist会先查list_table()若目标表不存在则以单主键列[(pk, STRING)]建表预留吞吐CapacityUnit(0, 0)创建成功后sleep(5)等待表生效。value 序列化策略base.py#L54-L64_flatten_dict_to_json_strings把 value 字典中非标量类型非 bool/bytearray/float/int/binary/str的值json.dumps成字符串存储标量原样保留读取时_parse_row反向尝试json.loads还原 JSON 字符串。这一机制规避了 Tablestore 对列类型的限制。5.3 读写与遍历put以key作为主键(pk, key)把 value 的属性列写入tablestore.Row并put_rowgetget_row按主键读取解析后返回当服务端返回OTSParameterInvalid且错误信息包含table not exist时返回Noneget_all使用get_range从INF_MIN到INF_MAX正向遍历整表每批limit5000通过next_start_primary_key分页循环取完全部数据delete_all同样用get_range遍历并逐行删除。需要特别说明Tablestore 版本的异步方法aput/aget/aget_all/adelete目前直接抛出NotImplementedError仅支持同步 API——这是从源码确认的实现现状选用时需注意。六、KV Store 如何驱动 Document Store 与 Index Store理解了三种实现之后再看它们在上层如何被消费就能完整还原 KV Store 的价值。6.1 KVDocumentStore文档存储的 KV 视角KVDocumentStore 是 LlamaIndex 文档存储的通用实现它把文档Node存储建模为三个逻辑 collection源码常量定义Collection 常量实际名称默认 namespacedocstore存储内容DEFAULT_COLLECTION_DATA_SUFFIXdocstore/data每个 Node 的正文与属性序列化 JSONDEFAULT_REF_DOC_COLLECTION_SUFFIXdocstore/ref_doc_info文档 - 其节点 ID 列表的映射RefDocInfoDEFAULT_METADATA_COLLECTION_SUFFIXdocstore/metadata节点 - 所属 ref_doc_id 与 doc_hash 的元数据add_documents会把 Node 转换成三类键值对_prepare_kv_pairs再通过kvstore.put_all(..., batch_sizebatch_size)分别批量写入三个 collection读取、删除、哈希校验等操作也都落在kvstore.get/get_all/delete上。因此KVDocumentStore 的底层行为完全由你传入的 KV Store 决定——换一个 KV Store 实现就等于换了一套存储后端。6.2 KVIndexStore索引结构的 KV 视角KVIndexStore 同样依赖BaseKVStore把IndexStruct序列化为 JSON 后存入默认 collectionindex_store/datanamespaceindex_store 后缀/data。add_index_struct以index_struct.index_id为 key 写入get_index_struct/index_structs从 KV Store 读回并反序列化。6.3 组装方式与共享存储两个通用实现分别派生出默认的简单版本SimpleDocumentStore(KVDocumentStore)simple_docstore.py默认使用SimpleKVStoreSimpleIndexStore(KVIndexStore)simple_index_store.py默认同样使用SimpleKVStore。提示KVDocumentStore/KVIndexStore的命名空间namespace与 collection 后缀均可自定义MongoDBKVStore、TablestoreKVStore也可以直接作为这两个类的kvstore参数传入实现同一套存储逻辑、不同的底层后端。七、实战三种 KV Store 的选型与用法速查7.1 安装# 内存版已包含在 llama-index-core 中无需额外安装 pip install llama-index-core # MongoDB 版 pip install llama-index-storage-kvstore-mongodb # Tablestore 版 pip install llama-index-storage-kvstore-tablestore7.2 直接使用 KV Store# SimpleKVStore内存 持久化 from llama_index.core.storage.kvstore import SimpleKVStore kv SimpleKVStore() kv.put(key1, {content: hello}, collectionmy_coll) print(kv.get(key1, collectionmy_coll)) # {content: hello} kv.persist(./kvstore.json) # 落盘 loaded SimpleKVStore.from_persist_path(./kvstore.json)# MongoDBKVStore服务化后端 from llama_index.storage.kvstore.mongodb import MongoDBKVStore kv MongoDBKVStore.from_uri(mongodb://localhost:27017, db_namemy_db) kv.put(key1, {content: hello}, collectionmy_coll) print(kv.get(key1, collectionmy_coll))7.3 将 KV Store 接入 Document Store / Index Storefrom llama_index.core.storage.docstore import KVDocumentStore from llama_index.core.storage.index_store import KVIndexStore from llama_index.storage.kvstore.mongodb import MongoDBKVStore kvstore MongoDBKVStore.from_uri(mongodb://localhost:27017, db_namemy_db) # 使用同一个 KV Store 构建 docstore 与 index_store docstore KVDocumentStore(kvstorekvstore) index_store KVIndexStore(kvstorekvstore)7.4 选型建议维度SimpleKVStoreMongoDBKVStoreTablestoreKVStore存储位置进程内存可选落盘 JSONMongoDB 服务阿里云 Tablestore异步 API✅ 支持✅ 支持需异步客户端❌ 抛NotImplementedError批量写入仅batch_size1✅ 原生批量 upsert逐行写入持久化/高可用手动persist由 MongoDB 提供由 Tablestore 提供典型场景原型、单机、临时缓存生产环境、多实例共享阿里云生态内生产环境八、总结KV Store 是 LlamaIndex 存储体系的地基BaseKVStore定义了put/get/delete与异步变体的统一契约MutableMappingKVStore提供了通用的内存映射骨架而SimpleKVStore、MongoDBKVStore、TablestoreKVStore则分别面向进程内存 JSON 落盘MongoDB 服务阿里云表格存储三种后端。上层KVDocumentStore与KVIndexStore通过 collection 划分逻辑空间把节点内容、ref_doc 关系、索引结构全部映射为键值操作。理解这层抽象后你可以用SimpleKVStore.persist快速实现可复现的原型用MongoDBKVStore.from_uri无缝切换生产级后端且获得原生批量写入与异步支持结合 StorageContext 统一装配自定义的 docstore / index_store实现多索引共享同一套底层存储。更深入的接口签名与参数细节可查阅 API ReferenceKV Store 部分 及本文引用的各源码文件。【免费下载链接】llama_indexLlamaIndex is the document processing platform for AI项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考