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:

package main

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

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

type School struct {
    Name string `json:"name,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"`
}

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{
        Name:    "Alice",
        Age:     26,
        Married: true,
        Location: loc{
            Type:   "Point",
            Coords: []float64{1.1, 2},
        },
        Dob: &dob,
        Raw: []byte("raw_bytes"),
        Friends: []Person{{
            Name: "Bob",
            Age:  24,
        }, {
            Name: "Charlie",
            Age:  29,
        }},
        School: []School{{
            Name: "Crown Public School",
        }},
    }

    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)
    }

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

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

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

    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.Printf("Me: %+v\n", r.Me)
    // R.Me would be same as the person that we set above.

    fmt.Println(string(resp.Json))
}

Index

Examples

Package Files

client.go doc.go txn.go

Variables

var (
    ErrFinished = errors.New("Transaction has already been committed or discarded")
    ErrReadOnly = errors.New("Readonly transaction cannot run mutations or be committed")
)

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. It must be done by the user after the function returns.

Code:

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)

op := &api.Operation{}
op.Schema = `
			age: int .
			married: bool .
			name: string @lang .
			location: 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"`
}

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"`
}

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

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

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

alice := assigned.Uids["blank-0"]

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

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", "loc")

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)
fmt.Println(string(resp.Json))

Output:

{"me":[{"name":"Alice","age":26,"married":true,"schools":[{"name@en":"Crown Public School"}]}]}

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 for interacting with the Dgraph store connected to in conns. The client can be backed by multiple connections (to the same server, or multiple servers in a cluster).

A single client is thread safe for sharing with multiple go routines.

func (*Dgraph) Alter Uses

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

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

1. Modify the schema.

2. Drop a predicate.

3. Drop the database.

Code:

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)

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

fmt.Println(err)

Output:

<nil>

func (*Dgraph) GetContext Uses

func (d *Dgraph) GetContext(ctx context.Context) context.Context

func (*Dgraph) Login Uses

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

func (*Dgraph) NewReadOnlyTxn Uses

func (d *Dgraph) NewReadOnlyTxn() *Txn

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) 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.

func (*Txn) Mutate Uses

func (txn *Txn) Mutate(ctx context.Context, mu *api.Mutation) (*api.Assigned, 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 subsequently be made.

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"`
}

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:"friend,omitempty"`
    Location loc      `json:"loc,omitempty"`
    School   []School `json:"school,omitempty"`
}

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)

// 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{
    Name:    "Alice",
    Age:     26,
    Married: true,
    Location: loc{
        Type:   "Point",
        Coords: []float64{1.1, 2},
    },
    Raw: []byte("raw_bytes"),
    Friends: []Person{{
        Name: "Bob",
        Age:  24,
    }, {
        Name: "Charlie",
        Age:  29,
    }},
    School: []School{{
        Name: "Crown Public School",
    }},
}

op := &api.Operation{}
op.Schema = `
		age: int .
		married: bool .
	`

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
assigned, err := dg.NewTxn().Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}

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

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)
}

// R.Me would be same as the person that we set above.
// fmt.Printf("Me: %+v\n", r.Me)

fmt.Println(string(resp.Json))

Output:

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

Code:

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)

type Person struct {
    Uid   string `json:"uid,omitempty"`
    Name  string `json:"name,omitempty"`
    Bytes []byte `json:"bytes,omitempty"`
}

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

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

p := Person{
    Name:  "Alice-new",
    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
	}
}`

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]}]

Code:

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)

// 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:"friend,omitempty"`
}

p := Person{
    Name:    "Alice",
    Age:     26,
    Married: true,
    Friends: []*Person{&Person{
        Name: "Bob",
        Age:  24,
    }, &Person{
        Name: "Charlie",
        Age:  29,
    }},
}

op := &api.Operation{}
op.Schema = `
		age: int .
		married: bool .
	`

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
assigned, err := dg.NewTxn().Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}

alice := assigned.Uids["blank-0"]
bob := assigned.Uids["blank-1"]
charlie := assigned.Uids["blank-2"]

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
			friend {
				uid
				name
				age
			}
		}

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

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

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)
}
fmt.Printf("Resp after deleting node: %+v\n", string(resp.Json))

Output:

Resp after deleting node: {"me":[],"me2":[{"name":"Bob","age":24}],"me3":[{"name":"Charlie","age":29}]}

Code:

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)

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:"friend,omitempty"`
}

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

op := &api.Operation{}
op.Schema = `
		age: int .
		married: bool .
	`

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
assigned, err := dg.NewTxn().Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}

alice := assigned.Uids["blank-0"]

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

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: "friend",
}
err = dg.Alter(ctx, op)
if err != nil {
    log.Fatal(err)
}

op.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("Response after deletion: %+v\n", r)

Output:

Response after deletion: {Me:[{Uid: Name:Alice Age:26 Married:false Friends:[]}]}

Code:

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)

// 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) .
	`

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"`
}

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

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

    School []School `json:"school,omitempty"`
}

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

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

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

auid := assigned.Uids["blank-0"]
variables := make(map[string]string)
variables["$id"] = auid

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

    }
}`

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.Printf("Me: %+v\n", r.Me)

Output:

Me: [{Name:Alice NameOrigin:Indonesia Friends:[{Name:Bob NameOrigin: Friends:[] Since:2009-11-10 23:00:00 +0000 UTC Family:yes Age:13 Close:true School:[]}] Since:0001-01-01 00:00:00 +0000 UTC Family: Age:0 Close:false School:[{Name:Wellington School Since:2009-11-10 23:00:00 +0000 UTC}]}]

Code:

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)
// 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"`
}

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

op := &api.Operation{}
op.Schema = `
		address: [string] .
		phone_number: [int] .
	`
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
assigned, err := dg.NewTxn().Mutate(ctx, mu)
if err != nil {
    log.Fatal(err)
}

variables := map[string]string{"$id": assigned.Uids["blank-0"]}
const q = `
	query Me($id: string){
		me(func: uid($id)) {
			address
			phone_number
		}
	}
	`

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]}]}

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:

type School struct {
    Name string `json:"name,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:"friend,omitempty"`
    School  []School `json:"school,omitempty"`
}

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)

op := &api.Operation{}
op.Schema = `
		age: int .
		married: bool .
	`

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

p := Person{
    Name: "Bob",
    Age:  24,
}

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

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

// 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{
    Name:    "Alice",
    Age:     26,
    Married: true,
    Raw:     []byte("raw_bytes"),
    Friends: []Person{{
        Uid: bob,
    }, {
        Name: "Charlie",
        Age:  29,
    }},
    School: []School{{
        Name: "Crown Public School",
    }},
}

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

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

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

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","age":26,"raw_bytes":"cmF3X2J5dGVz","married":true,"friend":[{"name":"Bob","age":24}],"school":[{"name":"Crown Public School"}]}]}

Code:

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)

type Person struct {
    Uid  string `json:"uid,omitempty"`
    Name string `json:"name,omitempty"`
}

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

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

p := Person{
    Name: "Alice",
}

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
		}
	}`

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"}]}

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.

func (*Txn) Sequencing Uses

func (txn *Txn) Sequencing(sequencing api.LinRead_Sequencing)

Directories

PathSynopsis
protos/api
x
yPackage y contains the code shared by the Go client and Dgraph server.

Package dgo imports 8 packages (graph) and is imported by 10 packages. Updated 2018-12-07. Refresh now. Tools for package owners.