查询方法
连接到数据库之后,用户可使用驱动的Gql()
或Uql()
方法执行GQL或UQL语句来全方位操作数据库。
GQL(ISO标准图查询语言)和UQL(嬴图原生查询语言)都可以用来操作数据库。为了使用驱动,你无需精通GQL或UQL,但如果对其中任何一种语言有基本的认识,会很有帮助。了解更多,请阅读GQL快速入门、GQL文档或UQL文档。
方法 |
参数 | 返回值 |
---|---|---|
Gql() |
|
Response 和error |
Uql() |
|
Response 和error |
请求配置
RequestConfig
包含以下字段:
字段 |
类型 |
默认值 |
描述 |
---|---|---|---|
Graph |
string | / | 使用的图名称;未指定时,使用UltipaConfig.DefaultGraph 指定的图 |
Timeout |
int32 | / | 请求超时阈值(单位:秒);此字段会覆盖UltipaConfig.Timeout |
Host |
string | / | 指定数据库集群中的一台服务器来执行请求 |
Thread |
uint32 | / | 请求的线程数 |
Timezone |
string | / | 时区,例如Europe/Paris ;未指定时默认使用本地时区 |
TimezoneOffset |
string | / | 相对于UTC时区的偏移量,格式为±<hh>:<mm> or ±<hh><mm> (例:+02:00 、-0430 );同时设置Timezone 和TimezoneOffset 时,仅TimezoneOffset 有效 |
指定查询的图
由于每个嬴图数据库实例可以托管多个图,大多数查询(包括CRUD操作)都需要指定目标图。
有两种方式可以为请求指定图:
- 连接时设置默认图:连接数据库时,你可以使用
UltipaConfig.DefaultGraph
(可选)设置一个默认图。 - 按请求指定图:对于特定查询,通过设置
RequestConfig.Graph
来选择图。此设置将覆盖UltipaConfig.DefaultGraph
的设置。
创建一个图
在数据库中新建一个图:
package main
import (
"fmt"
"log"
"github.com/ultipa/ultipa-go-driver/v5/sdk"
"github.com/ultipa/ultipa-go-driver/v5/sdk/configuration"
)
func main() {
config := &configuration.UltipaConfig{
// URI example: Hosts: []string{"xxxx.us-east-1.cloud.ultipa.com:60010"},
Hosts: []string{"10.xx.xx.xx:60010"},
Username: "<username>",
Password: "<password>",
}
driver, err := sdk.NewUltipaDriver(config)
if err != nil {
log.Fatalln("Failed to connect to Ultipa:", err)
}
// Creates a new open graph named 'g1'
response, _ := driver.Gql("CREATE GRAPH g1 ANY", nil)
fmt.Println(response.Status.Code)
}
SUCCESS
插入点和边
向图中插入点和边:
package main
import (
"fmt"
"log"
"github.com/ultipa/ultipa-go-driver/v5/sdk"
"github.com/ultipa/ultipa-go-driver/v5/sdk/configuration"
)
func main() {
config := &configuration.UltipaConfig{
// URI example: Hosts: []string{"xxxx.us-east-1.cloud.ultipa.com:60010"},
Hosts: []string{"10.xx.xx.xx:60010"},
Username: "<username>",
Password: "<password>",
DefaultGraph: "g1", // Sets the default graph to 'g1'
}
driver, err := sdk.NewUltipaDriver(config)
if err != nil {
log.Fatalln("Failed to connect to Ultipa:", err)
}
// Inserts nodes and edges into graph the 'g1'
response, _ := driver.Gql(`INSERT
(u1:User {_id: 'U1', name: 'rowlock'}),
(u2:User {_id: 'U2', name: 'Brainy'}),
(u3:User {_id: 'U3', name: 'purplechalk'}),
(u4:User {_id: 'U4', name: 'mochaeach'}),
(u5:User {_id: 'U5', name: 'lionbower'}),
(u1)-[:Follows {createdOn: DATE('2024-01-05')}]->(u2),
(u4)-[:Follows {createdOn: DATE('2024-02-10')}]->(u2),
(u2)-[:Follows {createdOn: DATE('2024-02-01')}]->(u3),
(u3)-[:Follows {createdOn: DATE('2024-05-03')}]->(u5)`, nil)
fmt.Println(response.Status.Code)
}
SUCCESS
更新点和边
更新图中一个点的属性值:
package main
import (
"encoding/json"
"fmt"
"log"
"github.com/ultipa/ultipa-go-driver/v5/sdk"
"github.com/ultipa/ultipa-go-driver/v5/sdk/configuration"
)
func main() {
config := &configuration.UltipaConfig{
// URI example: Hosts: []string{"xxxx.us-east-1.cloud.ultipa.com:60010"},
Hosts: []string{"10.xx.xx.xx:60010"},
Username: "<username>",
Password: "<password>",
}
driver, err := sdk.NewUltipaDriver(config)
if err != nil {
log.Fatalln("Failed to connect to Ultipa:", err)
}
// Updates name of the user U1 in the graph 'g1'
requestConfig := &configuration.RequestConfig{Graph: "g1"}
response, _ := driver.Gql("MATCH (n:User {_id: 'U1'}) SET n.name = 'RowLock99' RETURN n", requestConfig)
nodes, _, _ := response.Alias("n").AsNodes()
for _, node := range nodes {
jsonData, err := json.MarshalIndent(node, "", " ")
if err != nil {
fmt.Println("Error:", err)
continue
}
fmt.Println(string(jsonData))
}
}
{
"ID": "U1",
"UUID": 15276212135063977986,
"Schema": "User",
"Values": {
"Data": {
"name": "RowLock99"
}
}
}
删除点和边
从图中删除一条边:
package main
import (
"fmt"
"log"
"github.com/ultipa/ultipa-go-driver/v5/sdk"
"github.com/ultipa/ultipa-go-driver/v5/sdk/configuration"
)
func main() {
config := &configuration.UltipaConfig{
// URI example: Hosts: []string{"xxxx.us-east-1.cloud.ultipa.com:60010"},
Hosts: []string{"10.xx.xx.xx:60010"},
Username: "<username>",
Password: "<password>",
}
driver, err := sdk.NewUltipaDriver(config)
if err != nil {
log.Fatalln("Failed to connect to Ultipa:", err)
}
// Deletes the edge between users U3 and U5 in the graph 'g1'
requestConfig := &configuration.RequestConfig{Graph: "g1"}
response, _ := driver.Gql("MATCH ({_id: 'U1'})-[e]-({_id: 'U5'}) DELETE e", requestConfig)
fmt.Println(response.Status.Code)
}
SUCCESS
查询点
在图中查询点:
package main
import (
"encoding/json"
"fmt"
"log"
"github.com/ultipa/ultipa-go-driver/v5/sdk"
"github.com/ultipa/ultipa-go-driver/v5/sdk/configuration"
)
func main() {
config := &configuration.UltipaConfig{
// URI example: Hosts: []string{"xxxx.us-east-1.cloud.ultipa.com:60010"},
Hosts: []string{"10.xx.xx.xx:60010"},
Username: "<username>",
Password: "<password>",
}
driver, err := sdk.NewUltipaDriver(config)
if err != nil {
log.Fatalln("Failed to connect to Ultipa:", err)
}
// Retrieves 3 User nodes from the graph 'g1'
requestConfig := &configuration.RequestConfig{Graph: "g1"}
response, _ := driver.Gql("MATCH (u:User) RETURN u LIMIT 3", requestConfig)
nodes, _, _ := response.Alias("u").AsNodes()
for _, node := range nodes {
jsonData, err := json.MarshalIndent(node, "", " ")
if err != nil {
fmt.Println("Error:", err)
continue
}
fmt.Println(string(jsonData))
}
}
{
"ID": "U4",
"UUID": 6557243256474697731,
"Schema": "User",
"Values": {
"Data": {
"name": "mochaeach"
}
}
}
{
"ID": "U2",
"UUID": 7926337543195328514,
"Schema": "User",
"Values": {
"Data": {
"name": "Brainy"
}
}
}
{
"ID": "U5",
"UUID": 14771808976798482436,
"Schema": "User",
"Values": {
"Data": {
"name": "lionbower"
}
}
}
查询边
在图中查询边:
package main
import (
"encoding/json"
"fmt"
"log"
"github.com/ultipa/ultipa-go-driver/v5/sdk"
"github.com/ultipa/ultipa-go-driver/v5/sdk/configuration"
)
func main() {
config := &configuration.UltipaConfig{
// URI example: Hosts: []string{"xxxx.us-east-1.cloud.ultipa.com:60010"},
Hosts: []string{"10.xx.xx.xx:60010"},
Username: "<username>",
Password: "<password>",
}
driver, err := sdk.NewUltipaDriver(config)
if err != nil {
log.Fatalln("Failed to connect to Ultipa:", err)
}
// Retrieves all incoming Follows edges of the user U2 from the graph 'g1'
requestConfig := &configuration.RequestConfig{Graph: "g1"}
response, _ := driver.Gql("MATCH (:User {_id: 'U2'})<-[e:Follows]-() RETURN e", requestConfig)
edges, _, _ := response.Alias("e").AsEdges()
for _, edge := range edges {
jsonData, err := json.MarshalIndent(edge, "", " ")
if err != nil {
fmt.Println("Error:", err)
continue
}
fmt.Println(string(jsonData))
}
}
{
"UUID": 1,
"FromUUID": 15276212135063977986,
"ToUUID": 7926337543195328514,
"From": "U1",
"To": "U2",
"Schema": "Follows",
"Values": {
"Data": {
"createdOn": "2024-01-05"
}
}
}
{
"UUID": 2,
"FromUUID": 6557243256474697731,
"ToUUID": 7926337543195328514,
"From": "U4",
"To": "U2",
"Schema": "Follows",
"Values": {
"Data": {
"createdOn": "2024-02-10"
}
}
}
查询路径
在图中查询路径:
package main
import (
"encoding/json"
"fmt"
"log"
"github.com/ultipa/ultipa-go-driver/v5/sdk"
"github.com/ultipa/ultipa-go-driver/v5/sdk/configuration"
)
func main() {
config := &configuration.UltipaConfig{
// URI example: Hosts: []string{"xxxx.us-east-1.cloud.ultipa.com:60010"},
Hosts: []string{"10.xx.xx.xx:60010"},
Username: "<username>",
Password: "<password>",
}
driver, err := sdk.NewUltipaDriver(config)
if err != nil {
log.Fatalln("Failed to connect to Ultipa:", err)
}
// Retrieves 1-step paths from user U1 in the graph 'g1'
requestConfig := &configuration.RequestConfig{Graph: "g1"}
response, _ := driver.Gql(`
MATCH p = (u)-[]-()
WHERE u._id = "U1"
RETURN p`, requestConfig)
graph, _ := response.Alias("p").AsGraph()
for _, path := range graph.GetPath() {
jsonData, err := json.MarshalIndent(path, "", " ")
if err != nil {
fmt.Println("Error:", err)
continue
}
fmt.Println(string(jsonData))
}
}
{
"NodeUUIDs": [
15276212135063977986,
7926337543195328514
],
"EdgeUUIDs": [
1
],
"Nodes": {
"15276212135063977986": {
"ID": "U1",
"UUID": 15276212135063977986,
"Schema": "User",
"Values": {
"Data": {
"name": "RowLock99"
}
}
},
"7926337543195328514": {
"ID": "U2",
"UUID": 7926337543195328514,
"Schema": "User",
"Values": {
"Data": {
"name": "Brainy"
}
}
}
},
"Edges": {
"1": {
"UUID": 1,
"FromUUID": 15276212135063977986,
"ToUUID": 7926337543195328514,
"From": "U1",
"To": "U2",
"Schema": "Follows",
"Values": {
"Data": {
"createdOn": "2024-01-05"
}
}
}
}
}
流式返回
为了高效处理大量的查询结果,避免将它们一次性加载到内存中,可以使用流式方法GqlStream()
和UqlStream()
,它们会以增量的形式返回结果。
方法 |
参数 | 返回值 |
---|---|---|
GqlStream() |
|
error |
UqlStream() |
|
error |
从一个大图中流式返回点:
package main
import (
"fmt"
"log"
"github.com/ultipa/ultipa-go-driver/v5/sdk"
"github.com/ultipa/ultipa-go-driver/v5/sdk/configuration"
sdkhttp "github.com/ultipa/ultipa-go-driver/v5/sdk/http" // rename to avoid conflict
)
func main() {
config := &configuration.UltipaConfig{
// URI example: Hosts: []string{"xxxx.us-east-1.cloud.ultipa.com:60010"},
Hosts: []string{"10.xx.xx.xx:60010"},
Username: "<username>",
Password: "<password>"
}
driver, err := sdk.NewUltipaDriver(config)
if err != nil {
log.Fatalln("Failed to connect to Ultipa:", err)
}
// Retrieves all account nodes from the graph 'amz'
requestConfig := &configuration.RequestConfig{Graph: "amz"}
var totalNodeCount int64 = 0
fmt.Println("Stream started.")
cb := func(response *sdkhttp.Response) error {
nodes, _, _ := response.Get(0).AsNodes()
chunkCount := int64(len(nodes))
totalNodeCount += chunkCount
for _, node := range nodes {
fmt.Println(node.GetID())
}
fmt.Println("Node count so far:", totalNodeCount)
return nil
}
err = driver.GqlStream("MATCH (n:account) RETURN n", cb, requestConfig)
if err != nil {
log.Fatalln("Stream error:", err)
}
fmt.Println("Stream ended.")
}
Stream started.
ULTIPA8000000000000426
ULTIPA8000000000000439
...
Node count so far: 1024
ULTIPA80000000000003FB
ULTIPA8000000000000431
...
Node count so far: 2048
ULTIPA800000000000041A
ULTIPA8000000000000417
...
...
...
ULTIPA8000000000000403
Node count so far: 96114145
Stream ended.