| # Licensed to the Apache Software Foundation (ASF) under one | |
| # or more contributor license agreements. See the NOTICE file | |
| # distributed with this work for additional information | |
| # regarding copyright ownership. The ASF licenses this file | |
| # to you under the Apache License, Version 2.0 (the | |
| # "License"); you may not use this file except in compliance | |
| # with the License. You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, | |
| # software distributed under the License is distributed on an | |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| # KIND, either express or implied. See the License for the | |
| # specific language governing permissions and limitations | |
| # under the License. | |
| """ | |
| Code courtesy of the FalkorDB. | |
| """ | |
| # collect graph's schema | |
| def graph_schema(g): | |
| schema = {} | |
| # --------------------------------------------------------------------------- | |
| # process nodes | |
| # --------------------------------------------------------------------------- | |
| nodes = {} | |
| q = "CALL db.labels()" | |
| labels = [x[0] for x in g.query(q).result_set] | |
| for label in labels: | |
| nodes[label] = {} | |
| nodes[label]["attributes"] = {} | |
| q = f"MATCH (n:{label}) RETURN n LIMIT 50" | |
| result = g.query(q).result_set | |
| for row in result: | |
| node = row[0] | |
| for attr in node.properties: | |
| val = node.properties[attr] | |
| if attr not in nodes[label]["attributes"]: | |
| nodes[label]["attributes"][attr] = {"type": type(val).__name__} | |
| schema["nodes"] = nodes | |
| # --------------------------------------------------------------------------- | |
| # process relations | |
| # --------------------------------------------------------------------------- | |
| edges = {} | |
| q = "CALL db.relationshiptypes()" | |
| rels = [x[0] for x in g.query(q).result_set] | |
| for r in rels: | |
| edges[r] = {} | |
| edges[r]["attributes"] = {} | |
| q = f"MATCH ()-[e:{r}]->() RETURN e LIMIT 50" | |
| result = g.query(q).result_set | |
| for row in result: | |
| edge = row[0] | |
| for attr in edge.properties: | |
| val = edge.properties[attr] | |
| if attr not in edges[r]["attributes"]: | |
| edges[r]["attributes"][attr] = {"type": type(val).__name__} | |
| edges[r]["connects"] = [] | |
| # collect edge endpoints | |
| for src in labels: | |
| for dest in labels: | |
| q = f"MATCH (:{src})-[:{r}]->(:{dest}) RETURN 1 LIMIT 1" | |
| res = g.query(q).result_set | |
| if len(res) == 1: | |
| edges[r]["connects"].append((src, dest)) | |
| schema["edges"] = edges | |
| return schema |