Hi everyone!
Now that types have made it into Dgraph with v1.1.0, it is time to reconsider how expand works.
In v1.2.0 we will update the behavior of expand to the following specs:
-
expand(_all_)expands all of the predicates found in all of the types associated with any of the nodes at the level whereexpandappears. This includes any predicates appearing in those types, which could be reversed edges. -
expand(_predicate_)expands all of the predicates for all of the nodes at the level whereexpandappears. This includes any predicate coming out of the nodes, no matter whether any types are associated with those nodes. -
expand(_forward_)andexpand(_reverse_)will be REMOVED FROM THE LANGUAGE, as their interaction with types makes them redundant. -
expand(typeNameA, typeNameB)will expand all of the predicates in the types given as parameters.
Some examples
Letâs define this schema:
<name>: string @index(exact) .
<parent>: [uid] @reverse .
<lives_in>: string .
type Person {
name: string
parent: [uid]
<~parent>: [uid]
}
The type Person has three fields, corresponding to two predicates defined in the schema plus a reversed predicate. Letâs assume we have performed this mutation:
{
set {
_:f <name> "Francesc" .
_:f <dgraph.type> "Person" .
_:f <lives_in> "San Francisco" .
_:f <parent> _:p .
_:f <parent> _:l .
_:p <name> "Paco" .
_:p <dgraph.type> "Person" .
_:l <name> "Lucia" .
_:l <dgraph.type> "Person" .
}
}
Using expand(_all_) on this query will return only the predicates in Person type:
{
q(func: eq(name, "Francesc")) @recurse(depth:3) {
expand(_all_)
}
}
Since we know that all of the nodes in this dataset are of type Person, the query above is equivalent to:
{
q(func: eq(name, "Francesc")) @recurse(depth:3) {
expand(Person)
}
}
Both of the queries above return the same response:
{
"data": {
"q": [
{
"name": "Francesc",
"parent": [
{
"name": "Paco",
"~parent": [
{
"name": "Francesc"
}
]
},
{
"name": "Lucia",
"~parent": [
{
"name": "Francesc"
}
]
}
]
}
]
}
}
Notice how even though "Francesc" also has a predicate lives_in it will not appear in the response, as itâs not part of the type Person. Also, notice how ~parent is included in the response, as itâs also part of the type.
On the other hand, expanding on _predicate_ will return all of the predicates associated with the nodes, no matter whether theyâre part of the type or not.
{
q(func: eq(name, "Francesc")) @recurse(depth:3) {
expand(_predicate_)
}
}
{
"data": {
"q": [
{
"name": "Francesc",
"parent": [
{
"name": "Paco",
"~parent": [
{
"name": "Francesc",
"lives_in": "San Francisco"
}
]
},
{
"name": "Lucia",
"~parent": [
{
"name": "Francesc",
"lives_in": "San Francisco"
}
]
}
],
"lives_in": "San Francisco"
}
]
}
}
Notice how lives_in appears, although itâs not part of the type, and how ~parent appears as reverse predicates will still be fetched.
We need your opinion!
It is your time to tell us whether this will impact your usage of Dgraph so we can consider your needs in our design. Please let us know in this thread (or directly to francesc@dgraph.io) if you have any concerns regarding these changes.
We have other options, such as keeping _forward_ and _reverse_ but basing them on the behavior of _predicate_ rather than _all_. This would lead to not very performant queries, so thatâs why weâre considering removing them completely.
Thanks!




