Expand Predicates
The expand() function can be used to expand the predicates out of a node. To
use expand(), the type system is required.
Refer to the section on the type system to check how to set the types
nodes. The rest of this section assumes familiarity with that section.
There are two ways to use the expand function.
- Types can be passed to
expand()to expand all the predicates in the type.
Query example: List the movies from the Harry Potter series:
- Query
- Go
- Java
- Python
- JavaScript (gRPC)
- JavaScript (HTTP)
- Curl
{
all(func: eq(name@en, "Harry Potter")) @filter(type(Series)) {
name@en
expand(Series) {
name@en
expand(Film)
}
}
}
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"google.golang.org/grpc"
"github.com/dgraph-io/dgo/v230"
"github.com/dgraph-io/dgo/v230/protos/api"
)
func main() {
conn, err := grpc.Dial("localhost:9080", grpc.WithInsecure())
if err != nil {
log.Fatal(err)
}
defer conn.Close()
dgraphClient := dgo.NewDgraphClient(api.NewDgraphClient(conn))
ctx := context.Background()
txn := dgraphClient.NewTxn()
defer txn.Discard(ctx)
query := `{
all(func: eq(name@en, "Harry Potter")) @filter(type(Series)) {
name@en
expand(Series) {
name@en
expand(Film)
}
}
}`
resp, err := txn.Query(ctx, query)
if err != nil {
log.Fatal(err)
}
var result map[string]interface{}
json.Unmarshal(resp.Json, &result)
fmt.Printf("%+v\n", result)
}
import io.dgraph.DgraphClient;
import io.dgraph.DgraphGrpc;
import io.dgraph.DgraphProto;
import io.dgraph.Transaction;
import java.util.Map;
public class App {
public static void main(String[] args) {
ManagedChannel channel = ManagedChannelBuilder
.forAddress("localhost", 9080)
.usePlaintext()
.build();
DgraphGrpc.DgraphStub stub = DgraphGrpc.newStub(channel);
DgraphClient dgraphClient = new DgraphClient(stub);
String query = "{
all(func: eq(name@en, \"Harry Potter\")) @filter(type(Series)) {
name@en
expand(Series) {
name@en
expand(Film)
}
}
}";
Transaction txn = dgraphClient.newTransaction();
try {
DgraphProto.Response response = txn.query(query);
System.out.println(response.getJson().toStringUtf8());
} finally {
txn.discard();
}
}
}
import grpc
from dgraph import DgraphClient, Txn
def main():
client_stub = DgraphClient("localhost:9080")
client = DgraphClient(client_stub)
query = """{
all(func: eq(name@en, "Harry Potter")) @filter(type(Series)) {
name@en
expand(Series) {
name@en
expand(Film)
}
}
}"""
txn = client.txn()
try:
response = txn.query(query)
print(response.json)
finally:
txn.discard()
if __name__ == "__main__":
main()
const dgraph = require("dgraph-js");
const grpc = require("grpc");
async function main() {
const clientStub = new dgraph.DgraphClientStub(
"localhost:9080",
grpc.credentials.createInsecure()
);
const dgraphClient = new dgraph.DgraphClient(clientStub);
const query = `{
all(func: eq(name@en, "Harry Potter")) @filter(type(Series)) {
name@en
expand(Series) {
name@en
expand(Film)
}
}
}`;
const txn = dgraphClient.newTxn();
try {
const res = await txn.query(query);
const json = res.getJson();
console.log(JSON.stringify(JSON.parse(json), null, 2));
} finally {
await txn.discard();
}
}
main().catch((e) => {
console.error(e);
});
const fetch = require("node-fetch");
async function main() {
const query = `{
all(func: eq(name@en, "Harry Potter")) @filter(type(Series)) {
name@en
expand(Series) {
name@en
expand(Film)
}
}
}`;
const response = await fetch("http://localhost:8080/query", {
method: "POST",
headers: {
"Content-Type": "application/dql"
},
body: query
});
const result = await response.json();
console.log(JSON.stringify(result, null, 2));
}
main().catch((e) => {
console.error(e);
});
curl -X POST http://localhost:8080/query \
-H "Content-Type: application/dql" \
-d '{
all(func: eq(name@en, "Harry Potter")) @filter(type(Series)) {
name@en
expand(Series) {
name@en
expand(Film)
}
}
}'
- If
_all_is passed as an argument toexpand(), the predicates to be expanded will be the union of fields in the types assigned to a given node.
The _all_ keyword requires that the nodes have types. Dgraph will look for all
the types that have been assigned to a node, query the types to check which
attributes they have, and use those to compute the list of predicates to expand.
For example, consider a node that has types Animal and Pet, which have
the following definitions:
type Animal {
name
species
dob
}
type Pet {
owner
veterinarian
}
When expand(_all_) is called on this node, Dgraph will first check which types
the node has (Animal and Pet). Then it will get the definitions of Animal
and Pet and build a list of predicates from their type definitions.
name
species
dob
owner
veterinarian
For string predicates, expand only returns values not tagged with a language
(see language preference). So it's often
required to add name@fr or name@. as well to an expand query.
Filtering during expand
Expand queries support filters on the type of the outgoing edge. For example,
expand(_all_) @filter(type(Person)) will expand on all the predicates but will
only include edges whose destination node is of type Person. Since only nodes of
type uid can have a type, this query will filter out any scalar values.
Please note that other type of filters and directives are not currently supported
with the expand function. The filter needs to use the type function for the
filter to be allowed. Logical AND and OR operations are allowed. For
example, expand(_all_) @filter(type(Person) OR type(Animal)) will only expand
the edges that point to nodes of either type.