使用 Neo4j 和 Go 构建应用程序

Neo4j Go 驱动程序是官方库,用于通过 Go 应用程序与 Neo4j 实例交互。

Neo4j 的核心是 Cypher,这是与 Neo4j 数据库交互的查询语言。虽然本指南不要求您成为经验丰富的 Cypher 查询者,但如果您已经了解一些 Cypher,将更容易专注于 Go 特定的部分。因此,尽管本指南也在过程中提供 Cypher 的简要介绍,但如果您是初次接触图数据库建模和查询,请考虑查看入门 → Cypher 以获取更详细的演练。然后,您可以在遵循本指南开发 Go 应用程序时应用这些知识。

安装

在模块内部,使用 go get 安装 Neo4j Go 驱动程序

go get github.com/neo4j/neo4j-go-driver/v5

连接到数据库

通过创建 DriverWithContext 对象并提供 URL 和身份验证令牌来连接到数据库。一旦您拥有 DriverWithContext 实例,使用 .VerifyConnectivity() 方法确保可以建立正常工作的连接。

package main

import (
    "fmt"
    "context"
    "github.com/neo4j/neo4j-go-driver/v5/neo4j"
)

func main() {
    ctx := context.Background()
    // URI examples: "neo4j://localhost", "neo4j+s://xxx.databases.neo4j.io"
    dbUri := "{neo4j-database-uri}"
    dbUser := "{neo4j-username}"
    dbPassword := "{neo4j-password}"
    driver, err := neo4j.NewDriverWithContext(
        dbUri,
        neo4j.BasicAuth(dbUser, dbPassword, ""))
    defer driver.Close(ctx)

    err = driver.VerifyConnectivity(ctx)
    if err != nil {
        panic(err)
    }
    fmt.Println("Connection established.")
}

创建示例图

使用函数 ExecuteQuery() 运行 Cypher 查询。不要硬编码或连接参数:使用占位符并指定参数作为关键字参数。

创建两个 Person 节点和它们之间的 KNOWS 关系
result, err := neo4j.ExecuteQuery(ctx, driver, `
    CREATE (a:Person {name: $name})
    CREATE (b:Person {name: $friendName})
    CREATE (a)-[:KNOWS]->(b)
    `,
    map[string]any{
        "name": "Alice",
        "friendName": "David",
    }, neo4j.EagerResultTransformer,
    neo4j.ExecuteQueryWithDatabase("neo4j"))
if err != nil {
    panic(err)
}

summary := result.Summary
fmt.Printf("Created %v nodes in %+v.\n",
    summary.Counters().NodesCreated(),
    summary.ResultAvailableAfter())

查询图

要从数据库检索信息,请使用 Cypher 子句 MATCH

检索所有喜欢其他 PersonPerson 节点
result, err := neo4j.ExecuteQuery(ctx, driver, `
    MATCH (p:Person)-[:KNOWS]->(:Person)
    RETURN p.name AS name
    `,
    nil,
    neo4j.EagerResultTransformer,
    neo4j.ExecuteQueryWithDatabase("neo4j"))
if err != nil {
    panic(err)
}

// Loop through results and do something with them
for _, record := range result.Records {
    name, _ := record.Get("name")  // .Get() 2nd return is whether key is present
    fmt.Println(name)
    // or
    // fmt.Println(record.AsMap())  // get Record as a map
}

// Summary information
fmt.Printf("The query `%v` returned %v records in %+v.\n",
    result.Summary.Query().Text(), len(result.Records),
    result.Summary.ResultAvailableAfter())

关闭连接和会话

对所有 DriverWithContextSessionWithContext 实例调用 .close() 方法,以释放它们仍然持有的任何资源。最佳实践是在创建新对象后立即使用 defer 关键字调用这些方法。

driver, err := neo4j.NewDriverWithContext(dbUri, neo4j.BasicAuth(dbUser, dbPassword, ""))
defer driver.Close(ctx)
session := driver.NewSession(ctx, neo4j.SessionConfig{DatabaseName: "neo4j"})
defer session.Close(ctx)

术语表

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

原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)(ACID)是保证数据库事务可靠处理的属性。符合 ACID 的 DBMS 确保数据库中的数据即使在出现故障时也保持准确和一致。

最终一致性

如果数据库保证所有集群成员都将在某个时间点存储数据的最新版本,则该数据库是最终一致的。

因果一致性

如果读写查询在集群的每个成员中以相同的顺序被看到,则数据库是因果一致的。这比最终一致性更强。

NULL

Null 标记不是一种类型,而是表示值不存在的占位符。更多信息请参见Cypher → 使用 null

事务

事务是一个工作单元,要么整体提交,要么在失败时回滚。一个例子是银行转账:它涉及多个步骤,但所有步骤都必须成功或被撤销,以避免钱从一个账户中扣除但未添加到另一个账户的情况。

反压

反压是一种阻碍数据流动的力。它确保客户端不会被比其处理能力更快的数据淹没。

事务函数

事务函数是由 ExecuteReadExecuteWrite 调用执行的回调。在服务器故障的情况下,驱动程序会自动重新执行回调。

DriverWithContext

一个 DriverWithContext 对象包含建立与 Neo4j 数据库连接所需的详细信息。

© . All rights reserved.