操作查询结果
本节介绍如何处理查询结果,以便以最适合您的应用程序的形式提取数据。
结果作为列表
默认情况下,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 = "<URI for Neo4j database>"
AUTH = ("<Username>", "<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
-
长期支持版本是保证支持多年的版本。Neo4j 4.4 是 LTS,Neo4j 5 也将具有 LTS 版本。
- Aura
-
Aura 是 Neo4j 的完全托管云服务。它提供免费和付费计划。
- Cypher
-
Cypher 是 Neo4j 的图形查询语言,它允许您从数据库中检索数据。它类似于 SQL,但适用于图形。
- APOC
-
Cypher 上的强大程序 (APOC) 是一个包含(许多)函数的库,这些函数无法用 Cypher 本身轻松表达。
- Bolt
-
Bolt 是用于 Neo4j 实例和驱动程序之间交互的协议。默认情况下,它监听端口 7687。
- ACID
-
原子性、一致性、隔离性、持久性 (ACID) 是保证数据库事务可靠处理的属性。符合 ACID 的 DBMS 确保数据库中的数据在出现故障的情况下仍然准确且一致。
- 最终一致性
-
如果数据库提供保证,即所有集群成员将在某个时间点存储数据的最新版本,则该数据库最终一致。
- 因果一致性
-
如果读写查询以相同的顺序被集群中的每个成员看到,则数据库因果一致。这比最终一致性更强。
- NULL
-
空标记不是类型,而是值缺失的占位符。有关更多信息,请参阅 Cypher → 使用
null
。 - 事务
-
事务是工作单元,它要么全部提交,要么在失败时回滚。一个例子是银行转账:它涉及多个步骤,但它们必须全部成功或被恢复,以避免从一个帐户中扣款,但没有添加到另一个帐户中。
- 背压
-
背压是抵制数据流的力量。它确保客户端不会被其无法处理的速度更快的数据淹没。
- 事务函数
-
事务函数是
execute_read
或execute_write
调用执行的回调。驱动程序会自动在服务器发生故障时重新执行回调。 - 驱动程序
-
一个
Driver
对象包含建立与 Neo4j 数据库连接所需的详细信息。