数据与AI
在 Snowflake 内直接跑 Neo4j…
当数据已在 Snowflake 表中、想通过 Neo4j Graph Analytics Snowflake Native App 用 SQL CALL 就地运行图算法时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
在 Snowflake 内直接跑 Neo特定
解决思路
- 先探查源数据:用 SELECT GET_DDL('TABLE', 'MY_DATABASE.MY_SCHEMA.MY_TABLE') 查看表定义,或查询 MY_DATABASE.INFORMATION_SCHEMA.COLUMNS 获取 COLUMN_NAME、DATA_TYPE;据此判断哪些表是节点、哪些表表示关系(边)。
- 创建投影视图(最关键的一步):用 CREATE OR REPLACE VIEW MY_DATABASE.MY_SCHEMA.MY_NODES_VW AS SELECT ... FROM ... 把表重塑为节点/关系格式;Snowflake 视图默认继承源列类型,所以每个属性列都必须显式 CAST,绝不能直接 SELECT col。
- 节点视图规则:把主键暴露为 NODEID,类型必须是 BIGINT 或 STRING,且必须同时别名并显式转换,如 SOURCE_COL::BIGINT AS NODEID 或 SOURCE_COL::STRING AS NODEID;节点属性只允许 BIGINT、DOUBLE、ARRAY、VECTOR(FLOAT, n);复合键用 '++' 拼接各部分;命名用 <table>_NODES_VW。
- 按源类型→视图类型的转换规则处理列(保留原列名,除非重命名):整型数值(INT、INTEGER、BIGINT、SMALLINT、TINYINT、BYTEINT、NUMBER(p,0))用 CAST(col AS BIGINT) AS col;小数数值(FLOAT、DOUBLE、REAL、DECIMAL(p,s>0)、NUMBER(p,s>0))用 CAST(col AS DOUBLE) AS col;数值 ARRAY 保留为 ARRAY(GraphSAGE 除外),且关系视图不允许;VECTOR(FLOAT, n) 原样保留,关系视图不允许;BOOLEAN 默认丢弃,仅在显式选择时用 IFF(col, 1, 0)::BIGINT AS col;DATE、TIME、TIMESTAMP* 默认丢弃,仅在显式选择时用 DATE_PART('EPOCH_SECOND', col)::BIGINT AS col(并告知用户单位);VARCHAR、CHAR、TEXT、STRING 丢弃(不能作为图属性),若要按名称读结果,用键把输出 join 回源表;VARIANT、OBJECT、GEOGRAPHY、GEOMETRY、BINARY 丢弃(不支持作为图属性)。
- 采用最低公共分母策略:默认只包含安全列(数值→BIGINT/DOUBLE、ARRAY、VECTOR);布尔和时间类列需显式选择才纳入;丢弃列时简要告知用户丢了哪些、为什么,以便他们要求加回。
- 关系视图规则:暴露 SOURCENODEID 和 TARGETNODEID,用与 NODEID 相同的规则转换(如 SOURCE_COL::BIGINT AS SOURCENODEID);每个值必须匹配某个节点视图中已存在的 NODEID;关系属性只允许 BIGINT、DOUBLE、INT,不允许 ARRAY 和 VECTOR;命名用 <table>_RELATIONSHIPS_VW。
- 用单条 CALL 执行 Project → Compute → Write:第一个参数是计算池,第二个是含 project、compute、write 三部分的 JSON 配置;Snowflake SQL 中 JSON 用单引号。
- 注意 app 名称:Neo4j_Graph_Analytics 只是默认安装名;若以其他名字安装,需在过程调用(<APP>.graph.<algo>)、preview.*/admin.* 调用、USE DATABASE <APP> 语句以及权限授予中全部替换;可用 SHOW APPLICATIONS; 检查。
- 配置 defaultTablePrefix 为视图和输出表所在的 DB.SCHEMA,以便用短名引用;project 中 nodeTables 是数组(每项映射为一个 label),relationshipTables 是 map(每个键映射为一个 type,含 sourceTable/targetTable/orientation);compute 放算法参数,值为 null 的参数一律省略;write 是写入目标列表,nodeLabel(或 sourceLabel/targetLabel)为被写入节点的表/视图名,关系结果用 relationshipType。
- 按算法设置每个关系表的 orientation:NATURAL(默认,有向,源→目标,按表中存储方向);UNDIRECTED(视为双向,每条关系两个方向都包含);REVERSE(方向翻转,目标→源)。社区检测类(WCC、Louvain、Leiden、Label Propagation)用 UNDIRECTED,Triangle Count 必须用 UNDIRECTED;有向流与排名类(PageRank、Article Rank、Dijkstra 及其他寻路、Max Flow)用 NATURAL;Node Similarity 期望二分图(两个不相交节点集)按 NATURAL 投影,用 REVERSE 可比较另一节点集;KNN 完全忽略关系(相似度来自节点属性),orientation 对其无影响(K-Means 同样只用节点属性)。
- 选择计算池(CALL 第一个参数):CPU_X64_XS 为默认(开发/小图);CPU_X64_S/M/L 逐步增大;HIGHMEM_X64_S/M/L 适合大图且 CPU 需求较低;GPU_NV_XS、GPU_NV_S、GPU_GCP_NV_L4_1_24G 用于 GraphSAGE/GPU 工作(可用性因区域而异)。除非用户另有要求或 GraphSAGE 适合 GPU 池,否则优先用 CPU_X64_XS。
- 输出表命名用 result_<algotag>_<short_description>,只用下划线,不含空格/特殊字符(如 result_louvain_customer_segments);写多个节点 label 时每个 label 用不同表。
- 检查结果并按名称回查:节点属性类结果(中心性、社区检测、k-means、嵌入、FastPath)是以 NODEID 为键的表;关系类结果(Node Similarity、KNN、Dijkstra 及其他寻路、Max Flow)是以 SOURCENODEID/TARGETNODEID 为键的表,BFS 等异构写入还会加 SOURCELABEL/TARGETLABEL,节点 ID 以字符串存储;GraphSAGE 训练产出模型(无输出表,写入模型目录),之后用模型预测才产生节点属性表。
- 由于投影时丢弃了 VARCHAR 标签,需把结果 join 回源表以获取可读名称:节点属性结果按 NODEID join(如 SELECT u.name, u.country, r.score FROM ...result_page_rank_influence r JOIN ...USERS u ON r.NODEID = u.user_id ORDER BY r.score DESC LIMIT 10);关系结果需 join 源表两次,一次按 SOURCENODEID、一次按 TARGETNODEID。
- 安装:从 Snowflake Marketplace 安装 Neo4j Graph Analytics(默认 app 名 Neo4j_Graph_Analytics);提示时启用 Event sharing;在 Data Products → Apps → Neo4j Graph Analytics → Privileges → Grant 中授予 CREATE COMPUTE POOL 和 CREATE WAREHOUSE,然后点击 Activate。
- 权限设置 Part A(两种模式都必需):以 ACCOUNTADMIN 运行;CREATE ROLE IF NOT EXISTS MY_CONSUMER_ROLE; GRANT APPLICATION ROLE Neo4j_Graph_Analytics.app_user TO ROLE MY_CONSUMER_ROLE; SET MY_USER = (SELECT CURRENT_USER()); GRANT ROLE MY_CONSUMER_ROLE TO USER IDENTIFIER($MY_USER); 可选创建 admin 角色并授予 Neo4j_Graph_Analytics.app_admin(app_admin 过程需要);再授予消费角色对输出表的读取:GRANT USAGE ON DATABASE/SCHEMA 及 GRANT SELECT ON FUTURE TABLES IN SCHEMA。注意 ACCOUNTADMIN 不会隐式持有 application role;preview.* 和 admin.* 过程需要被授予 app_admin 的角色,算法过程和 preview.register_user_role 需要 app_user。
- 权限设置 Part B 只能二选一,不要混用。选项 1 应用身份授权(默认,每个 database/schema 运行一次):以 ACCOUNTADMIN 运行,USE DATABASE MY_DATABASE; CREATE DATABASE ROLE IF NOT EXISTS MY_DB_ROLE; 授予其对 DATABASE/SCHEMA 的 USAGE、对 ALL TABLES 和 ALL VIEWS 的 SELECT、对 FUTURE TABLES 和 FUTURE VIEWS 的 SELECT(FUTURE 授权让 app 能读取它创建的表/视图,链式调用需要)、对 SCHEMA 的 CREATE TABLE;再 GRANT DATABASE ROLE MY_DB_ROLE TO APPLICATION Neo4j_Graph_Analytics; 最后 USE ROLE MY_CONSUMER_ROLE 以消费角色运行算法。
- 权限设置 Part B 选项 2 以用户身份执行(execute-as-user,preview):作业以调用用户的 PAT 认证,在其持有的角色下、受 caller grants 约束;过程位于 <APP>.preview.*,GA 前可能变化。引导无法端到端脚本化:ADD PROGRAMMATIC ACCESS TOKEN 只显示一次 token secret,先跑 Part 1、从用户处收集 token,再跑 Part 2。
- execute-as-user Part 1:以 ACCOUNTADMIN 运行;PAT 默认需要网络策略,否则作业报 'Fail : Network policy is required',用 USE SCHEMA MY_DATABASE.MY_SCHEMA; CREATE AUTHENTICATION POLICY IF NOT EXISTS pat_no_network_required PAT_POLICY = (NETWORK_POLICY_EVALUATION = ENFORCED_NOT_REQUIRED); ALTER USER <user_name> SET AUTHENTICATION POLICY pat_no_network_required; 豁免(已有网络策略的用户仍强制执行;认证策略是 schema 级对象)。Step 1:以持有 app_admin 的角色(ACCOUNTADMIN 不隐式持有)运行 CALL Neo4j_Graph_Analytics.preview.set_enable_custom_credentials(TRUE); 每个账户一次,不是每用户。Step 2a:以 ACCOUNTADMIN 运行 ALTER USER <user_name> ADD PROGRAMMATIC ACCESS TOKEN app_pat DAYS_TO_EXPIRY = 365 ROLE_RESTRICTION = 'MY_CONSUMER_ROLE'; ROLE_RESTRICTION 是关键,它把 PAT 固定到该角色,且必须与 Step 2d 一致。
- execute-as-user Part 2 步骤 2b+2c:立即从上一个结果集复制 token_secret 列(Snowflake 不会再显示),粘贴到 SECRET_STRING;以 ACCOUNTADMIN 运行 CREATE OR REPLACE SECRET MY_DATABASE.MY_SCHEMA.pat_secret_<user_name> TYPE = GENERIC_STRING SECRET_STRING = '<paste_token_secret_here>';(只能用 GENERIC_STRING,PASSWORD 不行);再 GRANT USAGE ON DATABASE/SCHEMA TO APPLICATION Neo4j_Graph_Analytics 及 GRANT READ ON SECRET ... TO APPLICATION Neo4j_Graph_Analytics(这些是直接授权,不是 caller grants,app 在作业启动时以自身身份读取 secret)。
- execute-as-user 步骤 2d:以 <user_name> 身份打开会话(使 CURRENT_USER() 解析为该用户),在持有 app_user 的角色下运行 CALL Neo4j_Graph_Analytics.preview.register_user_role('MY_CONSUMER_ROLE', 'MY_DATABASE.MY_SCHEMA.pat_secret_<user_name>'); 第一个参数等于 PAT 的 ROLE_RESTRICTION,第二个是 SECRET 的 FQN。
- execute-as-user 步骤 2e:以 ACCOUNTADMIN 为作业要读写的数据发放 caller grants:GRANT CALLER USAGE ON DATABASE/SCHEMA、GRANT CALLER CREATE TABLE ON SCHEMA、GRANT INHERITED CALLER INSERT ON ALL TABLES、GRANT INHERITED CALLER SELECT ON ALL TABLES、GRANT INHERITED CALLER SELECT ON ALL VIEWS。每个 schema 重复;这是唯一的扩权机制,且没有 FUTURE 等价物,所以创建了后续作业需要读取的视图或表后要重跑。
- 用 CALL Neo4j_Graph_Analytics.preview.get_user_role_registration('<user_name>'); 查看管理员为某用户注册了什么。
- 轮换与回滚:轮换时铸造新 PAT、重新指向 secret(其授权保留)、删除旧 PAT,注册表无需更新(SECRET 名未变,只是值变了):CREATE OR REPLACE SECRET ... TYPE = GENERIC_STRING SECRET_STRING = '<new_token_secret>'; ALTER USER <user_name> REMOVE PROGRAMMATIC ACCESS TOKEN <old_pat_name>; 账户级禁用:CALL Neo4j_Graph_Analytics.preview.set_enable_custom_credentials(FALSE);(所有人回到应用身份,注册保留不用);撤销单个用户:REVOKE READ ON SECRET ... FROM APPLICATION Neo4j_Graph_Analytics; 或直接作废凭证:ALTER USER <user_name> REMOVE PROGRAMMATIC ACCESS TOKEN app_pat;
- 链式调用算法:因为结果写入表(且 FUTURE TABLES 授权让 app 能读取它创建的内容),可把一个算法的输出喂给下一个,例如先 CALL Neo4j_Graph_Analytics.graph.fast_rp('CPU_X64_XS', { ... }); 再对嵌入输出表(投影为节点视图)CALL Neo4j_Graph_Analytics.graph.knn('CPU_X64_XS', { ... }); 在 execute-as-user 模式下没有 FUTURE caller grants,创建中间结果表的投影视图后要重跑步骤 2e 的 caller grants,下一个算法才能读取。
- 把分类数据转成数值:图引擎不能把 VARCHAR 当属性,在视图中用 CASE 或查找 join 把类别映射为数字;要按原始标签读结果,用键把输出表 join 回源表。
- GraphSAGE 注意:被 GraphSAGE 使用的投影节点表不得含 ARRAY 属性列,多值数值特征用 VECTOR(FLOAT, n)(ARRAY 对非 GraphSAGE 算法没问题);特征列必须非 NULL 且有限,在视图中过滤、填充或排除可空特征列;gs_nc_train 的 targetProperty 是标签(非特征),可以为 NULL;运行前列出每个节点表 GraphSAGE 将使用的节点属性(所有非 NODEID 列,gs_nc_train 排除 targetProperty);训练(gs_nc_train、gs_unsup_train)可能很慢并可能用 GPU 池(GPU_NV_S),运行训练前展示确切的 CALL 并获得明确确认。
- Dijkstra Source-Target(dijkstra)需提供以下之一:单对(sourceNode + sourceNodeTable、targetNode + targetNodeTable);一源多目标(sourceNode + sourceNodeTable、targetNodes 列表 + targetNodesTable);多对(sourceTargetNodePairsTable,含 SOURCENODEID/TARGETNODEID 列,加 sourceNodeTable + targetNodeTable)。
- 通用注意:绝不要把 NODEID 本身当作算法属性;任何值为 null 的配置参数都省略。
- 排障:Insufficient privileges → app 需要对你表/视图的 SELECT 和 schema 的 CREATE TABLE;no role registered for <user> → execute-as-user 已启用但该用户未引导,以该用户身份运行 preview.register_user_role;Network policy is required → PAT 用户没有允许无网络策略使用 PAT 的认证策略,附加 PAT_POLICY = (NETWORK_POLICY_EVALUATION = ENFORCED_NOT_REQUIRED);execute-as-user 模式下 does not exist or not authorized → 缺少数据 schema 的 caller grants,或对象在 ON ALL ... 授权之后创建,重跑步骤 2e;写入时 Insufficient privileges to operate on table → 写 schema 缺少 CALLER CREATE TABLE / INHERITED CALLER INSERT ON ALL TABLES,重跑步骤 2e;USE ROLE not allowed / Current session is restricted → 角色受限 PAT 下的预期行为,一切必须能从注册的主角色访问;execute-as-user 模式下作业认证报错 → PAT 的 ROLE_RESTRICTION 与注册角色不匹配,或 SECRET 不是 TYPE = GENERIC_STRING;Column nodeId not found → 视图缺少或错误转换了键,用显式转换暴露 NODEID(及 SOURCENODEID/TARGETNODEID);属性类型/投影错误 → 某属性列未转换为支持的类型,套用转换规则,关系属性必须是 BIGINT/DOUBLE/INT;GraphSAGE 特征失败 → 移除 ARRAY 特征列(改用 VECTOR),确保特征非 NULL/有限;Compute pool not available → 池可能仍在启动,等一分钟重试;算法无结果 → 检查节点/关系视图非空,且每个 SOURCENODEID/TARGETNODEID 都匹配某个 NODEID。
- 完成前核对清单:app 已安装、消费角色已创建、只设置一种数据访问模式(应用身份或 execute-as-user);若用 execute-as-user:安装标志已开、PAT 已铸造且 ROLE_RESTRICTION 匹配、SECRET 可被 app 读取、用户已注册、caller grants 已发放;视图暴露 NODEID/SOURCENODEID/TARGETNODEID 且每个属性显式转换;orientation 与算法匹配;单条 CALL 无错运行、输出表已填充;结果已 join 回源表以获得可读标签。
适用边界 · 注意事项
- Aura Pro 内嵌 GDS 插件 → 用 neo4j-gds-skill
- Aura Graph Analytics → 用 neo4j-aura-graph-analytics-skill
- 自管理 Neo4j 内嵌 GDS 插件 → 用 neo4j-gds-skill
- 编写 Cypher 查询 → 用 neo4j-cypher-skill