投影图并使用图目录

Colab Google Colab 中跟随笔记本进行学习

此示例演示如何

  • 将 Neo4j 磁盘上的数据加载到内存中的投影图中;

  • 使用 图目录 管理投影图。

设置

有关如何开始使用 Python 的更多信息,请参阅 使用 Python 连接 教程。

pip install graphdatascience
# Import the client
from graphdatascience import GraphDataScience

# Replace with the actual URI, username, and password
AURA_CONNECTION_URI = "neo4j+s://xxxxxxxx.databases.neo4j.io"
AURA_USERNAME = "neo4j"
AURA_PASSWORD = ""

# Configure the client with AuraDS-recommended settings
gds = GraphDataScience(
    AURA_CONNECTION_URI,
    auth=(AURA_USERNAME, AURA_PASSWORD),
    aura_ds=True
)

在以下代码示例中,我们使用 print 函数打印 Pandas DataFrameSeries 对象。您可以尝试不同的方法来打印 Pandas 对象,例如通过 to_stringto_json 方法;如果您使用 JSON 表示形式,在某些情况下,您可能需要包含一个 默认处理程序 来处理 Neo4j DateTime 对象。查看 Python 连接 部分以获取一些示例。

有关如何开始使用 Cypher Shell 的更多信息,请参阅 Neo4j Cypher Shell 教程。

从安装 Cypher shell 的目录运行以下命令。
export AURA_CONNECTION_URI="neo4j+s://xxxxxxxx.databases.neo4j.io"
export AURA_USERNAME="neo4j"
export AURA_PASSWORD=""

./cypher-shell -a $AURA_CONNECTION_URI -u $AURA_USERNAME -p $AURA_PASSWORD

有关如何开始使用 Python 的更多信息,请参阅 使用 Python 连接 教程。

pip install neo4j
# Import the driver
from neo4j import GraphDatabase

# Replace with the actual URI, username, and password
AURA_CONNECTION_URI = "neo4j+s://xxxxxxxx.databases.neo4j.io"
AURA_USERNAME = "neo4j"
AURA_PASSWORD = ""

# Instantiate the driver
driver = GraphDatabase.driver(
    AURA_CONNECTION_URI,
    auth=(AURA_USERNAME, AURA_PASSWORD)
)
# Import to prettify results
import json

# Import for the JSON helper function
from neo4j.time import DateTime

# Helper function for serializing Neo4j DateTime in JSON dumps
def default(o):
    if isinstance(o, (DateTime)):
        return o.isoformat()

使用原生投影从 Neo4j 加载数据

原生投影用于将存储在磁盘上的图加载到内存中。 gds.graph.project 过程允许通过选择要投影的节点标签、关系类型和属性来投影图。

gds.graph.project 过程可以使用 “简写语法”,其中节点和关系投影简单地作为单个值或数组传递,或者使用 “扩展语法”,其中每个节点或关系投影都有其自己的配置。如果需要对数据或图结构进行额外的转换,则扩展语法特别有用。本节中将展示这两种方法,并使用以下图作为示例。

# Cypher query to create an example graph on disk
gds.run_cypher("""
    MERGE (a:EngineeringManagement {name: 'Alistair'})
    MERGE (j:EngineeringManagement {name: 'Jennifer'})
    MERGE (d:Developer {name: 'Leila'})
    MERGE (a)-[:MANAGES {start_date: 987654321}]->(d)
    MERGE (j)-[:MANAGES {start_date: 123456789, end_date: 987654321}]->(d)
""")
MERGE (a:EngineeringManagement {name: 'Alistair'})
MERGE (j:EngineeringManagement {name: 'Jennifer'})
MERGE (d:Developer {name: 'Leila'})
MERGE (a)-[:MANAGES {start_date: 987654321}]->(d)
MERGE (j)-[:MANAGES {start_date: 123456789, end_date: 987654321}]->(d)
# Cypher query to create an example graph on disk
write_example_graph_query = """
    MERGE (a:EngineeringManagement {name: 'Alistair'})
    MERGE (j:EngineeringManagement {name: 'Jennifer'})
    MERGE (d:Developer {name: 'Leila'})
    MERGE (a)-[:MANAGES {start_date: 987654321}]->(d)
    MERGE (j)-[:MANAGES {start_date: 123456789, end_date: 987654321}]->(d)
"""

# Create the driver session
with driver.session() as session:
    session.run(write_example_graph_query)

使用简写语法进行投影

在此示例中,我们使用简写语法简单地投影所有节点标签和关系类型。

# Project a graph using the shorthand syntax
shorthand_graph, result = gds.graph.project(
    "shorthand-example-graph",
    ["EngineeringManagement", "Developer"],
    ["MANAGES"]
)

print(result)
CALL gds.graph.project(
  'shorthand-example-graph',
  ['EngineeringManagement', 'Developer'],
  ['MANAGES']
)
YIELD graphName, nodeCount, relationshipCount
RETURN *
shorthand_graph_create_call = """
    CALL gds.graph.project(
      'shorthand-example-graph',
      ['EngineeringManagement', 'Developer'],
      ['MANAGES']
    )
    YIELD graphName, nodeCount, relationshipCount
    RETURN *
"""

# Create the driver session
with driver.session() as session:
    # Call to project a graph using the shorthand syntax
    result = session.run(shorthand_graph_create_call).data()

    # Prettify the result
    print(json.dumps(result, indent=2, sort_keys=True))

使用扩展语法进行投影

在此示例中,我们使用扩展语法进行 节点关系 投影,以

  • EngineeringManagementDeveloper 标签分别转换为 PersonEMPersonD

  • 有向 MANAGES 关系转换为 KNOWS 无向 关系;

  • 保留 start_dateend_date 关系属性,并向 end_date 添加默认值 999999999

投影后的图变为如下所示

(:PersonEM {first_name: 'Alistair'})-
  [:KNOWS {start_date: 987654321, end_date: 999999999}]-
  (:PersonD {first_name: 'Leila'})-
  [:KNOWS {start_date: 123456789, end_date: 987654321}]-
  (:PersonEM {first_name: 'Jennifer'})
# Project a graph using the extended syntax
extended_form_graph, result = gds.graph.project(
    "extended-form-example-graph",
    {
        "PersonEM": {
            "label": "EngineeringManagement"
        },
        "PersonD": {
            "label": "Developer"
        }
    },
    {
        "KNOWS": {
            "type": "MANAGES",
            "orientation": "UNDIRECTED",
            "properties": {
                "start_date": {
                    "property": "start_date"
                },
                "end_date": {
                    "property": "end_date",
                    "defaultValue": 999999999
                }
            }
        }
    }
)

print(result)
CALL gds.graph.project(
  'extended-form-example-graph',
  {
    PersonEM: {
      label: 'EngineeringManagement'
    },
    PersonD: {
      label: 'Developer'
    }
  },
  {
    KNOWS: {
      type: 'MANAGES',
      orientation: 'UNDIRECTED',
      properties: {
        start_date: {
          property: 'start_date'
        },
        end_date: {
          property: 'end_date',
          defaultValue: 999999999
        }
      }
    }
  }
)
YIELD graphName, nodeCount, relationshipCount
RETURN *
extended_form_graph_create_call = """
    CALL gds.graph.project(
      'extended-form-example-graph',
      {
        PersonEM: {
          label: 'EngineeringManagement'
        },
        PersonD: {
          label: 'Developer'
        }
      },
      {
        KNOWS: {
          type: 'MANAGES',
          orientation: 'UNDIRECTED',
          properties: {
            start_date: {
              property: 'start_date'
            },
            end_date: {
              property: 'end_date',
              defaultValue: 999999999
            }
          }
        }
      }
    )
    YIELD graphName, nodeCount, relationshipCount
    RETURN *
"""

# Create the driver session
with driver.session() as session:
    # Call to project a graph using the extended syntax
    result = session.run(extended_form_graph_create_call).data()

    # Prettify the results
    print(json.dumps(result, indent=2, sort_keys=True))

使用图目录

图目录可用于检索有关投影图的信息并对其进行管理。

列出所有图

gds.graph.list 过程可用于列出当前存储在内存中的所有图。

# List all in-memory graphs
all_graphs = gds.graph.list()

print(all_graphs)
CALL gds.graph.list()
show_in_memory_graphs_call = """
    CALL gds.graph.list()
"""

# Create the driver session
with driver.session() as session:
    # Run the Cypher procedure
    results = session.run(show_in_memory_graphs_call).data()

    # Prettify the results
    print(json.dumps(results, indent=2, sort_keys=True, default=default))

检查图是否存在

可以调用 gds.graph.exists 过程来检查图是否存在,方法是使用其名称。

# Check whether the "shorthand-example-graph" graph exists in memory
graph_exists = gds.graph.exists("shorthand-example-graph")

print(graph_exists)
CALL gds.graph.exists('example-graph')
check_graph_exists_call = """
    CALL gds.graph.exists('example-graph')
"""

# Create the driver session
with driver.session() as session:
    # Run the Cypher procedure and print the result
    print(session.run(check_graph_exists_call).data())

删除图

当不再需要图时,可以使用 gds.graph.drop 过程将其删除以释放内存。

# Drop a graph object and keep the result of the call
result = gds.graph.drop(shorthand_graph)

# Print the result
print(result)

# Drop a graph object and just print the result of the call
gds.graph.drop(extended_form_graph)
CALL gds.graph.drop('shorthand-example-graph');

CALL gds.graph.drop('extended-form-example-graph');
delete_shorthand_graph_call = """
    CALL gds.graph.drop('shorthand-example-graph')
"""

delete_extended_form_graph_call = """
    CALL gds.graph.drop('extended-form-example-graph')
"""

# Create the driver session
with driver.session() as session:
    # Drop a graph and keep the result of the call
    result = session.run(delete_shorthand_graph_call).data()

    # Prettify the result
    print(json.dumps(result, indent=2, sort_keys=True, default=default))

    # Drop a graph discarding the result of the call
    session.run(delete_extended_form_graph_call).data()

清理

删除投影图时,磁盘上的基础数据不会被删除。如果不再需要此类数据,则需要通过 Cypher 查询手动删除它们。

# Delete on-disk data
gds.run_cypher("""
    MATCH (example)
    WHERE example:EngineeringManagement OR example:Developer
    DETACH DELETE example
""")
MATCH (example)
WHERE example:EngineeringManagement OR example:Developer
DETACH DELETE example;
delete_example_graph_query = """
    MATCH (example)
    WHERE example:EngineeringManagement OR example:Developer
    DETACH DELETE example
"""

# Create the driver session
with driver.session() as session:
    # Run Cypher call
    print(session.run(delete_example_graph_query).data())

关闭连接

当不再需要连接时,应始终将其关闭。

尽管 GDS 客户端会在对象被删除时自动关闭连接,但最好显式关闭它。

# Close the client connection
gds.close()
# Close the driver connection
driver.close()

参考

Cypher

  • 了解有关 Cypher 语法的更多信息

  • 您可以使用 Cypher 速查表 作为所有可用 Cypher 功能的参考