We’re overhauling Dgraph’s docs to make them clearer and more approachable. If you notice any issues during this transition or have suggestions, please let us know.
Here is an example of Dgraph types schema:
The schema contains information about predicate types and node types.
A predicate is the smallest piece of information about an object. A predicate can hold a literal value or a relation to another entity:
name
and
predicate value is the string “Alice”.knows
with the
node representing Alice. The value of this predicate would be the
UID of the node representing Bob. In that case,
knows
is a relationship.Dgraph maintains a list of all predicates names and their type in the Dgraph types schema.
The Dgraph cluster schema mode defines if the Dgraph types must be declared before allowing mutations or not:
strict
mode, you must declare the predicates
(Update Dgraph types ) before you can run a
mutation using those predicates.flexible
mode (which is the default behavior), you can run a mutation
without declaring the predicate in the DQL Schema.When you deploy a GraphQL API schema, Dgraph generates all the underlying Dgraph types. Refer to GraphQL and DQL schemas for use cases using both approaches.
For example, you can run the following mutation (using the RDF notation):
In strict
mode, the mutation returns an error if the predicates aren’t present
in the Dgraph types schema.
In flexible
mode, Dgraph executes the mutation and adds the predicates
character_name
and has_for_child
to the Dgraph types.
All predicate types used in a Dgraph cluster are declared in the Dgraph schema.
The Dgraph types schema is the way to specify predicates types and cardinality (if it’s a list or not), to instruct Dgraph how to index predicates, and to declare if Dgraph needs to maintain different languages for a string predicate.
A predicate type is either created
by altering the Dgraph types schema (See Update Dgraph types ) or
during a mutation, if the Dgraph Cluster schema mode is flexible
and the
predicate used isn’t yet declared.
If a predicate type isn’t declared in the schema, then the type is inferred from the first mutation and added to the schema.
If the mutation is using RDF format with an RDF type, Dgraph uses this information to infer the predicate type.
If no type can be inferred, the predicate type is set to default
.
A predicate can hold a literal value (Scalar type) or a relation to another entity (UID type).
For all triples with a predicate of scalar types the object is a literal.
Dgraph Type | Go type |
---|---|
default | string |
int | int64 |
float | float |
string | string |
bool | bool |
dateTime | time.Time (RFC3339 format [Optional timezone] eg: 2006-01-02T15:04:05.999999999+10:00 or 2006-01-02T15:04:05.999999999) |
geo | go-geom |
password | string (encrypted) |
Dgraph supports date and time formats for dateTime
scalar type only if they
are RFC 3339 compatible which is different from ISO 8601(as defined in the RDF
spec). You should convert your values to RFC 3339 format before sending them
to Dgraph.
The float32vector
type denotes a vector of floating point numbers, i.e an
ordered array of float32. A node type can contain more than one vector
predicate.
Vectors are normally used to store embeddings obtained from other information
through an ML model. When a float32vector
is indexed,
the DQL similar_to
function can be
used for similarity search.
The uid
type denotes a relationship. Internally each node is identified by
it’s UID which is a uint64
.
Any alphanumeric combination of a predicate name is permitted. Dgraph also supports Internationalized Resource Identifiers (IRIs). You can read more in Predicates i18n.
You can’t define type names starting with dgraph.
, it’s reserved as the
namespace for Dgraph’s internal types/predicates. For example, defining
dgraph.Student
as a type is invalid.
Following characters are accepted if prefixed/suffixed with alphanumeric characters.
You aren’t restricted to use @ suffix, but the suffix character gets ignored.
The special characters below aren’t accepted.
Dgraph supports Internationalized Resource Identifiers (IRIs) for predicate names and values.
If your predicate is a URI or has language-specific characters, then enclose it
with angle brackets <>
when executing the schema mutation.
Schema syntax:
This syntax allows for internationalized predicate names, but full-text indexing
still defaults to English. To use the right tokenizer for your language, you
need to use the @lang
directive and enter values using your language tag.
Schema:
Mutation:
Query:
The unique constraint enables us to guarantee that all values of a predicate are distinct. To implement the @unique directive for a predicate, you should define it in the schema and create an index on the predicate based on its type. If a user doesn’t add the proper index to the predicate, then Dgraph returns an error.
Dgraph automatically includes the @upsert directive for the predicate. To enforce this uniqueness constraint, a predicate must have an index, as explained below. Currently, we only support the @unique directive on newly created predicates with the data types string and integer.
Data Type | Index |
---|---|
string | hash, exact |
int | int |
This is how you define the unique directive for a predicate.
To use upsert operations on a predicate, specify the @upsert
directive in the schema.
When committing transactions involving predicates with the @upsert
directive,
Dgraph checks index keys for conflicts, helping to enforce uniqueness
constraints when running concurrent upserts.
This is how you specify the upsert directive for a predicate.
The NoConflict directive prevents conflict detection at the predicate level. This is an experimental feature and not a recommended directive but exists to help avoid conflicts for predicates that don’t have high correctness requirements. This can cause data loss, especially when used for predicates with count index.
This is how you specify the @noconflict
directive for a predicate.
As well as implying a schema type for a first mutation, an RDF type can override a schema type for storage. Dgraph supports a number of RDF types.
If a predicate has a schema type and a mutation has an RDF type with a different underlying Dgraph type, the convertibility to schema type is checked, and an error is thrown if incompatible, but the value is stored in the RDF type’s corresponding Dgraph type. Query results are always returned in schema type.
For example, if no schema is set for the age
predicate. Given the mutation
Dgraph:
int
, as implied by the first triple,"13"
to int
on storage,"14"
can be converted to int
, but stores as string
,"14.5"
can’t be
converted to int
.A password for an entity is set with setting the schema for the attribute to be
of type password
. Passwords can’t be queried directly, only checked for a
match using the checkpwd
function. The passwords are encrypted using
bcrypt
.
For example: to set a password, first set schema, then the password:
to check a password:
output:
You can also use alias with password type.
output:
The schema is also used to set predicates indexes, which are required to apply filtering functions in DQL queries.
Node types are declared along with predicate types in the Dgraph types schema.
Node types are optional.
Node type declares the list of predicates that could be present in a Node of this type. Node type are defined using the following syntax:
All predicates used in a type must be defined in the Dgraph types schema itself.
Reverse predicates can also be included inside a type definition. For example,
the following schema, declares that a node of type Child may have a ~children
inverse relationship.
A node is given a type by setting the dgraph.type
predicate value to the type
name.
A node may be given many types, dgraph.type
is an array of strings.
DQL types are only declarative and aren’t enforced by Dgraph. In DQL, you can
always add node without a dgraph.type
predicate.
Here’s an example of mutation to set the types of a node:
Node types are optional, but there are two use cases where actually knowing the list of potential predicates of a node is necessary:
delete { <uid> * * . }
mutation.The Dgraph node types are used in those 2 use cases: when executing the
delete all predicates
mutation or the expand all
query, Dgraph checks if the
node has a dgraph.type
predicate. If so, the engine is using the declared type
to find the list of predicates and apply the delete or the expand on all of
them.
When nodes have a type (i.e have a dgraph.type
predicate), then you can use
the function type()
in queries.
delete { <uid> * * . }
only deletes the
predicates declared in the type. You may have added other predicates by running
DQL mutation on this node: the node may still exist after the operation if it
holds predicates not declared in the node type.
The following pages are the language reference for DQL.
They contain examples that you can run interactively using a database of 21 million triples about movies and actors.
The queries are executed on an instance of Dgraph running at https://play.dgraph.io/.
The example movie database uses the following schema:
We’re overhauling Dgraph’s docs to make them clearer and more approachable. If you notice any issues during this transition or have suggestions, please let us know.
Here is an example of Dgraph types schema:
The schema contains information about predicate types and node types.
A predicate is the smallest piece of information about an object. A predicate can hold a literal value or a relation to another entity:
name
and
predicate value is the string “Alice”.knows
with the
node representing Alice. The value of this predicate would be the
UID of the node representing Bob. In that case,
knows
is a relationship.Dgraph maintains a list of all predicates names and their type in the Dgraph types schema.
The Dgraph cluster schema mode defines if the Dgraph types must be declared before allowing mutations or not:
strict
mode, you must declare the predicates
(Update Dgraph types ) before you can run a
mutation using those predicates.flexible
mode (which is the default behavior), you can run a mutation
without declaring the predicate in the DQL Schema.When you deploy a GraphQL API schema, Dgraph generates all the underlying Dgraph types. Refer to GraphQL and DQL schemas for use cases using both approaches.
For example, you can run the following mutation (using the RDF notation):
In strict
mode, the mutation returns an error if the predicates aren’t present
in the Dgraph types schema.
In flexible
mode, Dgraph executes the mutation and adds the predicates
character_name
and has_for_child
to the Dgraph types.
All predicate types used in a Dgraph cluster are declared in the Dgraph schema.
The Dgraph types schema is the way to specify predicates types and cardinality (if it’s a list or not), to instruct Dgraph how to index predicates, and to declare if Dgraph needs to maintain different languages for a string predicate.
A predicate type is either created
by altering the Dgraph types schema (See Update Dgraph types ) or
during a mutation, if the Dgraph Cluster schema mode is flexible
and the
predicate used isn’t yet declared.
If a predicate type isn’t declared in the schema, then the type is inferred from the first mutation and added to the schema.
If the mutation is using RDF format with an RDF type, Dgraph uses this information to infer the predicate type.
If no type can be inferred, the predicate type is set to default
.
A predicate can hold a literal value (Scalar type) or a relation to another entity (UID type).
For all triples with a predicate of scalar types the object is a literal.
Dgraph Type | Go type |
---|---|
default | string |
int | int64 |
float | float |
string | string |
bool | bool |
dateTime | time.Time (RFC3339 format [Optional timezone] eg: 2006-01-02T15:04:05.999999999+10:00 or 2006-01-02T15:04:05.999999999) |
geo | go-geom |
password | string (encrypted) |
Dgraph supports date and time formats for dateTime
scalar type only if they
are RFC 3339 compatible which is different from ISO 8601(as defined in the RDF
spec). You should convert your values to RFC 3339 format before sending them
to Dgraph.
The float32vector
type denotes a vector of floating point numbers, i.e an
ordered array of float32. A node type can contain more than one vector
predicate.
Vectors are normally used to store embeddings obtained from other information
through an ML model. When a float32vector
is indexed,
the DQL similar_to
function can be
used for similarity search.
The uid
type denotes a relationship. Internally each node is identified by
it’s UID which is a uint64
.
Any alphanumeric combination of a predicate name is permitted. Dgraph also supports Internationalized Resource Identifiers (IRIs). You can read more in Predicates i18n.
You can’t define type names starting with dgraph.
, it’s reserved as the
namespace for Dgraph’s internal types/predicates. For example, defining
dgraph.Student
as a type is invalid.
Following characters are accepted if prefixed/suffixed with alphanumeric characters.
You aren’t restricted to use @ suffix, but the suffix character gets ignored.
The special characters below aren’t accepted.
Dgraph supports Internationalized Resource Identifiers (IRIs) for predicate names and values.
If your predicate is a URI or has language-specific characters, then enclose it
with angle brackets <>
when executing the schema mutation.
Schema syntax:
This syntax allows for internationalized predicate names, but full-text indexing
still defaults to English. To use the right tokenizer for your language, you
need to use the @lang
directive and enter values using your language tag.
Schema:
Mutation:
Query:
The unique constraint enables us to guarantee that all values of a predicate are distinct. To implement the @unique directive for a predicate, you should define it in the schema and create an index on the predicate based on its type. If a user doesn’t add the proper index to the predicate, then Dgraph returns an error.
Dgraph automatically includes the @upsert directive for the predicate. To enforce this uniqueness constraint, a predicate must have an index, as explained below. Currently, we only support the @unique directive on newly created predicates with the data types string and integer.
Data Type | Index |
---|---|
string | hash, exact |
int | int |
This is how you define the unique directive for a predicate.
To use upsert operations on a predicate, specify the @upsert
directive in the schema.
When committing transactions involving predicates with the @upsert
directive,
Dgraph checks index keys for conflicts, helping to enforce uniqueness
constraints when running concurrent upserts.
This is how you specify the upsert directive for a predicate.
The NoConflict directive prevents conflict detection at the predicate level. This is an experimental feature and not a recommended directive but exists to help avoid conflicts for predicates that don’t have high correctness requirements. This can cause data loss, especially when used for predicates with count index.
This is how you specify the @noconflict
directive for a predicate.
As well as implying a schema type for a first mutation, an RDF type can override a schema type for storage. Dgraph supports a number of RDF types.
If a predicate has a schema type and a mutation has an RDF type with a different underlying Dgraph type, the convertibility to schema type is checked, and an error is thrown if incompatible, but the value is stored in the RDF type’s corresponding Dgraph type. Query results are always returned in schema type.
For example, if no schema is set for the age
predicate. Given the mutation
Dgraph:
int
, as implied by the first triple,"13"
to int
on storage,"14"
can be converted to int
, but stores as string
,"14.5"
can’t be
converted to int
.A password for an entity is set with setting the schema for the attribute to be
of type password
. Passwords can’t be queried directly, only checked for a
match using the checkpwd
function. The passwords are encrypted using
bcrypt
.
For example: to set a password, first set schema, then the password:
to check a password:
output:
You can also use alias with password type.
output:
The schema is also used to set predicates indexes, which are required to apply filtering functions in DQL queries.
Node types are declared along with predicate types in the Dgraph types schema.
Node types are optional.
Node type declares the list of predicates that could be present in a Node of this type. Node type are defined using the following syntax:
All predicates used in a type must be defined in the Dgraph types schema itself.
Reverse predicates can also be included inside a type definition. For example,
the following schema, declares that a node of type Child may have a ~children
inverse relationship.
A node is given a type by setting the dgraph.type
predicate value to the type
name.
A node may be given many types, dgraph.type
is an array of strings.
DQL types are only declarative and aren’t enforced by Dgraph. In DQL, you can
always add node without a dgraph.type
predicate.
Here’s an example of mutation to set the types of a node:
Node types are optional, but there are two use cases where actually knowing the list of potential predicates of a node is necessary:
delete { <uid> * * . }
mutation.The Dgraph node types are used in those 2 use cases: when executing the
delete all predicates
mutation or the expand all
query, Dgraph checks if the
node has a dgraph.type
predicate. If so, the engine is using the declared type
to find the list of predicates and apply the delete or the expand on all of
them.
When nodes have a type (i.e have a dgraph.type
predicate), then you can use
the function type()
in queries.
delete { <uid> * * . }
only deletes the
predicates declared in the type. You may have added other predicates by running
DQL mutation on this node: the node may still exist after the operation if it
holds predicates not declared in the node type.
The following pages are the language reference for DQL.
They contain examples that you can run interactively using a database of 21 million triples about movies and actors.
The queries are executed on an instance of Dgraph running at https://play.dgraph.io/.
The example movie database uses the following schema: