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 whereexpand
appears. 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 whereexpand
appears. 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!