内容参考于:图灵AI大模型全栈

LLamaIndex中使用StorageContext来管理存储

LLamaIndex会存储原始数据(Docstore)、索引元数据(IndexStore)、向量数据(VectorStore)、知识图谱(GraphStore)

原始数据存储的是分割完的原始文档

索引元数据存储的是相当于一个目录,通过目录去找文档和向量的映射关系

上方的原始数据(Docstore)、索引元数据(IndexStore)、向量数据(VectorStore)是可以插拔的可以更换存储方式,StorageContext是用来管理上方4个的存储

首先查看官网说明,下图是文档的存储方式

地址:https://developers.llamaindex.ai/python/framework-api-reference/storage/docstore/

如下图红框,可以看到它可以存到Simple(会本地存储)、Readis(内存数据库)、Mongodb(数据库)中

这里使用SimpleDocumentStore,也就是下图红框来管理存储

它会创建下图的5个文件

default__vector_store文件存放向量数据

docstore文件存放文档内容,里面存的就是之前的节点格式的json

graph_store文件存放图数据

image__vector_store文件存放图片信息

index_store文件存放索引

如下图1和3,1是源文档,3是下一个文本节点

代码

# 导入目录文件加载器,用于读取本地文件并封装为 Document 对象
from llama_index.core import SimpleDirectoryReader
# 导入句子分割器,用于按语义边界将长文档切分为文本节点(TextNode)
from llama_index.core.node_parser import SentenceSplitter
# 导入简单文档存储类,内存型文档存储实现,支持节点的增删查改与本地持久化
# 作用:统一管理文本节点/文档的内容与元数据,是索引体系中文本数据的持久化载体
from llama_index.core.storage.docstore import SimpleDocumentStore
# 导入存储上下文容器,是 LlamaIndex 存储体系的统一调度入口
# 作用:聚合管理 docstore(文档存储)、vector_store(向量存储)、index_store(索引存储)等所有存储组件
#        提供统一的持久化、加载、初始化能力,避免单独管理各类存储
from llama_index.core import StorageContext


# ========== 第一步:加载本地文档 ==========
# 通过 SimpleDirectoryReader 加载指定的单个文本文件,返回 Document 对象列表
# input_files:直接指定目标文件路径列表,无需扫描整个目录,适合精准加载少量文件
documents = SimpleDirectoryReader(input_files=["./data_file/小说.txt"]).load_data()

# ========== 第二步:文档切分为文本节点 ==========
# 实例化默认配置的句子分割器(默认 chunk_size=1024、chunk_overlap=200)
# 调用 get_nodes_from_documents 将完整文档按语义边界切分为多个 TextNode 节点
nodes = SentenceSplitter().get_nodes_from_documents(documents)
# 打印切分后的节点列表,可查看节点数量与概览信息
print(nodes)

# ========== 第三步:创建文档存储并写入节点 ==========
# 实例化简单文档存储,默认是内存级存储,数据仅保存在运行内存中
# SimpleDocumentStore 特点:轻量、无外部依赖,基于字典存储节点,支持序列化到本地 JSON 文件
doc_store = SimpleDocumentStore()
# 向文档存储中批量添加节点
# 方法名 add_documents 兼容 Document 和 BaseNode 两类对象,节点会以 node_id 为键存入内部字典
doc_store.add_documents(nodes)

# ========== 第四步:构建存储上下文容器 ==========
# 通过 from_defaults 工厂方法创建存储上下文
# 作用:将我们自定义的 doc_store 注册到存储上下文中统一管理
# 未显式指定的存储组件(如 vector_store、index_store)会自动使用默认的内存实现
storage_context = StorageContext.from_defaults(docstore=doc_store)

# ========== 第五步:持久化存储到本地磁盘 ==========
# 调用 persist 方法将存储上下文中的所有存储组件序列化到本地目录
# 入参:目标目录路径,若目录不存在会自动创建
# 本示例会在 ./documents 目录下生成 docstore.json 文件,保存所有节点的完整数据
storage_context.persist("./documents")

# ========== 第六步:从本地磁盘加载已持久化的存储 ==========
# 通过 from_defaults 指定 persist_dir,读取本地持久化文件,重建存储上下文
# 底层会自动解析目录下的各类存储文件,还原 docstore、vector_store 等所有存储组件
new_storage_context = StorageContext.from_defaults(persist_dir="./documents")
# 打印文档存储中的所有文档字典
# docstore.docs 是存储的核心数据结构,类型为 Dict[str, BaseNode]
# 键为节点 ID(node_id),值为对应的节点完整对象,可直接读取节点文本、元数据等信息
print(new_storage_context.docstore.docs)

使用Mongodb存储,注意要连接外网

Mongodb官网下载地址:https://www.mongodb.com/try/download/community

首先下载Mongodb数据库,官网下载地址是一个msi的安装包,下载完双击运行即可,这里使用Docker下载

如下图配置,然后点击Run就可以了

如果想设置账户密码去问ai,把下图给ai

到这就安装好了Mongodb数据库了,接下来开始使用

首先安装下方的两个库

pip install llama-index-storage-docstore-mongodb
pip install pymongo

代码运行完就会有数据了,如下图,llama_index代码会自己创建

如下图读取的效果图

如下图红框,它会有三个集合,前面的novel是代码中设置的命名空间

点击下图红框

点击后会出现下图红框的内容,可以看到有embedding(向量)、metadata(元数据)、text(原始文档数据)

如下图data存放的是元数据、原始文档数据

metadata专门用来存储元数据,LlamaIndex自身用的

ref_doc_info就是之前说的目录,它对应一个原始文件,就是说通过SimpleDirectoryReader读取到原始文档后未分块之前它会有一个文档的唯一ID,这个ref_doc_info就把这个唯一ID保存了下来,然后分块后的文档,每一个分块都会带着这个文档的唯一ID,点击下图红框

可以看到这些id

然后复制下图红框的内容

然后来到data里,按CTRL+F搜索,是可以找到的,如下图红框的黄色高亮

代码

# 导入 LlamaIndex 核心组件:目录文件加载器、存储上下文
# SimpleDirectoryReader:批量/单个加载本地文件,封装为 Document 对象
# StorageContext:存储体系统一入口,聚合管理文档存储、向量存储等各类存储组件
from llama_index.core import (
 SimpleDirectoryReader,
 StorageContext
)
# 导入句子分割器,用于按语义边界将长文档切分为指定大小的文本节点
from llama_index.core.node_parser import SentenceSplitter
# 导入 MongoDB 版本文档存储实现
# 类全称:MongoDocumentStore
# 定位:生产级持久化文档存储,基于 MongoDB 数据库存储节点数据,替代内存/本地文件级的 SimpleDocumentStore
# 核心优势:支持海量节点持久化、多进程/多服务共享数据、支持查询与索引、适合线上生产环境
# 所属扩展包:llama-index-storage-docstore-mongodb,需单独安装
from llama_index.storage.docstore.mongodb import MongoDocumentStore


# ========== 1. 加载本地文档 ==========
# 使用 SimpleDirectoryReader 加载指定的单个文本文件,返回 Document 对象列表
# input_files:直接指定目标文件路径列表,无需扫描目录,适合精准加载少量文件
documents = SimpleDirectoryReader(
 input_files=["./data_file/小说.txt"]
).load_data()


# ========== 2. 文档切分为文本节点 ==========
# 实例化句子分割器,自定义切分粒度
# chunk_size=512:单个文本节点最大字符数为 512
# chunk_overlap=50:相邻节点首尾重叠 50 个字符,避免跨节点语义断裂
# 调用 get_nodes_from_documents 执行切分,返回 TextNode 列表
nodes = SentenceSplitter(
 chunk_size=512,
 chunk_overlap=50
).get_nodes_from_documents(documents)

# 打印切分后的节点总数,校验切分结果
print(f"切分后的 Node 数量:{len(nodes)}")

# ========== 3. 初始化 MongoDB 文档存储 ==========
# 使用 from_uri 工厂方法创建 MongoDocumentStore 实例,通过连接 URI 对接 MongoDB
# 入参说明:
#   uri:MongoDB 标准连接字符串,格式为 mongodb://账号:密码@地址:端口,本地无认证可简写为 mongodb://localhost:27017
#   db_name:目标数据库名称,所有存储数据会存入该数据库下
#   namespace:命名空间,用于同一数据库内的业务数据隔离
#             本质是集合名前缀,不同 namespace 对应不同的 MongoDB 集合,数据完全独立
#             适合多项目、多业务共用同一个 MongoDB 实例的场景,避免数据混淆
docstore = MongoDocumentStore.from_uri(
 uri="mongodb://localhost:27017",
 db_name="llama_index",
 # 命名空间文档多了之后方便做隔离
 namespace="novel"
)

# ========== 4. 构建存储上下文 ==========
# 将自定义的 MongoDB 文档存储注册到存储上下文中统一管理
# 未显式指定的向量存储、索引存储等组件,会自动使用默认的内存实现
# 如果后续想换数据库,执行修改下方docstore的值就可以了
storage_context = StorageContext.from_defaults(
 docstore=docstore
)

# ========== 5. 批量写入节点到 MongoDB ==========
# 调用 add_documents 方法,将所有切分后的节点存入 MongoDB 文档存储
# 注意:
#   1. 首次运行需打开该行注释执行写入;后续重复运行建议注释,避免重复写入数据
#   2. 节点以 node_id 为主键,重复写入的行为以官方实现为准,建议做好去重处理
# storage_context.docstore.add_documents(nodes)
# print("Node 已成功存入 MongoDB")


# ========== 6. 读取并预览 MongoDB 中的节点数据 ==========
print("\n=============== DocStore 数据 ===============\n")
# storage_context.docstore.docs 返回所有节点的字典,键为 node_id,值为节点完整对象
# 此处截取前 3 个节点做预览,避免输出过多内容
for node_id, node in list(storage_context.docstore.docs.items())[:3]:
 # 打印节点唯一 ID
 print(f"Node ID: {node_id}")
 # 打印节点文本的前 100 个字符,做内容预览
 print(node.text[:100])
 # 打印分隔线,区分不同节点
 print("-" * 50)


img

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐