llama_index 如何保存节点Map并在递归检索中检索它们?

oknrviil  于 5个月前  发布在  其他
关注(0)|答案(5)|浏览(55)

问题验证

  • 我已经在文档和Discord上寻找答案。

问题

嘿,
我正在尝试在网页上创建RAG应用程序。我正在使用UnstructuredElementNodeParser解析我的文档。
由于调用base_nodes, node_mappings = node_parser.get_base_nodes_and_mappings(raw_nodes),我得到了基本节点和节点Map。
我正在使用向量索引来存储基本节点,但是如何存储节点Map?我应该如何从索引中检索它们并将它们传递给RecursiveRetriever以进行检索?

e3bfsja2

e3bfsja21#

你好@harshsavasil!我是一个机器人,可以帮助你解决任何问题或疑问。让我们一起看看如何解决这个问题。
要持久化节点Map并从索引中检索它们以在 RecursiveRetriever 中使用,您可以使用 SimpleObjectNodeMapping 类提供的 persistfrom_persist_dir 方法。

持久化节点Map

要持久化节点Map,请在您的 SimpleObjectNodeMapping 示例上调用 persist 方法:

node_mapping.persist(persist_dir="your_persist_directory")

从索引中检索节点Map

要从索引中检索节点Map,请使用 from_persist_dir 类方法:

retrieved_node_mapping = SimpleObjectNodeMapping.from_persist_dir(persist_dir="your_persist_directory")

RecursiveRetriever 中使用

一旦您检索到了 SimpleObjectNodeMapping ,就可以使用它来创建一个 ObjectRetriever ,然后将其用于 RecursiveRetriever :

object_retriever = retrieved_node_mapping.as_retriever()

示例代码

# Persisting the node mappings
node_mapping.persist(persist_dir="your_persist_directory")

# Retrieving the node mappings
retrieved_node_mapping = SimpleObjectNodeMapping.from_persist_dir(persist_dir="your_persist_directory")

# Using in RecursiveRetriever
object_retriever = retrieved_node_mapping.as_retriever()

这将允许您持久化和检索节点Map,并在 RecursiveRetriever 中使用它们。 SimpleObjectNodeMapping 类处理索引和对象节点Map的持久性,确保在需要时可以重建具有相同Map的索引 1(https://github.com/run-llama/llama_index/blob/main/llama-index-core/llama_index/core/objects/base.py)2(https://github.com/run-llama/llama_index/blob/main/llama-index-legacy/llama_index/legacy/objects/base.py)3(https://github.com/run-llama/llama_index/blob/main/llama-index-core/llama_index/core/objects/base_node_mapping.py)4(https://github.com/run-llama/llama_index/blob/main/llama-index-legacy/llama_index/legacy/objects/base_node_mapping.py)。

  • 要继续与 Dosu 交谈,请提及 @dosu。*
9ceoxa92

9ceoxa922#

我们能否将这些节点Map存储在数据库中,以便更好地存储和高效检索?

ne5o7dgx

ne5o7dgx3#

是的,你可以将节点Map存储在数据库中以获得更好的存储和高效的检索。你可以通过将节点及其关系序列化为适合数据库存储的格式(如JSON),然后使用数据库客户端将这些记录插入到你的数据库中来实现这一点。
以下是如何将节点序列化并存储在SQLite数据库中的示例:

import sqlite3
import json
from typing import List
from llama_index.core.schema import BaseNode, TextNode
from llama_index.core.node_parser.relational.unstructured_element import UnstructuredElementNodeParser

# Initialize the parser
parser = UnstructuredElementNodeParser()

# Example function to store nodes in a SQLite database
def store_nodes_in_db(nodes: List[BaseNode], db_path: str):
    # Connect to the SQLite database (or create it if it doesn't exist)
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    # Create a table for storing nodes if it doesn't exist
    cursor.execute('''
CREATE TABLE IF NOT EXISTS nodes (
id TEXT PRIMARY KEY,
type TEXT,
content TEXT,
relationships TEXT,
metadata TEXT
)
''')

    # Insert nodes into the database
    for node in nodes:
        node_data = {
            'id': node.id,
            'type': node.type,
            'content': node.get_content(),
            'relationships': json.dumps(node.relationships),
            'metadata': json.dumps(node.metadata)
        }
        cursor.execute('''
INSERT OR REPLACE INTO nodes (id, type, content, relationships, metadata)
VALUES (:id, :type, :content, :relationships, :metadata)
''', node_data)

    # Commit the transaction and close the connection
    conn.commit()
    conn.close()

# Example usage
text_node = TextNode(id="example_id", content="Example content")
nodes = parser.get_nodes_from_node(text_node)
store_nodes_in_db(nodes, 'nodes.db')

在这个例子中:

  1. 我们初始化 UnstructuredElementNodeParser
  2. 我们定义一个函数 store_nodes_in_db ,它接受一个节点列表和一个数据库路径作为参数。
  3. 该函数连接到SQLite数据库,并在不存在的情况下为存储节点创建一个表。
  4. 然后,它将每个节点的数据序列化为JSON格式并插入到数据库中。
  5. 最后,我们使用一个示例 TextNode 来演示如何使用这个函数。
    这种方法可以适应其他类型的数据库(例如,PostgreSQL,MongoDB)通过使用适当的数据库客户端和查询语法 1(https://github.com/run-llama/llama_index/blob/main/llama-index-core/llama_index/core/node_parser/relational/unstructured_element.py) 。
  • 要继续与 Dosu 交谈,请提及 @dosu。*
pbossiut

pbossiut4#

@dosu 我如何从数据库中检索这些节点以供RAG使用?

wrrgggsh

wrrgggsh5#

从数据库中检索节点以进行检索增强生成(RAG),您可以创建一个自定义检索器,该检索器从数据库中获取节点并将它们转换为 NodeWithScore 对象。以下是使用SQLite实现此目标的示例:

逐步指南

  1. 连接到SQLite数据库:使用类似于 sqlite3 的库连接到您的SQLite数据库并获取所需的数据。
  2. 创建自定义检索器:扩展 BaseRetriever 类以创建从SQLite数据库获取数据的自定义检索器。
  3. 将数据转换为节点:将获取的数据转换为 NodeWithScore 对象,然后可以使用 RecursiveRetriever

示例实现

import sqlite3
from typing import List
from llama_index.core.base.base_retriever import BaseRetriever
from llama_index.core.schema import NodeWithScore, TextNode
from llama_index.core.indices.query.schema import QueryBundle

class SQLiteRetriever(BaseRetriever):
    """Retriever that fetches data from an SQLite database."""

    def __init__(self, db_path: str, top_k: int = 10) -> None:
        """Initialize with database path and top_k results."""
        self.db_path = db_path
        self.top_k = top_k

    def _retrieve(self, query_bundle: QueryBundle) -> List[NodeWithScore]:
        """Retrieve nodes from the SQLite database."""
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()

        # Example query to fetch data based on some criteria
        cursor.execute("SELECT content, score FROM nodes WHERE content LIKE ?", ('%' + query_bundle.query_str + '%',))
        results = cursor.fetchall()
        conn.close()

        # Convert results to NodeWithScore objects
        result_nodes = [
            NodeWithScore(node=TextNode(text=row[0]), score=row[1])
            for row in results[:self.top_k]
        ]
        return result_nodes

# Example usage
db_path = 'nodes.db'
retriever = SQLiteRetriever(db_path=db_path, top_k=10)
query_bundle = QueryBundle(query_str="example query")
nodes = retriever._retrieve(query_bundle)

RecursiveRetriever 集成

要将其与 RecursiveRetriever 集成,您将创建一个检索器字典并将其传递给 RecursiveRetriever :

from llama_index.core.retrievers.recursive_retriever import RecursiveRetriever

retriever_dict = {
    'root': retriever  # Add your SQLiteRetriever instance here
}

recursive_retriever = RecursiveRetriever(root_id='root', retriever_dict=retriever_dict)
nodes = recursive_retriever.retrieve(query_bundle)

此设置允许 RecursiveRetriever 使用 SQLiteRetriever 从SQLite数据库中获取节点并递归地探索从节点到其他检索器或查询引擎的链接 1(https://github.com/run-llama/llama_index/blob/main/llama-index-packs/llama-index-packs-ragatouille-retriever/llama_index/packs/ragatouille_retriever/base.py)2(https://github.com/run-llama/llama_index/blob/main/llama-index-core/llama_index/core/retrievers/recursive_retriever.py)3(https://github.com/run-llama/llama_index/blob/main/llama-index-core/llama_index/core/indices/struct_store/sql_retriever.py)。

  • 要继续与 Dosu 交谈,请提及 @dosu。*

相关问题