查询方法
连接到数据库之后,用户可使用驱动的gql()
或uql()
方法执行GQL或UQL语句来全方位操作数据库。
GQL(ISO标准图查询语言)和UQL(嬴图原生查询语言)都可以用来操作数据库。为了使用驱动,你无需精通GQL或UQL,但如果对其中任何一种语言有基本的认识,会很有帮助。了解更多,请阅读GQL快速入门、GQL文档或UQL文档。
方法 |
参数 | 返回值 |
---|---|---|
gql() |
|
Response |
uql() |
|
Response |
请求配置
RequestConfig
包含以下字段:
字段 |
类型 |
默认值 |
描述 |
---|---|---|---|
graph |
string | / | 使用的图名称;未指定时,使用UltipaConfig.defaultGraph 指定的图 |
timeout |
number | / | 请求超时阈值(单位:秒);此字段会覆盖UltipaConfig.timeout |
host |
string | / | 指定数据库集群中的一台服务器来执行请求 |
thread |
number | / | 请求的线程数 |
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
的设置。
创建一个图
在数据库中新建一个图:
import { UltipaDriver } from "@ultipa-graph/ultipa-driver";
import type { ULTIPA } from "@ultipa-graph/ultipa-driver/dist/types/index.js";
let sdkUsage = async () => {
const ultipaConfig: ULTIPA.UltipaConfig = {
hosts: ["10.xx.xx.xx:60010"],
username: "<username>",
password: "<password>"
};
const driver = new UltipaDriver(ultipaConfig);
// Creates a new open graph named 'g1'
let response = await driver.gql("CREATE GRAPH g1 ANY")
console.log(response.status?.message)
};
sdkUsage().catch(console.error);
SUCCESS
插入点和边
向图中插入点和边:
import { UltipaDriver } from "@ultipa-graph/ultipa-driver";
import type { ULTIPA } from "@ultipa-graph/ultipa-driver/dist/types/index.js";
async function sdkUsage() {
const ultipaConfig: ULTIPA.UltipaConfig = {
hosts: ["10.xx.xx.xx:60010"],
username: "<username>",
password: "<password>",
defaultGraph: "g1" // Sets the default graph to 'g1'
};
const driver = new UltipaDriver(ultipaConfig);
// Inserts nodes and edges into graph the 'g1'
let response = await 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)`);
console.log(response.status?.message);
}
sdkUsage().catch(console.error);
SUCCESS
更新点和边
更新图中一个点的属性值:
import { UltipaDriver } from "@ultipa-graph/ultipa-driver";
import type { ULTIPA } from "@ultipa-graph/ultipa-driver/dist/types/index.js";
import { RequestConfig } from "@ultipa-graph/ultipa-driver/dist/types/types.js";
async function sdkUsage() {
const ultipaConfig: ULTIPA.UltipaConfig = {
hosts: ["10.xx.xx.xx:60010"],
username: "<username>",
password: "<password>",
};
const driver = new UltipaDriver(ultipaConfig);
// Updates name of the user U1 in the graph 'g1'
const requestConfig: RequestConfig = { graph: "g1" };
let response = await driver.gql("MATCH (n:User {_id: 'U1'}) SET n.name = 'RowLock99' RETURN n", requestConfig);
const nodes = response.alias("n").asNodes();
for (const node of nodes) {
console.log(node);
}
};
sdkUsage().catch(console.error);
Node {
uuid: '15276212135063977986',
id: 'U1',
schema: 'User',
values: { name: 'RowLock99' }
}
删除点和边
从图中删除一条边:
import { UltipaDriver } from "@ultipa-graph/ultipa-driver";
import type { ULTIPA } from "@ultipa-graph/ultipa-driver/dist/types/index.js";
import { RequestConfig } from "@ultipa-graph/ultipa-driver/dist/types/types.js";
async function sdkUsage() {
const ultipaConfig: ULTIPA.UltipaConfig = {
hosts: ["10.xx.xx.xx:60010"],
username: "<username>",
password: "<password>",
};
const driver = new UltipaDriver(ultipaConfig);
// Deletes the edge between users U3 and U5 in the graph 'g1'
const requestConfig: RequestConfig = { graph: "g1" };
let response = await driver.gql("MATCH ({_id: 'U1'})-[e]-({_id: 'U5'}) DELETE e", requestConfig);
console.log(response.status?.message)
};
sdkUsage().catch(console.error);
SUCCESS
查询点
在图中查询点:
import { UltipaDriver } from "@ultipa-graph/ultipa-driver";
import type { ULTIPA } from "@ultipa-graph/ultipa-driver/dist/types/index.js";
import { RequestConfig } from "@ultipa-graph/ultipa-driver/dist/types/types.js";
let sdkUsage = async () => {
const ultipaConfig: ULTIPA.UltipaConfig = {
hosts: ["10.xx.xx.xx:60010"],
username: "<username>",
password: "<password>"
};
const driver = new UltipaDriver(ultipaConfig);
// Retrieves 3 User nodes from the graph 'g1'
const requestConfig: RequestConfig = { graph: "g1" };
let response = await driver.gql("MATCH (u:User) RETURN u LIMIT 3", requestConfig);
const nodes = response.alias("u").asNodes();
for (const node of nodes) {
console.log(node)
};
};
sdkUsage().catch(console.error);
Node {
uuid: '6557243256474697731',
id: 'U4',
schema: 'User',
values: { name: 'mochaeach' }
}
Node {
uuid: '7926337543195328514',
id: 'U2',
schema: 'User',
values: { name: 'Brainy' }
}
Node {
uuid: '14771808976798482436',
id: 'U5',
schema: 'User',
values: { name: 'lionbower' }
}
查询边
在图中查询边:
import { UltipaDriver } from "@ultipa-graph/ultipa-driver";
import type { ULTIPA } from "@ultipa-graph/ultipa-driver/dist/types/index.js";
import { RequestConfig } from "@ultipa-graph/ultipa-driver/dist/types/types.js";
let sdkUsage = async () => {
const ultipaConfig: ULTIPA.UltipaConfig = {
hosts: ["10.xx.xx.xx:60010"],
username: "<username>",
password: "<password>"
};
const driver = new UltipaDriver(ultipaConfig);
// Retrieves all incoming Follows edges of the user U2 from the graph 'g1'
const requestConfig: RequestConfig = { graph: "g1" };
let response = await driver.gql("MATCH (:User {_id: 'U2'})<-[e:Follows]-() RETURN e", requestConfig);
const edges = response.alias("e").asEdges();
for (const edge of edges) {
console.log(edge)
};
};
sdkUsage().catch(console.error);
Edge {
uuid: '1',
fromUuid: '15276212135063977986',
toUuid: '7926337543195328514',
from: 'U1',
to: 'U2',
schema: 'Follows',
values: { createdOn: '2024-01-05' }
}
Edge {
uuid: '2',
fromUuid: '6557243256474697731',
toUuid: '7926337543195328514',
from: 'U4',
to: 'U2',
schema: 'Follows',
values: { createdOn: '2024-02-10' }
}
查询路径
在图中查询路径:
import { UltipaDriver } from "@ultipa-graph/ultipa-driver";
import type { ULTIPA } from "@ultipa-graph/ultipa-driver/dist/types/index.js";
import { RequestConfig } from "@ultipa-graph/ultipa-driver/dist/types/types.js";
let sdkUsage = async () => {
const ultipaConfig: ULTIPA.UltipaConfig = {
hosts: ["10.xx.xx.xx:60010"],
username: "<username>",
password: "<password>"
};
const driver = new UltipaDriver(ultipaConfig);
// Retrieves 1-step paths from user U1 in the graph 'g1'
const requestConfig: RequestConfig = { graph: "g1" };
let response = await driver.gql(`
MATCH p = (u)-[]-()
WHERE u._id = "U1"
RETURN p`, requestConfig);
const graph = response.alias("p").asGraph();
for (const path of graph.paths ?? []) {
console.log(path)
};
};
sdkUsage().catch(console.error);
Path {
nodeUuids: [ '15276212135063977986', '7926337543195328514' ],
edgeUuids: [ '1' ],
nodes: Map(2) {
'15276212135063977986' => Node {
uuid: '15276212135063977986',
id: 'U1',
schema: 'User',
values: [Object]
},
'7926337543195328514' => Node {
uuid: '7926337543195328514',
id: 'U2',
schema: 'User',
values: [Object]
}
},
edges: Map(1) {
'1' => Edge {
uuid: '1',
fromUuid: '15276212135063977986',
toUuid: '7926337543195328514',
from: 'U1',
to: 'U2',
schema: 'Follows',
values: [Object]
}
}
}
流式返回
为了高效处理大量的查询结果,避免将它们一次性加载到内存中,可以使用流式方法gqlStream()
和uqlStream()
,它们会以增量的形式返回结果。
方法 |
参数 | 返回值 |
---|---|---|
gqlStream() |
|
void |
uqlStream() |
|
void |
从一个大图中流式返回点:
import { UltipaDriver } from "@ultipa-graph/ultipa-driver";
import type { ULTIPA } from "@ultipa-graph/ultipa-driver/dist/types/index.js";
import { RequestConfig } from "@ultipa-graph/ultipa-driver/dist/types/types.js";
let sdkUsage = async () => {
const ultipaConfig: ULTIPA.UltipaConfig = {
hosts: ["10.xx.xx.xx:60010"],
username: "<username>",
password: "<password>"
};
const driver = new UltipaDriver(ultipaConfig);
// Retrieves all Account nodes from the graph 'amz'
const requestConfig: RequestConfig = { graph: "amz" };
let count = 0;
driver.gqlStream(
"MATCH (n:Account) RETURN n",
{
onStart: () => {
console.log("Stream started.");
},
onData: async (res) => {
const nodes = res.alias("n")?.asNodes();
if (nodes) {
for (const node of nodes) {
console.log(node.id)
}
}
count += nodes?.length || 0;
console.log("Node count so far:", count);
},
onEnd: () => {
console.log("Stream ended.");
},
onError: (err) => {
console.error(err);
},
},
requestConfig
);
};
sdkUsage().catch(console.error);
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.