如何用 PolarDB 整合age算法插件, 实现图式搜索加速 - 刑侦、社交、风控、族谱、推荐等业务图谱类关系数据搜索

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介: 背景PolarDB 的云原生存算分离架构, 具备低廉的数据存储、高效扩展弹性、高速多机并行计算能力、高速数据搜索和处理; PolarDB与计算算法结合, 将实现双剑合璧, 推动业务数据的价值产出, 将数据变成生产力.本文将介绍PolarDB结合图式算法, 实现高效率的刑侦、社交、风控、族谱、推荐等业...

背景

PolarDB 的云原生存算分离架构, 具备低廉的数据存储、高效扩展弹性、高速多机并行计算能力、高速数据搜索和处理; PolarDB与计算算法结合, 将实现双剑合璧, 推动业务数据的价值产出, 将数据变成生产力.

本文将介绍PolarDB结合图式算法, 实现高效率的刑侦、社交、风控、族谱、推荐等业务图谱类关系数据搜索.

age是什么

https://age.apache.org/age-manual/master/intro/overview.html

Apache AGE is a PostgreSQL extension that provides graph database functionality. AGE is an acronym for A Graph Extension, and is inspired by Bitnine’s fork of PostgreSQL 10, AgensGraph, which is a multi-model database. The goal of the project is to create single storage that can handle both relational and graph model data so that users can use standard ANSI SQL along with openCypher, the Graph query language.

简单来说就是一个支持图式数据和搜索的多模数据库插件.

将age整合到PolarDB

https://age.apache.org/age-manual/master/intro/setup.html

https://age.apache.org/download

https://github.com/apache/age

https://github.com/apache/age/tree/release/1.1.0

  1. 下载最新分支并安装

git clone --branch release/1.1.0 --depth 1 https://github.com/apache/age  
  
cd age  
  
git branch  
* release/1.1.0  
  
which pg_config  
~/tmp_basedir_polardb_pg_1100_bld/bin/pg_config  
  1. 修复代码错误, 原因是RTE解析未兼容.

USE_PGXS=1 PG_CONFIG=~/tmp_basedir_polardb_pg_1100_bld/bin/pg_config make  
  
报错如下:  
src/backend/parser/cypher_analyze.c: In function ‘convert_cypher_walker’:  
src/backend/parser/cypher_analyze.c:178:17: error: ‘QTW_EXAMINE_RTES’ undeclared (first use in this function); did you mean ‘QTW_EXAMINE_RTES_AFTER’?  
  178 |         flags = QTW_EXAMINE_RTES | QTW_IGNORE_RT_SUBQUERIES |  
      |                 ^~~~~~~~~~~~~~~~  
      |                 QTW_EXAMINE_RTES_AFTER  
src/backend/parser/cypher_analyze.c:178:17: note: each undeclared identifier is reported only once for each function it appears in  
make: *** [<builtin>: src/backend/parser/cypher_analyze.o] Error 1  

原因如下:

https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=18c0da88a5d9da566c3bfac444366b73bd0b57da

Split QTW_EXAMINE_RTES flag into QTW_EXAMINE_RTES_BEFORE/_AFTER.  
  
This change allows callers of query_tree_walker() to choose whether  
to visit an RTE before or after visiting the contents of the RTE  
(i.e., prefix or postfix tree order).  All existing users of  
QTW_EXAMINE_RTES want the QTW_EXAMINE_RTES_BEFORE behavior, but  
an upcoming patch will want QTW_EXAMINE_RTES_AFTER, and it seems  
like a potentially useful change on its own.  
  
Andreas Karlsson (extracted from CTE inlining patch)  
  
Discussion: https://postgr.es/m/8810.1542402910@sss.pgh.pa.us  

https://git.postgresql.org/gitweb/?p=postgresql.git;a=blobdiff;f=src/include/nodes/nodeFuncs.h;h=a9f76bbb330a3a271363be317fd8caea3e09fe7d;hp=7739600db26e55628778d93d1e2a3833d90954d9;hb=18c0da88a5d9da566c3bfac444366b73bd0b57da;hpb=ff750ce2d82979e9588c629955e161a9379b05f3

-#define QTW_EXAMINE_RTES           0x10    /* examine RTEs */  
-#define QTW_DONT_COPY_QUERY            0x20    /* do not copy top Query */  
+#define QTW_EXAMINE_RTES_BEFORE        0x10    /* examine RTE nodes before their  
+                                            * contents */  
+#define QTW_EXAMINE_RTES_AFTER     0x20    /* examine RTE nodes after their  
+                                            * contents */  
+#define QTW_DONT_COPY_QUERY            0x40    /* do not copy top Query */  

修复如下:

cd age  
vi src/backend/parser/cypher_analyze.c  
  
  
        /*  
         * QTW_EXAMINE_RTES  
         *     We convert RTE_FUNCTION (cypher()) to RTE_SUBQUERY (SELECT)  
         *     in-place.  
         *  
         * QTW_IGNORE_RT_SUBQUERIES  
         *     After the conversion, we don't need to traverse the resulting  
         *     RTE_SUBQUERY. However, we need to traverse other RTE_SUBQUERYs.  
         *     This is done manually by the RTE_SUBQUERY case above.  
         *  
         * QTW_IGNORE_JOINALIASES  
         *     We are not interested in this.  
         */  
        // flags = QTW_EXAMINE_RTES | QTW_IGNORE_RT_SUBQUERIES |  
        flags = QTW_EXAMINE_RTES_BEFORE | QTW_IGNORE_RT_SUBQUERIES |  
                QTW_IGNORE_JOINALIASES;   

以上参考12分支:

https://github.com/apache/age/blob/release/PG12/1.1.0/src/backend/parser/cypher_analyze.c

        /*  
         * QTW_EXAMINE_RTES  
         *     We convert RTE_FUNCTION (cypher()) to RTE_SUBQUERY (SELECT)  
         *     in-place.  
         *  
         * QTW_IGNORE_RT_SUBQUERIES  
         *     After the conversion, we don't need to traverse the resulting  
         *     RTE_SUBQUERY. However, we need to traverse other RTE_SUBQUERYs.  
         *     This is done manually by the RTE_SUBQUERY case above.  
         *  
         * QTW_IGNORE_JOINALIASES  
         *     We are not interested in this.  
         */  
        flags = QTW_EXAMINE_RTES_BEFORE | QTW_IGNORE_RT_SUBQUERIES |  
                QTW_IGNORE_JOINALIASES;  

修复后继续安装即可

USE_PGXS=1 PG_CONFIG=~/tmp_basedir_polardb_pg_1100_bld/bin/pg_config make  
USE_PGXS=1 PG_CONFIG=~/tmp_basedir_polardb_pg_1100_bld/bin/pg_config make install  
  1. 使用age

postgres=# LOAD 'age';  
LOAD  
postgres=# SET search_path = ag_catalog, "$user", public;  
SET  
  
-- 以上也可以根据需要配置到数据库参数postgresql.conf 中, 即自动加载age:   
-- #shared_preload_libraries = ''  # (change requires restart)  
-- #local_preload_libraries = ''  
-- #session_preload_libraries = ''  
-- #search_path = '"$user", public'        # schema names  
  
postgres=# create extension age ;  
CREATE EXTENSION  
  1. 一些图式查询语法例子

postgres=# SELECT * FROM ag_catalog.create_graph('graph_name');  
NOTICE:  graph "graph_name" has been created  
 create_graph   
--------------  
   
(1 row)  
  
postgres=# SELECT *  
postgres-# FROM cypher('graph_name', $$  
postgres$#     RETURN 1  
postgres$# $$) AS (int_result agtype);  
 int_result   
------------  
 1  
(1 row)  
  
postgres=# SELECT *  
postgres-# FROM cypher('graph_name', $$  
postgres$#     WITH [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as lst  
postgres$#     RETURN lst  
postgres$# $$) AS (lst agtype);  
                lst                   
------------------------------------  
 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  
(1 row)  
  
postgres=# SELECT *  
postgres-# FROM cypher('graph_name', $$  
postgres$#     WITH {listKey: [{inner: 'Map1'}, {inner: 'Map2'}], mapKey: {i: 0}} as m  
postgres$#     RETURN m.listKey[0]  
postgres$# $$) AS (m agtype);  
         m           
-------------------  
 {"inner": "Map1"}  
(1 row)  
  
postgres=# SELECT *  
postgres-# FROM cypher('graph_name', $$  
postgres$# WITH {id: 0, label: "label_name", properties: {i: 0}}::vertex as v  
postgres$# RETURN v  
postgres$# $$) AS (v agtype);  
                                v                                   
------------------------------------------------------------------  
 {"id": 0, "label": "label_name", "properties": {"i": 0}}::vertex  
(1 row)  
  
postgres=# SELECT *  
postgres-# FROM cypher('graph_name', $$  
postgres$# WITH {id: 2, start_id: 0, end_id: 1, label: "label_name", properties: {i: 0}}::edge as e  
postgres$# RETURN e  
postgres$# $$) AS (e agtype);  
                                             e                                                
--------------------------------------------------------------------------------------------  
 {"id": 2, "label": "label_name", "end_id": 1, "start_id": 0, "properties": {"i": 0}}::edge  
(1 row)  
  
postgres=# SELECT *  
postgres-# FROM cypher('graph_name', $$  
postgres$# WITH [{id: 0, label: "label_name_1", properties: {i: 0}}::vertex,  
postgres$#             {id: 2, start_id: 0, end_id: 1, label: "edge_label", properties: {i: 0}}::edge,  
postgres$#            {id: 1, label: "label_name_2", properties: {}}::vertex  
postgres$#            ]::path as p  
postgres$# RETURN p  
postgres$# $$) AS (p agtype);  
                                                                                                                  p                                                                                         
                              
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------  
----------------------------  
 [{"id": 0, "label": "label_name_1", "properties": {"i": 0}}::vertex, {"id": 2, "label": "edge_label", "end_id": 1, "start_id": 0, "properties": {"i": 0}}::edge, {"id": 1, "label": "label_name_2", "prop  
erties": {}}::vertex]::path  
(1 row)  
  
postgres=# WITH graph_query as (  
postgres(#     SELECT *  
postgres(#         FROM cypher('graph_name', $$  
postgres$#         MATCH (n)  
postgres$#         RETURN n.name, n.age  
postgres$#     $$) as (name agtype, age agtype)  
postgres(# )  
postgres-# SELECT * FROM graph_query;  
 name | age   
------+-----  
(0 rows)  
  
postgres=# SELECT *  
postgres-# FROM cypher('graph_name', $$  
postgres$# MATCH (n)  
postgres$# RETURN n.name  
postgres$# ORDER BY n.name  
postgres$# SKIP 3  
postgres$# $$) as (names agtype);  
 names   
-------  
(0 rows)  

更多用法请参考age文档:

https://age.apache.org/age-manual/master/intro/overview.html

参考

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
19天前
|
存储 人工智能 Cloud Native
云栖重磅|从数据到智能:Data+AI驱动的云原生数据库
在9月20日2024云栖大会上,阿里云智能集团副总裁,数据库产品事业部负责人,ACM、CCF、IEEE会士(Fellow)李飞飞发表《从数据到智能:Data+AI驱动的云原生数据库》主题演讲。他表示,数据是生成式AI的核心资产,大模型时代的数据管理系统需具备多模处理和实时分析能力。阿里云瑶池将数据+AI全面融合,构建一站式多模数据管理平台,以数据驱动决策与创新,为用户提供像“搭积木”一样易用、好用、高可用的使用体验。
云栖重磅|从数据到智能:Data+AI驱动的云原生数据库
|
20天前
|
存储 编解码 负载均衡
数据分片算法
【10月更文挑战第25天】不同的数据分片算法适用于不同的应用场景和数据特点,在实际应用中,需要根据具体的业务需求、数据分布情况、系统性能要求等因素综合考虑,选择合适的数据分片算法,以实现数据的高效存储、查询和处理。
|
20天前
|
存储 缓存 算法
分布式缓存有哪些常用的数据分片算法?
【10月更文挑战第25天】在实际应用中,需要根据具体的业务需求、数据特征以及系统的可扩展性要求等因素综合考虑,选择合适的数据分片算法,以实现分布式缓存的高效运行和数据的合理分布。
|
1月前
|
机器学习/深度学习 人工智能 算法
"拥抱AI规模化浪潮:从数据到算法,解锁未来无限可能,你准备好迎接这场技术革命了吗?"
【10月更文挑战第14天】本文探讨了AI规模化的重要性和挑战,涵盖数据、算法、算力和应用场景等方面。通过使用Python和TensorFlow的示例代码,展示了如何训练并应用一个基本的AI模型进行图像分类,强调了AI规模化在各行业的广泛应用前景。
31 5
|
1月前
|
存储 算法 Java
Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性
Java Set因其“无重复”特性在集合框架中独树一帜。本文解析了Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定数据结构和算法确保元素唯一性,并提供了最佳实践建议,包括选择合适的Set实现类和正确实现自定义对象的hashCode()与equals()方法。
33 4
|
1月前
|
存储 人工智能 Cloud Native
云栖重磅|从数据到智能:Data+AI驱动的云原生数据库
阿里云瑶池在2024云栖大会上重磅发布由Data+AI驱动的多模数据管理平台DMS:OneMeta+OneOps,通过统一、开放、多模的元数据服务实现跨环境、跨引擎、跨实例的统一治理,可支持高达40+种数据源,实现自建、他云数据源的无缝对接,助力业务决策效率提升10倍。
|
24天前
|
存储 JSON 算法
TDengine 检测数据最佳压缩算法工具,助你一键找出最优压缩方案
在使用 TDengine 存储时序数据时,压缩数据以节省磁盘空间是至关重要的。TDengine 支持用户根据自身数据特性灵活指定压缩算法,从而实现更高效的存储。然而,如何选择最合适的压缩算法,才能最大限度地降低存储开销?为了解决这一问题,我们特别推出了一个实用工具,帮助用户快速判断并选择最适合其数据特征的压缩算法。
30 0
|
1月前
|
人工智能 算法 前端开发
无界批发零售定义及无界AI算法,打破传统壁垒,累积数据流量
“无界批发与零售”是一种结合了批发与零售的商业模式,通过后端逻辑、数据库设计和前端用户界面实现。该模式支持用户注册、登录、商品管理、订单处理、批发与零售功能,并根据用户行为计算信用等级,确保交易安全与高效。
|
1月前
|
前端开发 算法 JavaScript
无界SaaS模式深度解析:算力算法、链接力、数据确权制度
私域电商的无界SaaS模式涉及后端开发、前端开发、数据库设计、API接口、区块链技术、支付和身份验证系统等多个技术领域。本文通过简化框架和示例代码,指导如何将核心功能转化为技术实现,涵盖用户管理、企业店铺管理、数据流量管理等关键环节。
|
1月前
|
机器学习/深度学习 算法 数据处理
EM算法对人脸数据降维(机器学习作业06)
本文介绍了使用EM算法对人脸数据进行降维的机器学习作业。首先通过加载ORL人脸数据库,然后分别应用SVD_PCA、MLE_PCA及EM_PCA三种方法实现数据降维,并输出降维后的数据形状。此作业展示了不同PCA变种在人脸数据处理中的应用效果。
34 0