操作查询结果
本节展示如何处理查询结果,以提取最适合您应用程序的数据形式。
结果作为列表
默认情况下,Driver.execute_query()
返回一个 EagerResult
对象。
records, summary, keys = driver.execute_query(
"MATCH (a:Person) RETURN a.name AS name, a.age AS age",
database_="neo4j",
)
for person in records: (1)
print(person)
# person["name"] or person["age"] are also valid
# Some summary information (2)
print("Query `{query}` returned {records_count} records in {time} ms.".format(
query=summary.query, records_count=len(records),
time=summary.result_available_after
))
print(f"Available keys are {keys}") # ['name', 'age'] (3)
1 | 结果记录作为列表返回,因此很容易遍历它们。 |
2 | 执行的摘要,包含元数据和结果信息。 |
3 | 返回行中可用的 keys 。 |
转换为 Pandas DataFrame
驱动程序可以将结果转换为 Pandas DataFrame。为此,请使用 .execute_query()
关键字参数 result_transformer_
并将其设置为 neo4j.Result.to_df
。此方法仅在安装了 pandas
库时可用。
n
, m
) 和 10 行的 DataFrameimport neo4j
pandas_df = driver.execute_query(
"UNWIND range(1, 10) AS n RETURN n, n+1 AS m",
database_="neo4j",
result_transformer_=neo4j.Result.to_df
)
print(type(pandas_df)) # <class 'pandas.core.frame.DataFrame'>
此转换器接受两个可选参数
-
expand
— 如果为True
,结果中的某些数据结构将递归展开并扁平化。更多信息请参阅API 文档。 -
parse_dates
— 如果为True
,则仅包含time.DateTime
对象、time.Date
对象或None
的列将被转换为pandas.Timestamp
。
如果您需要向 to_df 传递参数,请使用 lambda 函数result_transformer_=lambda res: res.to_df(True)
|
转换为图
驱动程序可以将结果转换为图对象集合。为此,请使用 .execute_query()
关键字参数 result_transformer_
并将其设置为 neo4j.Result.graph
。为了最大限度地利用此方法,您的查询应返回图状结果而非单列。图转换器返回一个 Graph
对象,该对象公开 nodes
和 relationships
属性,这些属性是 Node
和 Relationship
对象的集合视图。
您可以使用图格式进行进一步处理或可视化查询结果。下面是一个使用 pyvis
库绘制图的示例实现。
pyvis
可视化图结果import pyvis
from neo4j import GraphDatabase
import neo4j
URI = "{neo4j-database-uri}"
AUTH = ("{neo4j-username}", "{neo4j-password}")
def main():
with GraphDatabase.driver(URI, auth=AUTH) as driver:
# Create some friends
input_list = [("Arthur", "Guinevre"),
("Arthur", "Lancelot"),
("Arthur", "Merlin")]
driver.execute_query("""
UNWIND $pairs AS pair
MERGE (a:Person {name: pair[0]})
MERGE (a)-[:KNOWS]->(friend:Person {name: pair[1]})
""", pairs=input_list,
database_="neo4j",
)
# Create a film
driver.execute_query("""
MERGE (film:Film {title: $title})
MERGE (liker:Person {name: $person_name})
MERGE (liker)-[:LIKES]->(film)
""", title="Wall-E", person_name="Arthur",
database_="neo4j",
)
# Query to get a graphy result
graph_result = driver.execute_query("""
MATCH (a:Person {name: $name})-[r]-(b)
RETURN a, r, b
""", name="Arthur",
result_transformer_=neo4j.Result.graph,
)
# Draw graph
nodes_text_properties = { # what property to use as text for each node
"Person": "name",
"Film": "title",
}
visualize_result(graph_result, nodes_text_properties)
def visualize_result(query_graph, nodes_text_properties):
visual_graph = pyvis.network.Network()
for node in query_graph.nodes:
node_label = list(node.labels)[0]
node_text = node[nodes_text_properties[node_label]]
visual_graph.add_node(node.element_id, node_text, group=node_label)
for relationship in query_graph.relationships:
visual_graph.add_edge(
relationship.start_node.element_id,
relationship.end_node.element_id,
title=relationship.type
)
visual_graph.show('network.html', notebook=False)
if __name__ == "__main__":
main()

自定义转换器
对于更高级的场景,您可以使用参数 result_transformer_
提供一个自定义函数,以进一步操作查询产生的 Result
对象。转换器接受一个 Result
对象,并可以输出任何数据结构。转换器的返回值又由 .execute_query()
返回。
在转换器函数内部,您可以使用 Result
的任何方法。
single
和 consume
的自定义转换器# Get a single record (or an exception) and the summary from a result.
def get_single_person(result):
record = result.single(strict=True)
summary = result.consume()
return record, summary
record, summary = driver.execute_query(
"MERGE (a:Person {name: $name}) RETURN a.name AS name",
name="Alice",
database_="neo4j",
result_transformer_=get_single_person,
)
print("The query `{query}` returned {record} in {time} ms.".format(
query=summary.query, record=record, time=summary.result_available_after))
fetch
和 peek
的自定义转换器# Get exactly 5 records, or an exception.
def exactly_5(result):
records = result.fetch(5)
if len(records) != 5:
raise Exception(f"Expected exactly 5 records, found only {len(records)}.")
if result.peek():
raise Exception("Expected exactly 5 records, found more.")
return records
records = driver.execute_query("""
UNWIND ['Alice', 'Bob', 'Laura', 'John', 'Patricia'] AS name
MERGE (a:Person {name: name}) RETURN a.name AS name
""", database_="neo4j",
result_transformer_=exactly_5,
)
转换器不得返回
|
术语表
- LTS
-
长期支持 (LTS) 版本是保证支持多年的版本。Neo4j 4.4 是 LTS 版本,Neo4j 5 也将有一个 LTS 版本。
- Aura
-
Aura 是 Neo4j 的全托管云服务。它提供免费和付费计划。
- Cypher
-
Cypher 是 Neo4j 的图查询语言,它允许您从数据库中检索数据。它类似于 SQL,但适用于图。
- APOC
-
Awesome Procedures On Cypher (APOC) 是一个函数库(包含许多函数),这些函数本身无法轻易地用 Cypher 表达。
- Bolt
-
Bolt 是 Neo4j 实例与驱动程序之间交互所使用的协议。它默认监听端口 7687。
- ACID
-
原子性、一致性、隔离性、持久性 (ACID) 是保证数据库事务可靠处理的属性。符合 ACID 的 DBMS 确保数据库中的数据在发生故障时仍能保持准确和一致。
- 最终一致性
-
如果数据库提供所有集群成员将在某个时间点存储最新版本数据的保证,则称其为最终一致性数据库。
- 因果一致性
-
如果集群的每个成员都以相同的顺序看到读写查询,则数据库是因果一致的。这比最终一致性更强。
- NULL
-
空标记不是一种类型,而是值缺失的占位符。更多信息请参阅 Cypher → 使用
null
。 - 事务
-
事务是作为一个整体提交或在失败时回滚的工作单元。一个例子是银行转账:它涉及多个步骤,但所有步骤都必须成功或被撤销,以避免资金从一个账户中扣除但未添加到另一个账户的情况。
- 背压
-
背压是阻碍数据流的一种力。它确保客户端不会被快于其处理速度的数据所淹没。
- 事务函数
-
事务函数是由
execute_read
或execute_write
调用执行的回调。在服务器故障时,驱动程序会自动重新执行该回调。 - Driver
-
一个
Driver
对象包含与 Neo4j 数据库建立连接所需的详细信息。