dgo: github.com/dgraph-io/dgo Index | Examples | Files | Directories

package dgo

import "github.com/dgraph-io/dgo"

Package dgo is used to interact with a Dgraph server. Queries, mutations, and most other types of admin tasks can be run from the client.

Code:

dg, cancel := getDgraphClient()
defer cancel()

op := &api.Operation{}
op.Schema = `
		name: string @index(exact) .
		age: int .
		married: bool .
		loc: geo .
		dob: datetime .
	`

ctx := context.Background()
err := dg.Alter(ctx, op)
if err != nil {
    log.Fatal(err)
}

// Ask for the type of name and age.
resp, err := dg.NewTxn().Query(ctx, `schema(pred: [name, age]) {type}`)
if err != nil {
    log.Fatal(err)
}

// resp.Json contains the schema query response.
fmt.Println(string(resp.Json))

Output:

{"schema":[{"predicate":"age","type":"int"},{"predicate":"name","type":"string"}]}

Code:

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "time"

    "github.com/dgraph-io/dgo/v2"
    "github.com/dgraph-io/dgo/v2/protos/api"
    "google.golang.org/grpc"
)

type School struct {
    Name  string   `json:"name,omitempty"`
    DType []string `json:"dgraph.type,omitempty"`
}

type loc struct {
    Type   string    `json:"type,omitempty"`
    Coords []float64 `json:"coordinates,omitempty"`
}

// If omitempty is not set, then edges with empty values (0 for int/float, "" for string, false
// for bool) would be created for values not specified explicitly.

type Person struct {
    Uid      string     `json:"uid,omitempty"`
    Name     string     `json:"name,omitempty"`
    Age      int        `json:"age,omitempty"`
    Dob      *time.Time `json:"dob,omitempty"`
    Married  bool       `json:"married,omitempty"`
    Raw      []byte     `json:"raw_bytes,omitempty"`
    Friends  []Person   `json:"friend,omitempty"`
    Location loc        `json:"loc,omitempty"`
    School   []School   `json:"school,omitempty"`
    DType    []string   `json:"dgraph.type,omitempty"`
}

func main() {
    conn, err := grpc.Dial("127.0.0.1:9180", grpc.WithInsecure())
    if err != nil {
        log.Fatal("While trying to dial gRPC")
    }
    defer conn.Close()

    dc := api.NewDgraphClient(conn)
    dg := dgo.NewDgraphClient(dc)

    dob := time.Date(1980, 01, 01, 23, 0, 0, 0, time.UTC)
    // While setting an object if a struct has a Uid then its properties in the graph are updated
    // else a new node is created.
    // In the example below new nodes for Alice, Bob and Charlie and school are created (since they
    // dont have a Uid).
    p := Person{
        Uid:     "_:alice",
        Name:    "Alice",
        Age:     26,
        Married: true,
        DType:   []string{"Person"},
        Location: loc{
            Type:   "Point",
            Coords: []float64{1.1, 2},
        },
        Dob: &dob,
        Raw: []byte("raw_bytes"),
        Friends: []Person{{
            Name:  "Bob",
            Age:   24,
            DType: []string{"Person"},
        }, {
            Name:  "Charlie",
            Age:   29,
            DType: []string{"Person"},
        }},
        School: []School{{
            Name:  "Crown Public School",
            DType: []string{"Institution"},
        }},
    }

    op := &api.Operation{}
    op.Schema = `
		name: string @index(exact) .
		age: int .
		married: bool .
		loc: geo .
		dob: datetime .
		Friend: [uid] .
		type: string .
		coords: float .

		type Person {
			name: string
			age: int
			married: bool
			Friend: [Person]
			loc: Loc
		}

		type Institution {
			name: string
		}

		type Loc {
			type: string
			coords: float
		}
	`

    ctx := context.Background()
    err = dg.Alter(ctx, op)
    if err != nil {
        log.Fatal(err)
    }

    mu := &api.Mutation{
        CommitNow: true,
    }
    pb, err := json.Marshal(p)
    if err != nil {
        log.Fatal(err)
    }

    mu.SetJson = pb
    response, err := dg.NewTxn().Mutate(ctx, mu)
    if err != nil {
        log.Fatal(err)
    }

    // Assigned uids for nodes which were created would be returned in the response.Uids map.
    variables := map[string]string{"$id1": response.Uids["alice"]}
    q := `query Me($id1: string){
		me(func: uid($id1)) {
			name
			dob
			age
			loc
			raw_bytes
			married
			dgraph.type
			friend @filter(eq(name, "Bob")){
				name
				age
				dgraph.type
			}
			school {
				name
				dgraph.type
			}
		}
	}`

    resp, err := dg.NewTxn().QueryWithVars(ctx, q, variables)
    if err != nil {
        log.Fatal(err)
    }

    type Root struct {
        Me []Person `json:"me"`
    }

    var r Root
    err = json.Unmarshal(resp.Json, &r)
    if err != nil {
        log.Fatal(err)
    }

    out, _ := json.MarshalIndent(r, "", "\t")
    fmt.Printf("%s\n", out)
}

Index

Examples

Package Files

client.go doc.go txn.go

Variables

var (
    // ErrFinished is returned when an operation is performed on
    // already committed or discarded transaction
    ErrFinished = errors.New("Transaction has already been committed or discarded")
    // ErrReadOnly is returned when a write/update is performed on a readonly transaction
    ErrReadOnly = errors.New("Readonly transaction cannot run mutations or be committed")
    // ErrAborted is returned when an operation is performed on an aborted transaction.
    ErrAborted = errors.New("Transaction has been aborted. Please retry")
)

func DeleteEdges Uses

func DeleteEdges(mu *api.Mutation, uid string, predicates ...string)

DeleteEdges sets the edges corresponding to predicates on the node with the given uid for deletion. This helper function doesn't run the mutation on the server. Txn needs to be committed in order to execute the mutation.

Code:

dg, cancel := getDgraphClient()
defer cancel()
op := &api.Operation{}
op.Schema = `
		age: int .
		married: bool .
		name: string @lang .
		location: string .
		Friends: [uid] .

		type Person {
			name
			age
			married
			Friends
		}

		type Institution {
			name
		}

		type Institution {
			name: string
		}
	`

ctx := context.Background()
err := dg.Alter(ctx, op)
if err != nil {
    log.Fatal(err)
}

type School struct {
    Uid   string   `json:"uid"`
    Name  string   `json:"name@en,omitempty"`
    DType []string `json:"dgraph.type,omitempty"`
}

type Person struct {
    Uid      string    `json:"uid,omitempty"`
    Name     string    `json:"name,omitempty"`
    Age      int       `json:"age,omitempty"`
    Married  bool      `json:"married,omitempty"`
    Friends  []Person  `json:"friends,omitempty"`
    Location string    `json:"location,omitempty"`
    Schools  []*School `json:"schools,omitempty"`
    DType    []string  `json:"dgraph.type,omitempty"`
}

// Lets add some data first.
p := Person{
    Uid:      "_:alice",
    Name:     "Alice",
    Age:      26,
    Married:  true,
    DType:    []string{"Person"},
    Location: "Riley Street",
    Friends: []Person{{
        Name:  "Bob",
        Age:   24,
        DType: []string{"Person"},
    }, {
        Name:  "Charlie",
        Age:   29,
        DType: []string{"Person"},
    }},
    Schools: []*School{&School{
        Name:  "Crown Public School",
        DType: []string{"Institution"},
    }},
}

mu := &api.Mutation{}
pb, err := json.Marshal(p)
if err != nil {
    log.Fatal(err)
}

mu.SetJson = pb
mu.CommitNow = true
response, err := dg.NewTxn().Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}

alice := response.Uids["alice"]

variables := make(map[string]string)
variables["$alice"] = alice
const q = `
		query Me($alice: string){
			me(func: uid($alice)) {
				name
				age
				location
				married
				dgraph.type
				friends {
					name
					age
					dgraph.type
				}
				schools {
					name@en
					dgraph.type
				}
			}
		}
	`

resp, err := dg.NewTxn().QueryWithVars(ctx, q, variables)
if err != nil {
    log.Fatal(err)
}

// Now lets delete the friend and location edge from Alice
mu = &api.Mutation{}
dgo.DeleteEdges(mu, alice, "friends", "location")

mu.CommitNow = true
_, err = dg.NewTxn().Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}

resp, err = dg.NewTxn().QueryWithVars(ctx, q, variables)
if err != nil {
    log.Fatal(err)
}

type Root struct {
    Me []Person `json:"me"`
}

var r Root
err = json.Unmarshal(resp.Json, &r)
out, _ := json.MarshalIndent(r.Me, "", "\t")
fmt.Printf("%s\n", out)

Output:

[
	{
		"name": "Alice",
		"age": 26,
		"married": true,
		"schools": [
			{
				"uid": "",
				"name@en": "Crown Public School",
				"dgraph.type": [
					"Institution"
				]
			}
		],
		"dgraph.type": [
			"Person"
		]
	}
]

type Dgraph Uses

type Dgraph struct {
    // contains filtered or unexported fields
}

Dgraph is a transaction aware client to a set of Dgraph server instances.

func NewDgraphClient Uses

func NewDgraphClient(clients ...api.DgraphClient) *Dgraph

NewDgraphClient creates a new Dgraph (client) for interacting with Alphas. The client is backed by multiple connections to the same or different servers in a cluster.

A single Dgraph (client) is thread safe for sharing with multiple goroutines.

func (*Dgraph) Alter Uses

func (d *Dgraph) Alter(ctx context.Context, op *api.Operation) error

Alter can be used to do the following by setting various fields of api.Operation:

1. Modify the schema.
2. Drop a predicate.
3. Drop the database.

Code:

dg, cancel := getDgraphClient()
defer cancel()
op := api.Operation{DropAll: true}
ctx := context.Background()
if err := dg.Alter(ctx, &op); err != nil {
    log.Fatal(err)
}

func (*Dgraph) Login Uses

func (d *Dgraph) Login(ctx context.Context, userid string, password string) error

Login logs in the current client using the provided credentials. Valid for the duration the client is alive.

func (*Dgraph) NewReadOnlyTxn Uses

func (d *Dgraph) NewReadOnlyTxn() *Txn

NewReadOnlyTxn sets the txn to readonly transaction.

func (*Dgraph) NewTxn Uses

func (d *Dgraph) NewTxn() *Txn

NewTxn creates a new transaction.

type Txn Uses

type Txn struct {
    // contains filtered or unexported fields
}

Txn is a single atomic transaction. A transaction lifecycle is as follows:

1. Created using NewTxn.
2. Various Query and Mutate calls made.
3. Commit or Discard used. If any mutations have been made, It's important
   that at least one of these methods is called to clean up resources. Discard
   is a no-op if Commit has already been called, so it's safe to defer a call
   to Discard immediately after NewTxn.

func (*Txn) BestEffort Uses

func (txn *Txn) BestEffort() *Txn

BestEffort enables best effort in read-only queries. This will ask the Dgraph Alpha to try to get timestamps from memory in a best effort to reduce the number of outbound requests to Zero. This may yield improved latencies in read-bound datasets.

This method will panic if the transaction is not read-only. Returns the transaction itself.

func (*Txn) Commit Uses

func (txn *Txn) Commit(ctx context.Context) error

Commit commits any mutations that have been made in the transaction. Once Commit has been called, the lifespan of the transaction is complete.

Errors could be returned for various reasons. Notably, ErrAborted could be returned if transactions that modify the same data are being run concurrently. It's up to the user to decide if they wish to retry. In this case, the user should create a new transaction.

func (*Txn) Discard Uses

func (txn *Txn) Discard(ctx context.Context) error

Discard cleans up the resources associated with an uncommitted transaction that contains mutations. It is a no-op on transactions that have already been committed or don't contain mutations. Therefore, it is safe (and recommended) to call as a deferred function immediately after a new transaction is created.

In some cases, the transaction can't be discarded, e.g. the grpc connection is unavailable. In these cases, the server will eventually do the transaction clean up itself without any intervention from the client.

Code:

dg, cancel := getDgraphClient()
defer cancel()

ctx, toCancel := context.WithTimeout(context.Background(), 30*time.Second)
defer toCancel()
err := dg.Alter(ctx, &api.Operation{
    DropAll: true,
})
if err != nil {
    log.Fatal("The drop all operation should have succeeded")
}

err = dg.Alter(ctx, &api.Operation{
    Schema: `name: string @index(exact) .`,
})
if err != nil {
    log.Fatal("The alter should have succeeded")
}

txn := dg.NewTxn()
_, err = txn.Mutate(ctx, &api.Mutation{
    SetNquads: []byte(`_:a <name> "Alice" .`),
})
if err != nil {
    log.Fatal("The mutation should have succeeded")
}
txn.Discard(ctx)

// now query the cluster and make sure that the data has made no effect
queryTxn := dg.NewReadOnlyTxn()
query := `
		{
			q (func: eq(name, "Alice")) {
				name
				dgraph.type
			}
		}
	`
resp, err := queryTxn.Query(ctx, query)
if err != nil {
    log.Fatal("The query should have succeeded")
}

fmt.Printf(string(resp.Json))

Output:

{"q":[]}

func (*Txn) Do Uses

func (txn *Txn) Do(ctx context.Context, req *api.Request) (*api.Response, error)

Do executes a query followed by one or more than one mutations.

func (*Txn) Mutate Uses

func (txn *Txn) Mutate(ctx context.Context, mu *api.Mutation) (*api.Response, error)

Mutate allows data stored on Dgraph instances to be modified. The fields in api.Mutation come in pairs, set and delete. Mutations can either be encoded as JSON or as RDFs.

If CommitNow is set, then this call will result in the transaction being committed. In this case, an explicit call to Commit doesn't need to be made subsequently.

If the mutation fails, then the transaction is discarded and all future operations on it will fail.

Code:

type School struct {
    Name  string   `json:"name,omitempty"`
    DType []string `json:"dgraph.type,omitempty"`
}

type loc struct {
    Type   string    `json:"type,omitempty"`
    Coords []float64 `json:"coordinates,omitempty"`
}

// If omitempty is not set, then edges with empty values (0 for int/float, "" for string, false
// for bool) would be created for values not specified explicitly.

type Person struct {
    Uid      string   `json:"uid,omitempty"`
    Name     string   `json:"name,omitempty"`
    Age      int      `json:"age,omitempty"`
    Married  bool     `json:"married,omitempty"`
    Raw      []byte   `json:"raw_bytes,omitempty"`
    Friends  []Person `json:"friends,omitempty"`
    Location loc      `json:"loc,omitempty"`
    School   []School `json:"school,omitempty"`
    DType    []string `json:"dgraph.type,omitempty"`
}

dg, cancel := getDgraphClient()
defer cancel()
// While setting an object if a struct has a Uid then its properties in the
// graph are updated else a new node is created.
// In the example below new nodes for Alice, Bob and Charlie and school
// are created (since they don't have a Uid).
p := Person{
    Uid:     "_:alice",
    Name:    "Alice",
    Age:     26,
    Married: true,
    DType:   []string{"Person"},
    Location: loc{
        Type:   "Point",
        Coords: []float64{1.1, 2},
    },
    Raw: []byte("raw_bytes"),
    Friends: []Person{{
        Name:  "Bob",
        Age:   24,
        DType: []string{"Person"},
    }, {
        Name:  "Charlie",
        Age:   29,
        DType: []string{"Person"},
    }},
    School: []School{{
        Name:  "Crown Public School",
        DType: []string{"Institution"},
    }},
}

op := &api.Operation{}
op.Schema = `
		name: string @index(exact) .
		age: int .
		married: bool .
		Friends: [uid] .
		loc: geo .
		type: string .
		coords: float .
		Friends: [uid] .

		type Person {
			name
			age
			married
			Friends
			loc
		  }

		type Institution {
			name
		}
	`

ctx := context.Background()
if err := dg.Alter(ctx, op); err != nil {
    log.Fatal(err)
}

mu := &api.Mutation{
    CommitNow: true,
}
pb, err := json.Marshal(p)
if err != nil {
    log.Fatal(err)
}

mu.SetJson = pb
response, err := dg.NewTxn().Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}

// Assigned uids for nodes which were created would be returned in the response.Uids map.
puid := response.Uids["alice"]
const q = `
		query Me($id: string){
			me(func: uid($id)) {
				name
				age
				loc
				raw_bytes
				married
				dgraph.type
				friends @filter(eq(name, "Bob")) {
					name
					age
					dgraph.type
				}
				school {
					name
					dgraph.type
				}
			}
		}
	`

variables := make(map[string]string)
variables["$id"] = puid
resp, err := dg.NewTxn().QueryWithVars(ctx, q, variables)
if err != nil {
    log.Fatal(err)
}

type Root struct {
    Me []Person `json:"me"`
}

var r Root
err = json.Unmarshal(resp.Json, &r)
if err != nil {
    log.Fatal(err)
}

out, _ := json.MarshalIndent(r, "", "\t")
fmt.Printf("%s\n", out)

Output:

{
	"me": [
		{
			"name": "Alice",
			"age": 26,
			"married": true,
			"raw_bytes": "cmF3X2J5dGVz",
			"friends": [
				{
					"name": "Bob",
					"age": 24,
					"loc": {},
					"dgraph.type": [
						"Person"
					]
				}
			],
			"loc": {
				"type": "Point",
				"coordinates": [
					1.1,
					2
				]
			},
			"school": [
				{
					"name": "Crown Public School",
					"dgraph.type": [
						"Institution"
					]
				}
			],
			"dgraph.type": [
				"Person"
			]
		}
	]
}

Code:

dg, cancel := getDgraphClient()
defer cancel()
type Person struct {
    Uid   string   `json:"uid,omitempty"`
    Name  string   `json:"name,omitempty"`
    Bytes []byte   `json:"bytes,omitempty"`
    DType []string `json:"dgraph.type,omitempty"`
}

op := &api.Operation{}
op.Schema = `
		name: string @index(exact) .
		bytes: string .

		type Person {
			name
			bytes
		}
	`

ctx := context.Background()
err := dg.Alter(ctx, op)
if err != nil {
    log.Fatal(err)
}

p := Person{
    Name:  "Alice-new",
    DType: []string{"Person"},
    Bytes: []byte("raw_bytes"),
}

mu := &api.Mutation{
    CommitNow: true,
}
pb, err := json.Marshal(p)
if err != nil {
    log.Fatal(err)
}

mu.SetJson = pb
_, err = dg.NewTxn().Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}

q := `
		{
			q(func: eq(name, "Alice-new")) {
				name
				bytes
				dgraph.type
			}
		}
	`

resp, err := dg.NewTxn().Query(ctx, q)
if err != nil {
    log.Fatal(err)
}

type Root struct {
    Me []Person `json:"q"`
}

var r Root
err = json.Unmarshal(resp.Json, &r)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Me: %+v\n", r.Me)

Output:

Me: [{Uid: Name:Alice-new Bytes:[114 97 119 95 98 121 116 101 115] DType:[Person]}]

Code:

dg, cancel := getDgraphClient()
defer cancel()
// In this test we check S * * deletion.
type Person struct {
    Uid     string    `json:"uid,omitempty"`
    Name    string    `json:"name,omitempty"`
    Age     int       `json:"age,omitempty"`
    Married bool      `json:"married,omitempty"`
    Friends []*Person `json:"friends,omitempty"`
    DType   []string  `json:"dgraph.type,omitempty"`
}

p := Person{
    Uid:     "_:alice",
    Name:    "Alice",
    Age:     26,
    Married: true,
    DType:   []string{"Person"},
    Friends: []*Person{&Person{
        Uid:   "_:bob",
        Name:  "Bob",
        Age:   24,
        DType: []string{"Person"},
    }, &Person{
        Uid:   "_:charlie",
        Name:  "Charlie",
        Age:   29,
        DType: []string{"Person"},
    }},
}

op := &api.Operation{}
op.Schema = `
		age: int .
		married: bool .
		friends: [uid] .

		type Person {
			name: string
			age: int
			married: bool
			friends: [Person]
		}
	`

ctx := context.Background()
err := dg.Alter(ctx, op)
if err != nil {
    log.Fatal(err)
}

mu := &api.Mutation{
    CommitNow: true,
}
pb, err := json.Marshal(p)
if err != nil {
    log.Fatal(err)
}

mu.SetJson = pb
response, err := dg.NewTxn().Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}

alice := response.Uids["alice"]
bob := response.Uids["bob"]
charlie := response.Uids["charlie"]

variables := make(map[string]string)
variables["$alice"] = alice
variables["$bob"] = bob
variables["$charlie"] = charlie
const q = `
		query Me($alice: string, $bob: string, $charlie: string){
			me(func: uid($alice)) {
				name
				age
				married
				dgraph.type
				friends {
					uid
					name
					age
					dgraph.type
				}
			}

			me2(func: uid($bob)) {
				name
				age
				dgraph.type
			}

			me3(func: uid($charlie)) {
				name
				age
				dgraph.type
			}
		}
	`

resp, err := dg.NewTxn().QueryWithVars(ctx, q, variables)
if err != nil {
    log.Fatal(err)
}

type Root struct {
    Me  []Person `json:"me"`
    Me2 []Person `json:"me2"`
    Me3 []Person `json:"me3"`
}

var r Root
err = json.Unmarshal(resp.Json, &r)

// Now lets try to delete Alice. This won't delete Bob and Charlie
// but just remove the connection between Alice and them.

// The JSON for deleting a node should be of the form {"uid": "0x123"}.
// If you wanted to delete multiple nodes you could supply an array of objects
// like [{"uid": "0x321"}, {"uid": "0x123"}] to DeleteJson.

d := map[string]string{"uid": alice}
pb, err = json.Marshal(d)
if err != nil {
    log.Fatal(err)
}

mu = &api.Mutation{
    CommitNow:  true,
    DeleteJson: pb,
}

_, err = dg.NewTxn().Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}

resp, err = dg.NewTxn().QueryWithVars(ctx, q, variables)
if err != nil {
    log.Fatal(err)
}

err = json.Unmarshal(resp.Json, &r)
if err != nil {
    log.Fatal(err)
}

out, _ := json.MarshalIndent(r, "", "\t")
fmt.Printf("%s\n", out)

Output:

{
	"me": [],
	"me2": [
		{
			"name": "Bob",
			"age": 24,
			"dgraph.type": [
				"Person"
			]
		}
	],
	"me3": [
		{
			"name": "Charlie",
			"age": 29,
			"dgraph.type": [
				"Person"
			]
		}
	]
}

Code:

dg, cancel := getDgraphClient()
defer cancel()
type Person struct {
    Uid     string   `json:"uid,omitempty"`
    Name    string   `json:"name,omitempty"`
    Age     int      `json:"age,omitempty"`
    Married bool     `json:"married,omitempty"`
    Friends []Person `json:"friends,omitempty"`
    DType   []string `json:"dgraph.type,omitempty"`
}

p := Person{
    Uid:     "_:alice",
    Name:    "Alice",
    Age:     26,
    Married: true,
    DType:   []string{"Person"},
    Friends: []Person{Person{
        Name:  "Bob",
        Age:   24,
        DType: []string{"Person"},
    }, Person{
        Name:  "Charlie",
        Age:   29,
        DType: []string{"Person"},
    }},
}

op := &api.Operation{}
op.Schema = `
		name: string .
		age: int .
		married: bool .
		friends: [uid] .

		type Person {
			name: string
			age: int
			married: bool
			friends: [Person]
		}
	`

ctx := context.Background()
err := dg.Alter(ctx, op)
if err != nil {
    log.Fatal(err)
}

mu := &api.Mutation{
    CommitNow: true,
}
pb, err := json.Marshal(p)
if err != nil {
    log.Fatal(err)
}

mu.SetJson = pb
response, err := dg.NewTxn().Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}

alice := response.Uids["alice"]

variables := make(map[string]string)
variables["$id"] = alice
const q = `
		query Me($id: string){
			me(func: uid($id)) {
				name
				age
				married
				dgraph.type
				friends {
					uid
					name
					age
					dgraph.type
				}
			}
		}
	`

resp, err := dg.NewTxn().QueryWithVars(ctx, q, variables)
if err != nil {
    log.Fatal(err)
}

type Root struct {
    Me []Person `json:"me"`
}
var r Root
err = json.Unmarshal(resp.Json, &r)
if err != nil {
    log.Fatal(err)
}

op = &api.Operation{DropAttr: "friends"}
err = dg.Alter(ctx, op)
if err != nil {
    log.Fatal(err)
}

op = &api.Operation{DropAttr: "married"}
err = dg.Alter(ctx, op)
if err != nil {
    log.Fatal(err)
}

// Also lets run the query again to verify that predicate data was deleted.
resp, err = dg.NewTxn().QueryWithVars(ctx, q, variables)
if err != nil {
    log.Fatal(err)
}

r = Root{}
err = json.Unmarshal(resp.Json, &r)
if err != nil {
    log.Fatal(err)
}

// Alice should have no friends and only two attributes now.
fmt.Printf("%+v\n", r)

Output:

{Me:[{Uid: Name:Alice Age:26 Married:false Friends:[] DType:[Person]}]}

Code:

dg, cancel := getDgraphClient()
defer cancel()
// Doing a dropAll isn't required by the user. We do it here so that
// we can verify that the example runs as expected.
op := api.Operation{DropAll: true}
ctx := context.Background()
if err := dg.Alter(ctx, &op); err != nil {
    log.Fatal(err)
}

op = api.Operation{}
op.Schema = `
		name: string @index(exact) .
		age: int .
		married: bool .
		NameOrigin: string .
		Since: string .
		Family: string .
		Age: bool .
		Close: bool .
		Friends: [uid] .

		type Person {
			name
			age
			married
			NameOrigin
			Since
			Family
			Age
			Close
			Friends
		  }

		type Institution {
			name
			Since
		  }
	`

err := dg.Alter(ctx, &op)
if err != nil {
    log.Fatal(err)
}

// This example shows example for SetObject using facets.
type School struct {
    Name  string    `json:"name,omitempty"`
    Since time.Time `json:"school|since,omitempty"`
    DType []string  `json:"dgraph.type,omitempty"`
}

type Person struct {
    Uid        string   `json:"uid,omitempty"`
    Name       string   `json:"name,omitempty"`
    NameOrigin string   `json:"name|origin,omitempty"`
    Friends    []Person `json:"friends,omitempty"`

    // These are facets on the friend edge.
    Since  time.Time `json:"friends|since,omitempty"`
    Family string    `json:"friends|family,omitempty"`
    Age    float64   `json:"friends|age,omitempty"`
    Close  bool      `json:"friends|close,omitempty"`

    School []School `json:"school,omitempty"`
    DType  []string `json:"dgraph.type,omitempty"`
}

ti := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
p := Person{
    Uid:        "_:alice",
    Name:       "Alice",
    NameOrigin: "Indonesia",
    DType:      []string{"Person"},
    Friends: []Person{
        Person{
            Name:   "Bob",
            Since:  ti,
            Family: "yes",
            Age:    13,
            Close:  true,
            DType:  []string{"Person"},
        },
        Person{
            Name:   "Charlie",
            Family: "maybe",
            Age:    16,
            DType:  []string{"Person"},
        },
    },
    School: []School{School{
        Name:  "Wellington School",
        Since: ti,
        DType: []string{"Institution"},
    }},
}

mu := &api.Mutation{}
pb, err := json.Marshal(p)
if err != nil {
    log.Fatal(err)
}

mu.SetJson = pb
mu.CommitNow = true
response, err := dg.NewTxn().Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}

auid := response.Uids["alice"]
variables := make(map[string]string)
variables["$id"] = auid

const q = `
		query Me($id: string){
			me(func: uid($id)) {
				name @facets
				dgraph.type
				friends @filter(eq(name, "Bob")) @facets {
					name
					dgraph.type
				}
				school @facets {
					name
					dgraph.type
				}

			}
		}
	`

resp, err := dg.NewTxn().QueryWithVars(ctx, q, variables)
if err != nil {
    log.Fatal(err)
}

type Root struct {
    Me []Person `json:"me"`
}

var r Root
err = json.Unmarshal(resp.Json, &r)
if err != nil {
    log.Fatal(err)
}

out, _ := json.MarshalIndent(r.Me, "", "\t")
fmt.Printf("%s\n", out)

Output:

[
	{
		"name": "Alice",
		"name|origin": "Indonesia",
		"friends": [
			{
				"name": "Bob",
				"friends|since": "2009-11-10T23:00:00Z",
				"friends|family": "yes",
				"friends|age": 13,
				"friends|close": true,
				"dgraph.type": [
					"Person"
				]
			}
		],
		"friends|since": "0001-01-01T00:00:00Z",
		"school": [
			{
				"name": "Wellington School",
				"school|since": "2009-11-10T23:00:00Z",
				"dgraph.type": [
					"Institution"
				]
			}
		],
		"dgraph.type": [
			"Person"
		]
	}
]

Code:

dg, cancel := getDgraphClient()
defer cancel() // This example shows example for SetObject for predicates with list type.
type Person struct {
    Uid         string   `json:"uid"`
    Address     []string `json:"address"`
    PhoneNumber []int64  `json:"phone_number"`
    DType       []string `json:"dgraph.type,omitempty"`
}

p := Person{
    Uid:         "_:person",
    Address:     []string{"Redfern", "Riley Street"},
    PhoneNumber: []int64{9876, 123},
    DType:       []string{"Person"},
}

op := &api.Operation{}
op.Schema = `
		address: [string] .
		phone_number: [int] .

		type Person {
			Address
			phone_number
		  }
	`

ctx := context.Background()
err := dg.Alter(ctx, op)
if err != nil {
    log.Fatal(err)
}

mu := &api.Mutation{}
pb, err := json.Marshal(p)
if err != nil {
    log.Fatal(err)
}

mu.SetJson = pb
mu.CommitNow = true
response, err := dg.NewTxn().Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}

variables := map[string]string{"$id": response.Uids["person"]}
const q = `
		query Me($id: string){
			me(func: uid($id)) {
				address
				phone_number
				dgraph.type
			}
		}
	`

resp, err := dg.NewTxn().QueryWithVars(ctx, q, variables)
if err != nil {
    log.Fatal(err)
}

type Root struct {
    Me []Person `json:"me"`
}

var r Root
err = json.Unmarshal(resp.Json, &r)
if err != nil {
    log.Fatal(err)
}

// List items aren't guaranteed to be in the same order.
fmt.Println(string(resp.Json))
// {"me":[{"address":["Riley Street","Redfern"],"phone_number":[9876,123]}]}

Code:

dg, cancel := getDgraphClient()
defer cancel()

ctx, toCancel := context.WithTimeout(context.Background(), 30*time.Second)
defer toCancel()

// Warn: Cleaning up the database
if err := dg.Alter(ctx, &api.Operation{DropAll: true}); err != nil {
    log.Fatal("The drop all operation should have succeeded")
}

op := &api.Operation{}
op.Schema = `
		name: string .
		email: string @index(exact) .`
if err := dg.Alter(ctx, op); err != nil {
    log.Fatal(err)
}

m1 := `
		_:n1 <name> "user" .
		_:n1 <email> "user@dgraphO.io" .
	`
mu := &api.Mutation{
    SetNquads: []byte(m1),
    CommitNow: true,
}
if _, err := dg.NewTxn().Mutate(ctx, mu); err != nil {
    log.Fatal(err)
}

req := &api.Request{CommitNow: true}
req.Query = `
		query {
  			me(func: eq(email, "user@dgraphO.io")) {
	    		v as uid
  			}
		}
	`
m2 := `uid(v) <email> "user@dgraph.io" .`
mu.SetNquads = []byte(m2)
req.Mutations = []*api.Mutation{mu}

// Update email only if matching uid found.
if _, err := dg.NewTxn().Do(ctx, req); err != nil {
    log.Fatal(err)
}

query := `
		{
			me(func: eq(email, "user@dgraph.io")) {
				name
				email
				dgraph.type
			}
		}
	`
resp, err := dg.NewTxn().Query(ctx, query)
if err != nil {
    log.Fatal(err)
}

// resp.Json contains the updated value.
fmt.Println(string(resp.Json))

Output:

{"me":[{"name":"user","email":"user@dgraph.io"}]}

Code:

dg, cancel := getDgraphClient()
defer cancel()

// Warn: Cleaning up the database
ctx := context.Background()
if err := dg.Alter(ctx, &api.Operation{DropAll: true}); err != nil {
    log.Fatal(err)
}

type Person struct {
    Uid     string   `json:"uid,omitempty"`
    Name    string   `json:"name,omitempty"`
    Age     int      `json:"age,omitempty"`
    Email   string   `json:"email,omitempty"`
    Friends []Person `json:"friends,omitempty"`
    DType   []string `json:"dgraph.type,omitempty"`
}

op := &api.Operation{Schema: `email: string @index(exact) @upsert .`}
if err := dg.Alter(context.Background(), op); err != nil {
    log.Fatal(err)
}

// Create and query the user using Upsert block
req := &api.Request{CommitNow: true}
req.Query = `
		{
			me(func: eq(email, "user@dgraph.io")) {
				...fragmentA
			}
		}

		fragment fragmentA {
			v as uid
		}
	`
pb, err := json.Marshal(Person{Uid: "uid(v)", Name: "Wrong", Email: "user@dgraph.io"})
if err != nil {
    log.Fatal(err)
}
mu := &api.Mutation{SetJson: pb}
req.Mutations = []*api.Mutation{mu}
if _, err := dg.NewTxn().Do(ctx, req); err != nil {
    log.Fatal(err)
}

// Fix the name and add age
pb, err = json.Marshal(Person{Uid: "uid(v)", Name: "user", Age: 35})
if err != nil {
    log.Fatal(err)
}
mu.SetJson = pb
req.Mutations = []*api.Mutation{mu}
if _, err := dg.NewTxn().Do(ctx, req); err != nil {
    log.Fatal(err)
}

q := `
  		{
			Me(func: has(email)) {
				age
				name
				email
				dgraph.type
			}
		}
	`
resp, err := dg.NewReadOnlyTxn().Query(ctx, q)
if err != nil {
    log.Fatal("The query should have succeeded")
}

type Root struct {
    Me []Person `json:"me"`
}
var r Root
if err := json.Unmarshal(resp.Json, &r); err != nil {
    log.Fatal(err)
}
fmt.Println(string(resp.Json))

// Delete the user now
mu.SetJson = nil
dgo.DeleteEdges(mu, "uid(v)", "age", "name", "email")
req.Mutations = []*api.Mutation{mu}
if _, err := dg.NewTxn().Do(ctx, req); err != nil {
    log.Fatal(err)
}

resp, err = dg.NewReadOnlyTxn().Query(ctx, q)
if err != nil {
    log.Fatal("The query should have succeeded")
}
if err := json.Unmarshal(resp.Json, &r); err != nil {
    log.Fatal(err)
}

fmt.Println(string(resp.Json))

Output:

{"Me":[{"age":35,"name":"user","email":"user@dgraph.io"}]}
{"Me":[]}

func (*Txn) Query Uses

func (txn *Txn) Query(ctx context.Context, q string) (*api.Response, error)

Query sends a query to one of the connected Dgraph instances. If no mutations need to be made in the same transaction, it's convenient to chain the method, e.g. NewTxn().Query(ctx, "...").

Code:

dg, cancel := getDgraphClient()
defer cancel()

// NOTE: Best effort only works with read-only queries.
txn := dg.NewReadOnlyTxn().BestEffort()
resp, err := txn.Query(context.Background(), `{ q(func: uid(0x1)) { uid } }`)
if err != nil {
    log.Fatal(err)
}

fmt.Println(string(resp.Json))

Output:

{"q":[{"uid":"0x1"}]}

Code:

type School struct {
    Name  string   `json:"name,omitempty"`
    DType []string `json:"dgraph.type,omitempty"`
}

type Person struct {
    Uid     string   `json:"uid,omitempty"`
    Name    string   `json:"name,omitempty"`
    Age     int      `json:"age,omitempty"`
    Married bool     `json:"married,omitempty"`
    Raw     []byte   `json:"raw_bytes,omitempty"`
    Friends []Person `json:"friends,omitempty"`
    School  []School `json:"school,omitempty"`
    DType   []string `json:"dgraph.type,omitempty"`
}

dg, cancel := getDgraphClient()
defer cancel()
op := &api.Operation{}
op.Schema = `
		name: string @index(exact) .
		age: int .
		married: bool .
		Friends: [uid] .

		type Person {
			name
			age
			married
			Friends
		}

		type Institution {
			name
		}
	`

ctx := context.Background()
err := dg.Alter(ctx, op)
if err != nil {
    log.Fatal(err)
}

p := Person{
    Uid:   "_:bob",
    Name:  "Bob",
    Age:   24,
    DType: []string{"Person"},
}

txn := dg.NewTxn()
pb, err := json.Marshal(p)
if err != nil {
    log.Fatal(err)
}

mu := &api.Mutation{
    CommitNow: true,
    SetJson:   pb,
}
response, err := txn.Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}
bob := response.Uids["bob"]

// While setting an object if a struct has a Uid then its properties
// in the graph are updated else a new node is created.
// In the example below new nodes for Alice and Charlie and school are created
// (since they dont have a Uid).  Alice is also connected via the friend edge
// to an existing node Bob.
p = Person{
    Uid:     "_:alice",
    Name:    "Alice",
    Age:     26,
    Married: true,
    DType:   []string{"Person"},
    Raw:     []byte("raw_bytes"),
    Friends: []Person{{
        Uid: bob,
    }, {
        Name:  "Charlie",
        Age:   29,
        DType: []string{"Person"},
    }},
    School: []School{{
        Name:  "Crown Public School",
        DType: []string{"Institution"},
    }},
}

txn = dg.NewTxn()
mu = &api.Mutation{}
pb, err = json.Marshal(p)
if err != nil {
    log.Fatal(err)
}

mu.SetJson = pb
mu.CommitNow = true
response, err = txn.Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}

// Assigned uids for nodes which were created would be returned in the response.Uids map.
puid := response.Uids["alice"]
variables := make(map[string]string)
variables["$id"] = puid
const q = `
		query Me($id: string){
			me(func: uid($id)) {
				name
				age
				loc
				raw_bytes
				married
				dgraph.type
				friends @filter(eq(name, "Bob")) {
					name
					age
					dgraph.type
				}
				school {
					name
					dgraph.type
				}
			}
		}
	`

resp, err := dg.NewTxn().QueryWithVars(ctx, q, variables)
if err != nil {
    log.Fatal(err)
}

type Root struct {
    Me []Person `json:"me"`
}

var r Root
err = json.Unmarshal(resp.Json, &r)
if err != nil {
    log.Fatal(err)
}

out, _ := json.MarshalIndent(r, "", "\t")
fmt.Printf("%s\n", out)

Output:

{
	"me": [
		{
			"name": "Alice",
			"age": 26,
			"married": true,
			"raw_bytes": "cmF3X2J5dGVz",
			"friends": [
				{
					"name": "Bob",
					"age": 24,
					"dgraph.type": [
						"Person"
					]
				}
			],
			"school": [
				{
					"name": "Crown Public School",
					"dgraph.type": [
						"Institution"
					]
				}
			],
			"dgraph.type": [
				"Person"
			]
		}
	]
}

Code:

dg, cancel := getDgraphClient()
defer cancel()
type Person struct {
    Uid   string   `json:"uid,omitempty"`
    Name  string   `json:"name,omitempty"`
    DType []string `json:"dgraph.type,omitempty"`
}

op := &api.Operation{}
op.Schema = `
		name: string @index(exact) .

		type Person {
			name
		}
	`

ctx := context.Background()
err := dg.Alter(ctx, op)
if err != nil {
    log.Fatal(err)
}

p := Person{
    Name:  "Alice",
    DType: []string{"Person"},
}

mu := &api.Mutation{
    CommitNow: true,
}
pb, err := json.Marshal(p)
if err != nil {
    log.Fatal(err)
}

mu.SetJson = pb
_, err = dg.NewTxn().Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}

variables := make(map[string]string)
variables["$a"] = "Alice"
q := `
		query Alice($a: string){
			me(func: eq(name, $a)) {
				name
				dgraph.type
			}
		}
	`

resp, err := dg.NewTxn().QueryWithVars(ctx, q, variables)
if err != nil {
    log.Fatal(err)
}

type Root struct {
    Me []Person `json:"me"`
}

var r Root
err = json.Unmarshal(resp.Json, &r)
if err != nil {
    log.Fatal(err)
}

fmt.Println(string(resp.Json))

Output:

{"me":[{"name":"Alice","dgraph.type":["Person"]}]}

func (*Txn) QueryWithVars Uses

func (txn *Txn) QueryWithVars(ctx context.Context, q string, vars map[string]string) (
    *api.Response, error)

QueryWithVars is like Query, but allows a variable map to be used. This can provide safety against injection attacks.

Directories

PathSynopsis
protos/api

Package dgo imports 10 packages (graph) and is imported by 19 packages. Updated 2019-12-02. Refresh now. Tools for package owners.