#前面已经分享过以 HTTP API 或 JavaScript driver 开发 Neo4j 前端应用,今天我们就来看後端应用罗,这篇文章会以 Golang 语言为参考。
目前(2020/10) Neo4j 官方支援的程序语言有 Java、 .NET、JavaScript、Python、Go,针对 Java 还有额外支援框架 Spring、Neo4j-OGM。
其他语言如 Ruby、PHP、Erlang/Elixir、Perl、C/C++、Clojure、Haskell、R 则都是 Neo4j 社区中的开发者们所贡献,但也都有收录在官方教学
使用 go get 或 GO Module 管理 package,建议後者。
go get github.com/neo4j/neo4j-go-driver/neo4j
go mod init github.com/eggttball/go-neo4j
go mod edit -require github.com/neo4j/[email protected]
Import neo4j driver
import "github.com/neo4j/neo4j-go-driver/neo4j"
连线 Neo4j 资料库服务的第一个步骤,便是宣告 driver
物件,一个应用程序只需要初始化这样一个物件即可,勿初始化多个 driver,并在程序结束後手动关闭,一个 driver 会维护一个 Connection Pool 来自动管理资料库的连线与释放。
以下的范例程序码在初始化 Session 後立即关闭 driver,只是示范关闭 driver,实务应用上,勿频繁地关闭 driver 并重新初始化 driver。
session
物件则是管理一连串交易的容器,如果你写多执行绪的应用,不需要担心 driver 物件的状态不同步;但是 session 物件就必须注意其状态,不可以执行绪共用,并应在完成交易後立即关闭。
create driver and session
driver, err := neo4j.NewDriver("bolt://localhost:7687", neo4j.BasicAuth("neo4j", password, ""), func(c *neo4j.Config) {
c.Encrypted = encrypted
})
if err != nil {
return "", err
}
defer driver.Close()
session, err := driver.Session(neo4j.AccessModeWrite)
if err != nil {
return "", err
}
defer session.Close()
这边指定的 Access Mode Read/Write 有助於在连线因果丛集时,让丛集决定要将 Cypher 查询指派给 Core server 还是 Replica server,正确的设定 Access Mode 将有助於资料库的效能大幅提升。
不过在 Session 初始化时的 Access Mode 只会影响自动交易,如果是手动交易,Access Mode 最终还是取决於 Session.WriteTransaction 或是 Session.ReadTransaction。
Session.Run
就相当於 HTTP API 的 /tx/commit,在单次的资料库要求开启交易并立即确认执行。
Result.Consume 会一次读取所有的回传资料并回传 Summary
result, err := session.Run("CREATE (a:Person {name: $name})", map[string]interface{}{"name":
name})
if err != nil {
return err
}
if _, err = result.Consume(); err != nil {
return err
}
greeting, err := session.WriteTransaction(func(transaction neo4j.Transaction) (interface{}, error) {
result, err := transaction.Run(
"CREATE (a:Greeting) SET a.message = $message RETURN a.message + ', from node ' + id(a)",
map[string]interface{}{"message": "hello, world"})
if err != nil {
return nil, err
}
if result.Next() {
return result.Record().GetByIndex(0), nil
}
return nil, result.Err()
})
这边用到了 Result.Next() 来确认是否有回传结果,以及 Result.Record() 来取得每一笔资料
如果预期回传的资料有多笔,可以这样写。
for result.Next() {
record = result.Record();
if value, ok := record.Get('field_name'); ok {
// a value with alias field_name was found
// process value
}
}
以上也刻意示范了 Get by index 和 Get by field name 的选择作法
从资料库取得的结果都会是 interface{} 型别,在程序码中的操作很不便,但我们可以把它 UnBoxing 成真正的物件型别,列表如下
Cypher Type | Driver Type |
---|---|
null | nil |
List | []interface{} |
Map | map[string]interface{} |
Boolean | bool |
Integer | int64 |
Float | float |
String | string |
ByteArray | []byte |
Node | neo4j.Node |
Relationship | neo4j.Relationship |
Path | neo4j.Path |
Point | neo4j.Point |
Date | neo4j.Date |
Time | neo4j.OffsetTime |
LocalTime | neo4j.LocalTime |
DateTime | time.Time |
LocalDateTime | neo4j.LocalDateTime |
Duration | neo4j.Duration |
例如
value, ok := record.Get('birthday').(neo4j.Date)
如果资料库是采用因果丛集架构,只需要将协定改成 bolt+routing 中可,後面接的机器位址则必须是任一台 Core Server。
if driver, err = neo4j.NewDriver("bolt+routing://localhost:7687", neo4j.BasicAuth("username", "password", "")); err != nil {
return err
}
资考资源:
https://github.com/neo4j/neo4j-go-driver
https://neo4j.com/docs/pdf/neo4j-driver-manual-1.7-go.pdf
https://godoc.org/github.com/neo4j/neo4j-go-driver/neo4j
<<: [Python]如何Speech to Text: SpeechRecognition
理解js单执行绪&非同步运行机制 由於js为单执行绪,也就是一次只处理一件事情并依序执行,但...
今天的目标: 要怎麽样依照范本复制并改动 Google Sheet,并一次性地的将结果搜集到同一份 ...
方法一 此多边形方法虽然不是小画家的画法,但一样可以达成多边形的做法,如下: /** * 滑鼠点下画...
我自己的写文习惯是如果文章内容刚好符合两个分类,就会同时设定两个分类。不过这也意外让我入了一个坑啊(...
今年的疫情蛮严重的,希望大家都过得安好,希望疫情快点过去,能回到一些线下技术聚会的时光~ 今天目标:...