The code in this document is written in java
, but its style is very similar to gremlin(groovy)
. The user only needs to replace the variable declaration in the code with def
or remove it directly, You can convert java
code into groovy
; in addition, each line of statement can be without a semicolon at the end, groovy
considers a line to be a statement. The gremlin(groovy)
written by the user in HugeGraph-Studio
can refer to the java
code in this document, and some examples will be given below.
HugeGraph-Client is the general entry for operating graph. Users must first create a HugeGraph-Client object and establish a connection (pseudo connection) with HugeGraph-Server before they can obtain the operation entry objects of schema, graph and gremlin.
Currently, HugeGraph-Client only allows connections to existing graphs on the server, and cannot create custom graphs. Its creation method is as follows:
// HugeGraphServer address: "http://localhost:8080" // Graph Name: "hugegraph" HugeClient hugeClient = HugeClient.builder("http://localhost:8080", "hugegraph") .configTimeout(20) // 20s timeout .configUser("**", "**") // enable auth .build();
If the above process of creating HugeClient fails, an exception will be thrown, and the user needs to use try-catch. If successful, continue to get schema, graph and gremlin manager.
When operating through gremlin
in HugeGraph-Hubble
(or HugeGraph-Studio
), HugeClient
is not required and can be ignored.
SchemaManager is used to manage four kinds of schema in HugeGraph, namely PropertyKey (property type), VertexLabel (vertex type), EdgeLabel (edge type) and IndexLabel (index label). A SchemaManager object can be created for schema information definition.
The user can obtain the SchemaManager object using the following methods:
SchemaManager schema = hugeClient.schema()
Create a schema
object via gremlin
in HugeGraph-Hubble
:
schema = graph.schema()
The definition process of the 4 kinds of schema is described below.
PropertyKey is used to standardize the property constraints of vertices and edges, and properties of properties are not currently supported.
The constraint information that PropertyKey allows to define includes: name, datatype, cardinality, and userdata, which are introduced one by one below.
interface | param | must set |
---|---|---|
propertyKey(String name) | name | y |
interface | Java Class |
---|---|
asText() | String |
asInt() | Integer |
asDate() | Date |
asUuid() | UUID |
asBoolean() | Boolean |
asByte() | Byte |
asBlob() | Byte[] |
asDouble() | Double |
asFloat() | Float |
asLong() | Long |
interface | cardinality | description |
---|---|---|
valueSingle() | single | single value |
valueList() | list | multi-values that allow duplicate value |
valueSet() | set | multi-values that not allow duplicate value |
interface | description |
---|---|
userdata(String key, Object value) | The same key, the latter will cover the former |
schema.propertyKey("name").asText().valueSet().ifNotExist().create()
The syntax of creating the above PropertyKey
object through gremlin
in HugeGraph-Hubble
is exactly the same. If the user does not define the schema
variable, it should be written like this:
graph.schema().propertyKey("name").asText().valueSet().ifNotExist().create()
In the following examples, the syntax of gremlin
and java
is exactly the same, so we won't repeat them.
schema.propertyKey("name").remove()
// Get PropertyKey schema.getPropertyKey("name") // Get attributes of PropertyKey schema.getPropertyKey("name").cardinality() schema.getPropertyKey("name").dataType() schema.getPropertyKey("name").name() schema.getPropertyKey("name").userdata()
VertexLabel is used to define the vertex type and describe the constraint information of the vertex.
The constraint information that VertexLabel allows to define include: name, idStrategy, properties, primaryKeys and nullableKeys, which are introduced one by one below.
interface | param | must set |
---|---|---|
vertexLabel(String name) | name | y |
interface | idStrategy | description |
---|---|---|
useAutomaticId | AUTOMATIC | generate id automatically by Snowflake algorithm |
useCustomizeStringId | CUSTOMIZE_STRING | passed id by user, must be string type |
useCustomizeNumberId | CUSTOMIZE_NUMBER | passed id by user, must be number type |
usePrimaryKeyId | PRIMARY_KEY | choose some important prop as primary key to splice id |
interface | description |
---|---|
properties(String... properties) | allow to pass multi properties |
interface | description |
---|---|
primaryKeys(String... keys) | allow to choose multi prop as primaryKeys |
Note that the selection of the ID strategy and the setting of primaryKeys have some mutual constraints, which cannot be called at will. The constraints are shown in the following table:
useAutomaticId | useCustomizeStringId | useCustomizeNumberId | usePrimaryKeyId | |
---|---|---|---|---|
unset primaryKeys | AUTOMATIC | CUSTOMIZE_STRING | CUSTOMIZE_NUMBER | ERROR |
set primaryKeys | ERROR | ERROR | ERROR | PRIMARY_KEY |
interface | description |
---|---|
nullableKeys(String... properties) | allow to pass multi props |
Note: primaryKeys and nullableKeys cannot intersect, because a property cannot be both primary and nullable.
g.V().hasLabel('person'), g.E().has('label', 'person')
query, but the performance will be slower when inserting data, and it will take up more storage space. This defaults to true.interface | description |
---|---|
enableLabelIndex(boolean enable) | Whether to create a label index |
interface | description |
---|---|
userdata(String key, Object value) | The same key, the latter will cover the former |
// Use Automatic Id strategy schema.vertexLabel("person").properties("name", "age").ifNotExist().create(); schema.vertexLabel("person").useAutomaticId().properties("name", "age").ifNotExist().create(); // Use Customize_String Id strategy schema.vertexLabel("person").useCustomizeStringId().properties("name", "age").ifNotExist().create(); // Use Customize_Number Id strategy schema.vertexLabel("person").useCustomizeNumberId().properties("name", "age").ifNotExist().create(); // Use PrimaryKey Id strategy schema.vertexLabel("person").properties("name", "age").primaryKeys("name").ifNotExist().create(); schema.vertexLabel("person").usePrimaryKeyId().properties("name", "age").primaryKeys("name").ifNotExist().create();
VertexLabel can append constraints, but only properties and nullableKeys, and the appended properties must also be added to the nullableKeys collection.
schema.vertexLabel("person").properties("price").nullableKeys("price").append();
schema.vertexLabel("person").remove();
// Get VertexLabel schema.getVertexLabel("name") // Get attributes of VertexLabel schema.getVertexLabel("person").idStrategy() schema.getVertexLabel("person").primaryKeys() schema.getVertexLabel("person").name() schema.getVertexLabel("person").properties() schema.getVertexLabel("person").nullableKeys() schema.getVertexLabel("person").userdata()
EdgeLabel is used to define the edge type and describe the constraint information of the edge.
The constraint information that EdgeLabel allows to define include: name, sourceLabel, targetLabel, frequency, properties, sortKeys and nullableKeys, which are introduced one by one below.
interface | param | must set |
---|---|---|
edgeLabel(String name) | name | y |
sourceLabel: The name of the source vertex type of the edge link, only one is allowed;
targetLabel: The name of the target vertex type of the edge link, only one is allowed;
interface | param | must set |
---|---|---|
sourceLabel(String label) | label | y |
targetLabel(String label) | label | y |
interface | frequency | description |
---|---|---|
singleTime() | single | a relationship can only occur once |
multiTimes() | multiple | a relationship can occur many times |
interface | description |
---|---|
properties(String... properties) | allow to pass multi props |
interface | description |
---|---|
sortKeys(String... keys) | allow to choose multi prop as sortKeys |
Note: sortKeys and nullableKeys also cannot intersect.
enableLabelIndex: It is consistent with the concept of enableLabelIndex in the vertex.
userdata: Users can add some constraints or additional information by themselves, and then check whether the incoming properties meet the constraints, or extract additional information when necessary.
interface | description |
---|---|
userdata(String key, Object value) | The same key, the latter will cover the former |
schema.edgeLabel("knows").link("person", "person").properties("date").ifNotExist().create(); schema.edgeLabel("created").multiTimes().link("person", "software").properties("date").sortKeys("date").ifNotExist().create();
schema.edgeLabel("knows").properties("price").nullableKeys("price").append();
schema.edgeLabel("knows").remove();
// Get EdgeLabel schema.getEdgeLabel("knows") // Get attributes of EdgeLabel schema.getEdgeLabel("knows").frequency() schema.getEdgeLabel("knows").sourceLabel() schema.getEdgeLabel("knows").targetLabel() schema.getEdgeLabel("knows").sortKeys() schema.getEdgeLabel("knows").name() schema.getEdgeLabel("knows").properties() schema.getEdgeLabel("knows").nullableKeys() schema.getEdgeLabel("knows").userdata()
IndexLabel is used to define the index type and describe the constraint information of the index, mainly for the convenience of query.
The constraint information that IndexLabel allows to define include: name, baseType, baseValue, indexFields, indexType, which are introduced one by one below.
interface | param | must set |
---|---|---|
indexLabel(String name) | name | y |
baseType: Indicates whether to index VertexLabel or EdgeLabel, used in conjunction with the baseValue below.
baseValue: Specifies the name of the VertexLabel or EdgeLabel to be indexed.
interface | param | description |
---|---|---|
onV(String baseValue) | baseValue | build index for VertexLabel: ‘baseValue’ |
onE(String baseValue) | baseValue | build index for EdgeLabel: ‘baseValue’ |
interface | param | description |
---|---|---|
by(String... fields) | files | allow to build index for multi fields for secondary index |
g.V().has("city", "Beijing")
to query all the vertices with “city attribute value is Beijing”g.V().has("city", "Beijing").has('street', 'Zhongguancun street ')
to query all vertices of “city property value is Beijing and street property value is ZhongGuanCun”, or g.V().has("city", "Beijing")
to query all vertices of “city property value is Beijing”.The query of Secondary Index is based on the query condition of “yes” or “equal”, and does not support “partial matching”.
g.V().has("age", P.gt(18))
to query the vertices with “age property value greater than 18” . In addition to P.gt()
, also supports P.gte()
, P.lte()
, P.lt()
, P.eq()
, P.between()
, P.inside()
and P.outside()
etc.g.V().has("address", Text.contains('building')
to query all vertices whose “address property contains a ‘building’”The query of the Search Index is based on the query condition of “is” or “contains”.
g.V().has("city", "Beijing").has ("age", P.between(18, 30))
Query “city property is Beijing and all vertices whose age is greater than or equal to 18 and less than 30”.Shard Index can have any number or date property, but at most one range search condition can be provided when querying, and the prefix properties of the Shard Search conditions must be “equals”.
interface | indexType | description |
---|---|---|
secondary() | Secondary | support prefix search |
range() | Range | support range(numeric or date type) search |
search() | Search | support full text search |
shard() | Shard | support prefix + range(numeric or date type) search |
unique() | Unique | support unique props value, not support search |
schema.indexLabel("personByAge").onV("person").by("age").range().ifNotExist().create(); schema.indexLabel("createdByDate").onE("created").by("date").secondary().ifNotExist().create(); schema.indexLabel("personByLived").onE("person").by("lived").search().ifNotExist().create(); schema.indexLabel("personByCityAndAge").onV("person").by("city", "age").shard().ifNotExist().create(); schema.indexLabel("personById").onV("person").by("id").unique().ifNotExist().create();
schema.indexLabel("personByAge").remove()
// Get IndexLabel schema.getIndexLabel("personByAge") // Get attributes of IndexLabel schema.getIndexLabel("personByAge").baseType() schema.getIndexLabel("personByAge").baseValue() schema.getIndexLabel("personByAge").indexFields() schema.getIndexLabel("personByAge").indexType() schema.getIndexLabel("personByAge").name()
Vertices are the most basic elements of a graph, and there can be many vertices in a graph. Here is an example of adding vertices:
Vertex marko = graph.addVertex(T.label, "person", "name", "marko", "age", 29); Vertex lop = graph.addVertex(T.label, "software", "name", "lop", "lang", "java", "price", 328);
key1 -> val1, key2 -> val2 ...
, and the order between key-value pairs is free .T.label -> "val"
, which is used to define the category of the vertex, so that the program can obtain the schema definition of the VertexLabel from the cache or backend, and then do subsequent constraint checks. The label in the example is defined as person.AUTOMATIC
, users are not allowed to pass in id key-value pairs.CUSTOMIZE_STRING
, the user needs to pass in the value of the id of the String type. The key-value pair is like: "T.id", "123456"
.CUSTOMIZE_NUMBER
, the user needs to pass in the value of the id of the Number type. The key-value pair is like: "T.id", 123456
.PRIMARY_KEY
, the parameters must also contain the name and value of the properties corresponding to the primaryKeys
, if not set an exception will be thrown. For example, the primaryKeys
of person
is name
, in the example, the value of name
is set to marko
.addVertex
method, the vertices are inserted into the backend storage system immediately.After added vertices, edges are also needed to form a complete graph. Here is an example of adding edges:
Edge knows1 = marko.addEdge("knows", vadas, "city", "Beijing");
addEdge()
of the (source) vertex is to add an edge(relationship) between itself and another vertex. The first parameter of the function is the label of the edge, and the second parameter is the target vertex. The position and order of these two parameters are fixed. The subsequent parameters are the order of key1 -> val1, key2 -> val2 ...
, set the properties of the edge, and the key-value pair order is free.Note: When frequency is multiple, the value of the property type corresponding to sortKeys must be set.
Simple examples can reference HugeGraph-Client