前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >基于招投标货物知识图谱全流程构建指南-数据存储

基于招投标货物知识图谱全流程构建指南-数据存储

原创
作者头像
fanstuck
发布2025-01-22 17:36:39
发布2025-01-22 17:36:39
5231
举报
文章被收录于专栏:知识图谱从零开始构建实战

前言

本文承接上篇文章:基于招投标货物知识图谱全流程构建指南(一),在上篇文章主要讲述了该系统的两层流程:

的数据获取层、数据处理层。如果你一路跟随博主的步伐,从学习知识图谱的基本概念和理论,到实际代码实现,再到结合具体业务领域构建高阶应用,想必已经深刻体会到我们从零出发,一步步跨越技术难关,最终搭建起属于自己的知识图谱技术体系的过程。通过前期的积累与打磨,相信这一阶段的挑战会更加从容。博主始终坚持基于真实业务场景的落地成果进行总结,将复杂的技术原理以通俗易懂的方式呈现给大家,并辅以科学严谨的技术理论支撑,力求每篇文章都成为高质量的技术干货。

如果你对知识图谱技术和项目实战感兴趣,这篇文章将带你深入探索招投标领域的货物知识图谱全流程构建,希望能够为你的技术进阶之路带来切实的帮助,也欢迎小伙伴们多多支持博主的分享与创作!

数据处理层:大语言模型的数据提取与存储

数据存储分为两个主要部分:MySQL 数据库Neo4j 图数据库。每种数据库的存储方式各有其特点和优势,具体应用到不同的数据需求和业务场景中。

MySQL 数据库

公告数据的获取和处理只是第一步,真正的价值在于将这些数据高效存储并能支持后续的查询和分析。为了实现这一目标,我们将数据分为两部分进行存储:MySQL 数据库Neo4j 图数据库

数据存储需求分析
  • MySQL 数据库
    • 适合存储结构化的表格数据,例如每条招标公告的标题、发布日期、招标金额等。
    • 提供了高效的检索能力,支持基于 SQL 的复杂查询和统计分析。
  • Neo4j 图数据库
    • 适合存储复杂关系型数据,例如项目与投标人之间的关系、投标金额等。
    • 提供了基于图形的查询能力,能够快速解析节点与节点之间的多层关系。

在这一部分,我们将介绍如何将数据分别存储到 MySQL 和 Neo4j 中,并实现两种存储方式的互补。

数据存储到 MySQL

设计思路

MySQL 是传统的关系型数据库,适合存储结构化数据。我们为每条招投标公告设计一个表格,表格的列包括:

  • 标题:招标公告的标题。
  • 链接:公告详情页的 URL。
  • 发布日期:公告发布的时间。
  • 行业类型:项目所属行业(如市政工程、建筑工程)。
  • 辖区:项目所在的地理区域。
  • 信息类型:公告类型(如采购公告、中标公告)。
  • 开标类型:标识项目是公开招标还是邀请招标。

通过 Pandas 的 to_sql 方法,可以轻松地将这些数据存储到 MySQL 数据库中。我们使用了 DBUtilsSQLAlchemy 来管理数据库连接和操作。

代码语言:python
代码运行次数:0
复制
# 创建 SQLAlchemy 引擎
def _create_engine(self):
    try:
        user = quote_plus(self.db_config['user'])
        password = quote_plus(self.db_config['password'])
        engine = create_engine(
            f"mysql+pymysql://{user}:{password}@{self.db_config['host']}:{self.db_config['port']}/{self.db_config['db']}"
        )
        return engine
    except Exception as e:
        print(f"Failed to create SQLAlchemy engine: {e}")
        return None
  • 通过 SQLAlchemy 创建一个数据库引擎,用于与 MySQL 数据库交互。
  • 使用 quote_plus 处理用户名和密码中的特殊字符,确保连接字符串的格式正确。 然后,通过以下方法将 Pandas 的 DataFrame 数据存入数据库:
代码语言:python
代码运行次数:0
复制
# 将 DataFrame 导入到数据库
def insert_dataframe(self, df, table_name, if_exists="replace", index=False):
    try:
        engine = self._create_engine()
        if engine:
            df.to_sql(name=table_name, con=engine, if_exists=if_exists, index=index)
            print(f"DataFrame has been successfully imported into the '{table_name}' table.")
        else:
            print("Failed to create SQLAlchemy engine for DataFrame insertion.")
    except Exception as e:
        print(f"Error while inserting DataFrame: {e}")

功能解读:

  • to_sql 方法直接将 DataFrame 数据存储到 MySQL 数据库中。
  • 参数 if_exists="replace" 表示如果表已经存在,则替换;index=False 表示不保存 DataFrame 的索引列。
  • 通过异常处理,确保操作的安全性。

假设我们从招投标公告中提取了一部分数据,并将其存储为 Pandas 的 DataFrame,数据示例如下:

标题

链接

发布日期

行业类型

辖区

信息类型

开标类型

项目A招标公告

2025-01-01

建筑工程

红谷滩区

招标公告

公开招标

我们可以通过以下代码将其存入数据库:

代码语言:python
代码运行次数:0
复制
df = pd.DataFrame([
    {
        "标题": "项目A招标公告",
        "链接": "http://example.com/a",
        "发布日期": "2025-01-01",
        "行业类型": "建筑工程",
        "辖区": "红谷滩区",
        "信息类型": "招标公告",
        "开标类型": "公开招标"
    }
])

db_utils = DBUtilsDemo(url="localhost", user="root", password="password", database="bidding")
db_utils.insert_dataframe(df, table_name="bidding_announcements")

执行完成后,数据会成功存储到 bidding_announcements 表中。

数据存储到 Neo4j 图数据库

设计思路

Neo4j 是一种图数据库,特别适合存储复杂关系数据。在本项目中,我们将招投标公告的数据存储为以下结构:

  • 节点(Node):

Project(项目):表示每个招投标项目。

Bidder(投标人):表示每个投标公司。

  • 关系(Relationship):

BID_ON:表示投标人对项目的投标行为,包含投标金额等属性。

我们通过 Neo4j 的 Python 驱动实现数据存储:

代码语言:python
代码运行次数:0
复制
# 创建项目节点
def create_project_node(self, project_id, project_name, release_date):
    query = (
        "MERGE (p:Project {id: $project_id}) "
        "SET p.name = $project_name, p.release_date = $release_date"
    )
    with self._get_session() as session:
        session.run(query, project_id=project_id, project_name=project_name, release_date=release_date)

# 创建投标人节点
def create_bidder_node(self, bidder_id, bidder_name):
    query = (
        "MERGE (b:Bidder {id: $bidder_id}) "
        "SET b.name = $bidder_name"
    )
    with self._get_session() as session:
        session.run(query, bidder_id=bidder_id, bidder_name=bidder_name)

# 创建投标关系
def create_bid_relationship(self, project_id, bidder_id, bid_amount):
    query = (
        "MATCH (p:Project {id: $project_id}), (b:Bidder {id: $bidder_id}) "
        "MERGE (b)-[:BID_ON {amount: $bid_amount}]->(p)"
    )
    with self._get_session() as session:
        session.run(query, project_id=project_id, bidder_id=bidder_id, bid_amount=bid_amount)

通过结合两种数据库的优势,我们能够高效地管理和分析招投标数据,为后续的知识图谱展示和决策支持提供了强大的技术保障。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 数据处理层:大语言模型的数据提取与存储
    • MySQL 数据库
  • 数据存储到 MySQL
    • 设计思路
  • 数据存储到 Neo4j 图数据库
    • 设计思路
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档