Overview
An Ultipa graph database may contain multiple graphsets, each containing its own graph structure (schemas and properties), metadata (nodes and edges), various indexes, processes, jobs, and more. The terms "graphset" and "graph" are often used interchangeably.
Showing Graphsets
To retrieve information about graphsets in the database:
// Shows all graphsets
show().graph()
//Shows all graphsets with additional details (total_nodes, total_edges)
show().graph().more()
// Shows the specified graphset
show().graph("myGraph")
// Shows the specified graphset with additional details (total_nodes, total_edges)
show().graph("myGraph").more()
The information about graphsets is organized into tables _graph
, _graph_shard_1
, _graph_shard_2
, and so on:
- The
_graph
table contains all graphsets in the database. - Each
_graph_shard_<N>
table contains the graphsets that have data stored in the shard with id<N>
.
Each table includes fields that provide essential details about each graphset:
Field |
Description |
---|---|
id |
The unique id of the graphset. |
name |
The unique name assigned to the graphset. |
description |
The description given to the graphset. |
status |
The current state of the graphset, which can be NORMAL , LOADING_SNAPSHOT , CREATING , DROPPING , or SCALING . |
shards |
The ids of shards where the graph data is distributed. |
partition_by |
The function that computes the hash value for the sharding key, which is essential for sharding the graph data. |
meta_version |
The version number utilized by meta servers to synchronize DDL (Data Definition Language) operations on the graphset with shard servers. |
total_nodes |
The total count of nodes in the graphset. Only available in _graph when the more() method is used. |
total_edges |
The total count of edges in the graphset. Only available in _graph when the more() method is used. |
Creating Graphsets
You can create one or more graphsets using a single create()
statement. Each graphset is specified by chaining together the three methods graph().shards().partitionByHash()
.
create()
.graph("<name>", "<desc?>").shards(<shardList>).partitionByHash(<hashFunc>, <shardKey?>)
.graph("<name>", "<desc?>").shards(<shardList>).partitionByHash(<hashFunc>, <shardKey?>)
...
Method | Param | Description |
---|---|---|
graph() |
<graphName> |
The unique name of the graphset. Naming conventions are:
|
<graphDesc?> |
Optional. Description of the graphset. | |
shards() |
<shardList> |
Non-empty list of ids of shards where the graph data will be stored. |
partitionByHash() |
<hashFunc> |
The function (Crc32 , Crc64WE , Crc64XZ , or CityHash64 ) that computes the hash value for the sharding key, which is essential for sharding the graph data. Note that this function cannot be modified after the graphset is created. For more information, please refer to the Crc and CityHash functions. |
<shardKey?> |
Optional. The node property used as the sharding key. Only _id is supported now. |
To create a graphset named myGraph
and distribute its data to shards 1
, 2
and 3
using the CityHash64
function based on the _id
of nodes:
create().graph("myGraph").shards([1,2,3]).partitionByHash(CityHash64, _id)
To create two graphsets:
create()
.graph("myGraph_1").shards([1,2,3]).partitionByHash(CityHash64)
.graph("myGraph_2").shards([2]).partitionByHash(Crc32)
Altering Name and Description
You can modify name and description of a graphset using the alter().graph().set()
statement.
To alter both name and description of the graphset myGraph
alter().graph("myGraph").set({name: "superGraph", description: "Graph used for transactions"})
To alter name of the graphset myGraph
:
alter().graph("myGraph").set({name: "superGraph"})
To alter description of the graphset myGraph
:
alter().graph("myGraph").set({description: "Graph used for transactions"})
To remove description of the graphset myGraph
:
alter().graph("myGraph").set({description: ""})
Migrating Graphset Data
As data in a graphset is distributed across shards, data migration may become necessary sometime — whether to more shards when existing ones become overloaded, or to distribute data across additional geographical locations. Conversely, migrating to fewer shards can free up underutilized resources, reduce costs, and simplify management. You can perform data migration for a graphset using the alter().graph().shards().partitionConfig()
statement.
alter().graph("<graphName>").shards(<shardList>).partitionConfig({strategy: "<rsStrat>"})
Method |
Param |
Description | Optional |
---|---|---|---|
graph() |
<graphName> |
Specifies the graphset. | No |
shards() |
<shardList> |
Non-empty list of ids of shards where the graph data will be stored. This must differ from the current shard list and align with the strategy set in partitionConfig() . |
No |
partitionConfig() |
Config map | Specifies the migration strategy , which can be set as follows:
balance is used by default. |
Yes |
Assuming the graphset myGraph
is currently distributed across shards 1
and 2
. To migrate myGraph
from shards [1,2]
to [1,4,5]
:
alter().graph('myGraph').shards([1,4,5]).partitionConfig({strategy: "balance"})
To migrate myGraph
from shards [1,2]
to [3]
:
alter().graph('myGraph').shards([3]).partitionConfig({strategy: "balance"})
To quickly migrate myGraph
from shards [1,2]
to [1,2,4]
:
alter().graph('myGraph').shards([1,2,4]).partitionConfig({strategy: "quickly_expand"})
To quickly migrate myGraph
from shards [1,2]
to [1]
:
alter().graph('myGraph').shards([1]).partitionConfig({strategy: "quickly_shrink"})
Dropping Graphsets
You can drop one or more graphsets using a single drop()
statement. Each graphset is specified by chaining a graph()
method. Dropping a graphset deleting the entire graphset from the database.
To drop the graphset myGraph
:
drop().graph("myGraph")
To drop two graphsets:
drop().graph("myGraph_1").graph("myGraph_2")
By default, a graphset cannot be deleted if it still has existing HDC projections. To bypass this restriction and force the deletion, use the force()
method:
drop().graph("myGraph_1").graph("myGraph_2").force()
Truncating a Graphset
You can truncate a graphset using the truncate().graph()
statement. Truncating a graphset only deletes nodes and edges within it, while retaining the graphset itself and its structure (schemas and properties).
You can specify to truncate the nodes or edges only by chaining a nodes()
or edges()
method. However, note that the deletion of a node leads to the removal of all edges that are connected to it.
// Truncates the graphset 'myGraph' (all nodes and edges will be deleted)
truncate().graph("myGraph")
// Truncates all @user nodes (edges attached to them will be deleted too)
truncate().graph("myGraph").nodes(@user)
// Truncates all nodes (all edges will be deleted too)
truncate().graph("myGraph").nodes("*")
// Truncates all @link edges
truncate().graph("myGraph").edges(@link)
// Truncates all edges
truncate().graph("myGraph").edges("*")
Compacting a Graphset
You can compact a graphset using the compact().graph()
statement. Compacting a graphset clears its invalid and redundant data from the server disk but does not make any changes to the valid data. The compact operation runs as a job, you may run show().job(<id?>)
afterward to verify its completion.
To compact the graphset myGraph
:
compact().graph("myGraph")
Data manipulation operations can generate redundant data, such as the old records retained after being updated or deleted. It's suggested to regularly compact graphsets to reclaim storage space and improve query efficiency.