主题
大多数 LlamaIndex 索引结构都支持插入、删除、更新与刷新操作。
插入
在初次构建好索引之后,你可以把新的 Document “插入”任意索引数据结构。该文档会被拆分成节点并被摄取进索引。
插入的底层机制取决于索引结构。比如摘要索引会把新 Document 作为额外的节点插入那条列表;向量库索引则把新 Document(及其嵌入)插入底层的文档/嵌入存储。
下面给一段代码示例:
from llama_index.core import SummaryIndex, Document
index = SummaryIndex([])
text_chunks = ["text_chunk_1", "text_chunk_2", "text_chunk_3"]
doc_chunks = []
for i, text in enumerate(text_chunks):
doc = Document(text=text, id_=f"doc_id_{i}")
doc_chunks.append(doc)
# insert
for doc_chunk in doc_chunks:
index.insert(doc_chunk)删除
你可以指定 document\_id,从大多数索引数据结构中“删除”一个 Document(注意:树索引目前不支持删除)。该文档对应的所有节点都会被删除。
index.delete_ref_doc("doc_id_0", delete_from_docstore=True)delete_from_docstore 默认为 False,这是考虑到你可能在共用同一 docstore 的多个索引之间共享节点。不过当它设为 False 时,这些节点在查询时不会被用到,因为它们会从索引的 index_struct(负责记录哪些节点可用于查询)中移除。
更新
如果某个 Document 已存在于索引中,你可以用相同的 doc id_ 来“更新”它(例如文档内容发生了变化)。
# NOTE: the document has a `doc_id` specified
doc_chunks[0].text = "Brand new document text"
index.update_ref_doc(doc_chunks[0])刷新
如果你在加载数据时为每个文档设了 doc id_,就可以让索引自动刷新。
refresh() 只会更新 doc id_ 相同、但文本内容不同的文档。凡是不在索引中的文档也会被一并插入。
refresh() 还会返回一个布尔列表,指示输入中的哪些文档在索引里被刷新了。
# modify first document, with the same doc_id
doc_chunks[0] = Document(text="Super new document text", id_="doc_id_0")
# add a new document
doc_chunks.append(
Document(
text="This isn't in the index yet, but it will be soon!",
id_="doc_id_3",
)
)
# refresh the index
refreshed_docs = index.refresh_ref_docs(doc_chunks)
# refreshed_docs[0] and refreshed_docs[-1] should be true同样,我们传入了若干额外关键字参数,以确保文档从 docstore 中删除。这当然是可选的。
如果你 print() 一下 refresh() 的输出,就能看到哪些输入文档被刷新了:
print(refreshed_docs)
# > [True, False, False, True]当你从一个持续更新的目录读取数据时,这一点最有用。
要在使用 SimpleDirectoryReader 时自动设置 doc id_,可以打开 filename_as_id 开关。更多内容见定制 Document。
文档追踪
任何使用 docstore 的索引(也就是除多数向量库集成之外的所有索引),都可以查看你已经插入 docstore 的文档。
print(index.ref_doc_info)
"""
> {'doc_id_1': RefDocInfo(node_ids=['071a66a8-3c47-49ad-84fa-7010c6277479'], metadata={}),
'doc_id_2': RefDocInfo(node_ids=['9563e84b-f934-41c3-acfd-22e88492c869'], metadata={}),
'doc_id_0': RefDocInfo(node_ids=['b53e6c2f-16f7-4024-af4c-42890e945f36'], metadata={}),
'doc_id_3': RefDocInfo(node_ids=['6bedb29f-15db-4c7c-9885-7490e10aa33f'], metadata={})}
"""输出里的每一项都以被摄取的 doc id_ 作为 key,其对应的值是每个文档被拆分出的 node_ids。
最后,每个输入文档原始的 metadata 字典也会被追踪。metadata 属性的更多内容见定制 Document。