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

简介: 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  

2、修复代码错误, 原因是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  

3、使用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  

4、一些图式查询语法例子

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数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
10月前
|
算法 数据可视化 测试技术
HNSW算法实战:用分层图索引替换k-NN暴力搜索
HNSW是一种高效向量检索算法,通过分层图结构实现近似最近邻的对数时间搜索,显著降低查询延迟。相比暴力搜索,它在保持高召回率的同时,将性能提升数十倍,广泛应用于大规模RAG系统。
807 10
HNSW算法实战:用分层图索引替换k-NN暴力搜索
|
11月前
|
机器学习/深度学习 算法 安全
【无人机三维路径规划】基于非支配排序的鲸鱼优化算法NSWOA与多目标螳螂搜索算法MOMSA求解无人机三维路径规划研究(Matlab代码实现)
【无人机三维路径规划】基于非支配排序的鲸鱼优化算法NSWOA与多目标螳螂搜索算法MOMSA求解无人机三维路径规划研究(Matlab代码实现)
435 5
|
11月前
|
机器学习/深度学习 算法 安全
【无人机三维路径规划】多目标螳螂搜索算法MOMSA与非支配排序的鲸鱼优化算法NSWOA求解无人机三维路径规划研究(Matlab代码实现)
【无人机三维路径规划】多目标螳螂搜索算法MOMSA与非支配排序的鲸鱼优化算法NSWOA求解无人机三维路径规划研究(Matlab代码实现)
349 0
|
11月前
|
存储 算法 数据可视化
基于禁忌搜索算法的TSP问题最优路径搜索matlab仿真
本程序基于禁忌搜索算法解决旅行商问题(TSP),旨在寻找访问多个城市的最短路径。使用 MATLAB 2022A 编写,包含城市坐标生成、路径优化及结果可视化功能。通过禁忌列表、禁忌长度与藐视准则等机制,提升搜索效率与解的质量,适用于物流配送、路径规划等场景。
|
机器学习/深度学习 并行计算 算法
MATLAB实现利用禁忌搜索算法解决基站选址问题
MATLAB实现利用禁忌搜索算法解决基站选址问题
374 0
|
存储 搜索推荐 算法
加密算法、排序算法、字符串处理及搜索算法详解
本文涵盖四大类核心技术知识。加密算法部分介绍了对称加密(如 AES)、非对称加密(如 RSA)、哈希摘要(如 SHA-2)、签名算法的特点及密码存储方案(加盐、BCrypt 等)。 排序算法部分分类讲解了比较排序(冒泡、选择、插入、归并、快排、堆排序)和非比较排序(计数、桶、基数排序)的时间复杂度、适用场景及实现思路,强调混合排序的工业应用。 字符串处理部分包括字符串反转的双指针法,及项目中用正则进行表单校验、网页爬取、日志处理的实例。 搜索算法部分详解了二分查找的实现(双指针与中间索引计算)和回溯算法的概念(递归 + 剪枝),以 N 皇后问题为例说明回溯应用。内容全面覆盖算法原理与实践
350 0
|
存储 关系型数据库 MySQL
亿级数据秒级响应:PolarDB MySQL HTAP实时分析方案设计与压测报告
PolarDB MySQL HTAP方案实现亿级数据秒级响应,支持高并发事务与实时分析。通过行列混存、智能路由与资源隔离,满足电商、金融等场景的实时报表、决策需求,降低架构复杂度与运维成本。
771 6
|
机器学习/深度学习 算法 数据可视化
基于Qlearning强化学习的机器人迷宫路线搜索算法matlab仿真
本内容展示了基于Q-learning算法的机器人迷宫路径搜索仿真及其实现过程。通过Matlab2022a进行仿真,结果以图形形式呈现,无水印(附图1-4)。算法理论部分介绍了Q-learning的核心概念,包括智能体、环境、状态、动作和奖励,以及Q表的构建与更新方法。具体实现中,将迷宫抽象为二维网格世界,定义起点和终点,利用Q-learning训练机器人找到最优路径。核心程序代码实现了多轮训练、累计奖励值与Q值的可视化,并展示了机器人从起点到终点的路径规划过程。
729 0
|
人工智能 自然语言处理 算法
阿里云 AI 搜索开放平台:从算法到业务——AI 搜索驱动企业智能化升级
本文介绍了阿里云 AI 搜索开放平台的技术的特点及其在各行业的应用。
1508 3

热门文章

最新文章

相关产品

  • 云原生数据库 PolarDB