Pagination
Pagination allows returning only a portion, rather than the whole, result set. This can be useful for top-k style queries as well as to reduce the size of the result set for client side processing or to allow paged access to results.
Pagination is often used with sorting.
:::noteWithout a sort order specified, the results are sorted by uid, which is assigned randomly. So the ordering, while deterministic, might not be what you expected.:::
First
Syntax Examples:
q(func: ..., first: N)predicate (first: N) { ... }predicate @filter(...) (first: N) { ... }
For positive N, first: N retrieves the first N results, by sorted or UID order.
For negative N, first: N retrieves the last N results, by sorted or UID order. Currently, negative is only supported when no order is applied. To achieve the effect of a negative with a sort, reverse the order of the sort and use a positive N.
Query Example: Last two films, by UID order, directed by Steven Spielberg and the first three genres of those movies, sorted alphabetically by English name.
- Query
- Go
- Java
- Python
- JavaScript (gRPC)
- JavaScript (HTTP)
- Curl
{
me(func: allofterms(name@en, "Steven Spielberg")) {
director.film (first: -2) {
name@en
initial_release_date
genre (orderasc: name@en) (first: 3) {
name@en
}
}
}
}
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 := `{
me(func: allofterms(name@en, "Steven Spielberg")) {
director.film (first: -2) {
name@en
initial_release_date
genre (orderasc: name@en) (first: 3) {
name@en
}
}
}
}`
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 = "{
me(func: allofterms(name@en, \"Steven Spielberg\")) {
director.film (first: -2) {
name@en
initial_release_date
genre (orderasc: name@en) (first: 3) {
name@en
}
}
}
}";
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 = """{
me(func: allofterms(name@en, "Steven Spielberg")) {
director.film (first: -2) {
name@en
initial_release_date
genre (orderasc: name@en) (first: 3) {
name@en
}
}
}
}"""
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 = `{
me(func: allofterms(name@en, "Steven Spielberg")) {
director.film (first: -2) {
name@en
initial_release_date
genre (orderasc: name@en) (first: 3) {
name@en
}
}
}
}`;
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 = `{
me(func: allofterms(name@en, "Steven Spielberg")) {
director.film (first: -2) {
name@en
initial_release_date
genre (orderasc: name@en) (first: 3) {
name@en
}
}
}
}`;
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 '{
me(func: allofterms(name@en, "Steven Spielberg")) {
director.film (first: -2) {
name@en
initial_release_date
genre (orderasc: name@en) (first: 3) {
name@en
}
}
}
}'
Query Example: The three directors named Steven who have directed the most actors of all directors named Steven.
- Query
- Go
- Java
- Python
- JavaScript (gRPC)
- JavaScript (HTTP)
- Curl
{
ID as var(func: allofterms(name@en, "Steven")) @filter(has(director.film)) {
director.film {
stars as count(starring)
}
totalActors as sum(val(stars))
}
mostStars(func: uid(ID), orderdesc: val(totalActors), first: 3) {
name@en
stars : val(totalActors)
director.film {
name@en
}
}
}
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 := `{
ID as var(func: allofterms(name@en, "Steven")) @filter(has(director.film)) {
director.film {
stars as count(starring)
}
totalActors as sum(val(stars))
}
mostStars(func: uid(ID), orderdesc: val(totalActors), first: 3) {
name@en
stars : val(totalActors)
director.film {
name@en
}
}
}`
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 = "{
ID as var(func: allofterms(name@en, \"Steven\")) @filter(has(director.film)) {
director.film {
stars as count(starring)
}
totalActors as sum(val(stars))
}
mostStars(func: uid(ID), orderdesc: val(totalActors), first: 3) {
name@en
stars : val(totalActors)
director.film {
name@en
}
}
}";
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 = """{
ID as var(func: allofterms(name@en, "Steven")) @filter(has(director.film)) {
director.film {
stars as count(starring)
}
totalActors as sum(val(stars))
}
mostStars(func: uid(ID), orderdesc: val(totalActors), first: 3) {
name@en
stars : val(totalActors)
director.film {
name@en
}
}
}"""
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 = `{
ID as var(func: allofterms(name@en, "Steven")) @filter(has(director.film)) {
director.film {
stars as count(starring)
}
totalActors as sum(val(stars))
}
mostStars(func: uid(ID), orderdesc: val(totalActors), first: 3) {
name@en
stars : val(totalActors)
director.film {
name@en
}
}
}`;
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 = `{
ID as var(func: allofterms(name@en, "Steven")) @filter(has(director.film)) {
director.film {
stars as count(starring)
}
totalActors as sum(val(stars))
}
mostStars(func: uid(ID), orderdesc: val(totalActors), first: 3) {
name@en
stars : val(totalActors)
director.film {
name@en
}
}
}`;
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 '{
ID as var(func: allofterms(name@en, "Steven")) @filter(has(director.film)) {
director.film {
stars as count(starring)
}
totalActors as sum(val(stars))
}
mostStars(func: uid(ID), orderdesc: val(totalActors), first: 3) {
name@en
stars : val(totalActors)
director.film {
name@en
}
}
}'
Offset
Syntax Examples:
q(func: ..., offset: N)predicate (offset: N) { ... }predicate (first: M, offset: N) { ... }predicate @filter(...) (offset: N) { ... }
With offset: N the first N results are not returned. Used in combination with first, first: M, offset: N skips over N results and returns the following M.
:::noteSkipping over N results takes time proportional to N (complexity O(N)). In other words, the larger N, the longer it takes to compute the result set. Prefer after over offset.:::
Query Example: Order Hark Tsui's films by English title, skip over the first 4 and return the following 6.
- Query
- Go
- Java
- Python
- JavaScript (gRPC)
- JavaScript (HTTP)
- Curl
{
me(func: allofterms(name@en, "Hark Tsui")) {
name@zh
name@en
director.film (orderasc: name@en) (first:6, offset:4) {
genre {
name@en
}
name@zh
name@en
initial_release_date
}
}
}
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 := `{
me(func: allofterms(name@en, "Hark Tsui")) {
name@zh
name@en
director.film (orderasc: name@en) (first:6, offset:4) {
genre {
name@en
}
name@zh
name@en
initial_release_date
}
}
}`
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 = "{
me(func: allofterms(name@en, \"Hark Tsui\")) {
name@zh
name@en
director.film (orderasc: name@en) (first:6, offset:4) {
genre {
name@en
}
name@zh
name@en
initial_release_date
}
}
}";
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 = """{
me(func: allofterms(name@en, "Hark Tsui")) {
name@zh
name@en
director.film (orderasc: name@en) (first:6, offset:4) {
genre {
name@en
}
name@zh
name@en
initial_release_date
}
}
}"""
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 = `{
me(func: allofterms(name@en, "Hark Tsui")) {
name@zh
name@en
director.film (orderasc: name@en) (first:6, offset:4) {
genre {
name@en
}
name@zh
name@en
initial_release_date
}
}
}`;
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 = `{
me(func: allofterms(name@en, "Hark Tsui")) {
name@zh
name@en
director.film (orderasc: name@en) (first:6, offset:4) {
genre {
name@en
}
name@zh
name@en
initial_release_date
}
}
}`;
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 '{
me(func: allofterms(name@en, "Hark Tsui")) {
name@zh
name@en
director.film (orderasc: name@en) (first:6, offset:4) {
genre {
name@en
}
name@zh
name@en
initial_release_date
}
}
}'
After
Syntax Examples:
q(func: ..., after: UID)predicate (first: N, after: UID) { ... }predicate @filter(...) (first: N, after: UID) { ... }
Another way to get results after skipping over some results is to use the default UID ordering and skip directly past a node specified by UID. For example, a first query could be of the form predicate (after: 0x0, first: N), or just predicate (first: N), with subsequent queries of the form predicate(after: <uid of last entity in last result>, first: N).
:::noteSkipping over results with after takes constant time (complexity O(1)). In other words, no matter how many results are skipped, no extra time adds to computing the result set. This should be preferred over offset.:::
Query Example: The first five of Baz Luhrmann's films, sorted by UID order.
- Query
- Go
- Java
- Python
- JavaScript (gRPC)
- JavaScript (HTTP)
- Curl
{
me(func: allofterms(name@en, "Baz Luhrmann")) {
name@en
director.film (first:5) {
uid
name@en
}
}
}
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 := `{
me(func: allofterms(name@en, "Baz Luhrmann")) {
name@en
director.film (first:5) {
uid
name@en
}
}
}`
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 = "{
me(func: allofterms(name@en, \"Baz Luhrmann\")) {
name@en
director.film (first:5) {
uid
name@en
}
}
}";
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 = """{
me(func: allofterms(name@en, "Baz Luhrmann")) {
name@en
director.film (first:5) {
uid
name@en
}
}
}"""
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 = `{
me(func: allofterms(name@en, "Baz Luhrmann")) {
name@en
director.film (first:5) {
uid
name@en
}
}
}`;
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 = `{
me(func: allofterms(name@en, "Baz Luhrmann")) {
name@en
director.film (first:5) {
uid
name@en
}
}
}`;
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 '{
me(func: allofterms(name@en, "Baz Luhrmann")) {
name@en
director.film (first:5) {
uid
name@en
}
}
}'
The fifth movie is the Australian movie classic Strictly Ballroom. It has UID 0x99e44. The results after Strictly Ballroom can now be obtained with after.
- Query
- Go
- Java
- Python
- JavaScript (gRPC)
- JavaScript (HTTP)
- Curl
{
me(func: allofterms(name@en, "Baz Luhrmann")) {
name@en
director.film (first:5, after: 0x99e44) {
uid
name@en
}
}
}
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 := `{
me(func: allofterms(name@en, "Baz Luhrmann")) {
name@en
director.film (first:5, after: 0x99e44) {
uid
name@en
}
}
}`
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 = "{
me(func: allofterms(name@en, \"Baz Luhrmann\")) {
name@en
director.film (first:5, after: 0x99e44) {
uid
name@en
}
}
}";
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 = """{
me(func: allofterms(name@en, "Baz Luhrmann")) {
name@en
director.film (first:5, after: 0x99e44) {
uid
name@en
}
}
}"""
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 = `{
me(func: allofterms(name@en, "Baz Luhrmann")) {
name@en
director.film (first:5, after: 0x99e44) {
uid
name@en
}
}
}`;
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 = `{
me(func: allofterms(name@en, "Baz Luhrmann")) {
name@en
director.film (first:5, after: 0x99e44) {
uid
name@en
}
}
}`;
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 '{
me(func: allofterms(name@en, "Baz Luhrmann")) {
name@en
director.film (first:5, after: 0x99e44) {
uid
name@en
}
}
}'