Ask a Question

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:

{
  all(func: eq(name@en, "Harry Potter")) @filter(type(Series)) {
    name@en
    expand(Series) {
      name@en
      expand(Film)
    }
  }
}
curl -H "Content-Type: application/dql" localhost:8080/query -XPOST -d '
blahblah' | python -m json.tool | less
package main

import (
	"context"
	"flag"
	"fmt"
	"log"
    
	"github.com/dgraph-io/dgo/v2"
	"github.com/dgraph-io/dgo/v2/protos/api"
    
	"google.golang.org/grpc"
)

var (
	dgraph = flag.String("d", "127.0.0.1:9080", "Dgraph Alpha address")
)

func main() {
	flag.Parse()
	conn, err := grpc.Dial(*dgraph, grpc.WithInsecure())
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	dg := dgo.NewDgraphClient(api.NewDgraphClient(conn))
    
	resp, err := dg.NewTxn().Query(context.Background(), `blahblah`)
	
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Response: %s\n", resp.Json)
}
import io.dgraph.DgraphClient;
import io.dgraph.DgraphGrpc;
import io.dgraph.DgraphGrpc.DgraphStub;
import io.dgraph.DgraphProto.Response;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;

import java.util.Map;

public class App {

    public static void main(final String[] args) {
        ManagedChannel channel =
            ManagedChannelBuilder.forAddress("localhost", 9080).usePlaintext(true).build();
        DgraphStub stub = DgraphGrpc.newStub(channel);
        DgraphClient dgraphClient = new DgraphClient(stub);

        String query = "blahblah";

    
        Response res = dgraphClient.newTransaction().query(query);
    
        System.out.printf("Response: %s", res.getJson().toStringUtf8());
    }
}

import pydgraph
import json

def main():
    client_stub = pydgraph.DgraphClientStub("localhost:9080")
    client = pydgraph.DgraphClient(client_stub)
    query = """blahblah"""
    res = client.txn(read_only=True).query(query)
    print('Response: {}'.format(json.loads(res.json)))

    client_stub.close()


if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        print('Error: {}'.format(e))

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 = `blahblah`;
  const response = await dgraphClient.newTxn().query(query);
  console.log("Response: ", JSON.stringify(response.getJson()));

  clientStub.close();
}

main().then().catch((e) => {
  console.log("ERROR: ", e);
});
const dgraph = require("dgraph-js-http");

async function main() {
  const clientStub = new dgraph.DgraphClientStub("http://localhost:8080");
  const dgraphClient = new dgraph.DgraphClient(clientStub);

  const query = `blahblah`;
  const response = await dgraphClient.newTxn().query(query);
  console.log("Response: ", JSON.stringify(response.data));
}

main().then().catch((e) => {
  console.log("ERROR: ", e);
});
Response
  • If _all_ is passed as an argument to expand(), 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
Note 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.