Moved from GitHub dgo/130
Posted by AugustDev:
I am creating a node by serializing struct and feeding to dgraph. Then I would like to update a value node of the graph by building go struct again and providing it with node UID. Even though update is successful, some edges have disappeared.
Dgo go documentation says While setting an object if a struct has a Uid then its properties in the graph are updated else a new node is created.
I am providing code which:
- Creates
User
withFavQuote
,FavCar
and Contact details. (All good) - Knowing UID of
User
I updateFavQuote
. (FavQuote
updated,FavCar
remains, however edge to Contact details disappeared)
I had no problems with such node updates before, however this time the struct is more deeply nested.
package main
import (
"context"
"encoding/json"
"fmt"
"log"
"github.com/dgraph-io/dgo/v200"
"github.com/dgraph-io/dgo/v200/protos/api"
"google.golang.org/grpc"
)
// User -
type User struct {
UID string `json:"uid,omitempty"`
DType []string `json:"dgraph.type,omitempty"`
FavQuote string `json:"quote,omitempty"`
FavCar string `json:"car,omitempty"`
ContactDetails UserContactDetails `json:"user.contact_details,omitempty"`
}
// UserContactDetails -
type UserContactDetails struct {
UID string `json:"uid,omitempty"`
DType []string `json:"dgraph.type,omitempty"`
Mobile PhoneNumber `json:"contact_details.mobile,omitempty"`
}
// PhoneNumber -
type PhoneNumber struct {
UID string `json:"uid,omitempty"`
DType []string `json:"dgraph.type,omitempty"`
CountryCode string `json:"phone.country_code,omitempty"`
NationalNumber string `json:"phone.national_number,omitempty"`
}
func main() {
conn, err := grpc.Dial("localhost:9080", grpc.WithInsecure())
if err != nil {
log.Fatal(err)
}
defer conn.Close()
dg := dgo.NewDgraphClient(api.NewDgraphClient(conn))
u := User{
UID: "_:newUser",
DType: []string{"User"},
FavQuote: "Moon",
FavCar: "Lambo",
ContactDetails: UserContactDetails{
DType: []string{"ContactDetails"},
Mobile: PhoneNumber{
DType: []string{"PhoneNumber"},
CountryCode: "+33",
NationalNumber: "98766543",
},
},
}
op := &api.Operation{}
op.Schema = `
<phone.country_code>: string @index(exact) .
<phone.national_number>: string @index(exact) .
<quote>: string .
<car>: string .
type User {
quote
car
user.contact_details: ContactDetails
}
type ContactDetails {
contact_details.mobile: PhoneNumber
}
type PhoneNumber {
phone.country_code
phone.national_number
}
`
ctx := context.Background()
if err := dg.Alter(ctx, op); err != nil {
log.Fatal(err)
}
// CREATING USER
mu := &api.Mutation{
CommitNow: true,
}
ub, err := json.Marshal(u)
if err != nil {
log.Fatal(err)
}
mu.SetJson = ub
response, err := dg.NewTxn().Mutate(ctx, mu)
if err != nil {
log.Fatal(err)
}
uid := response.Uids["newUser"]
fmt.Println("UID: " + uid)
// User correctly created with all details and can be verified in Ratel
// MODIFYING USER
u = User{
UID: uid,
FavQuote: "Jupiter",
}
mu = &api.Mutation{
CommitNow: true,
}
ub, err = json.Marshal(u)
if err != nil {
log.Fatal(err)
}
mu.SetJson = ub
_, err = dg.NewTxn().Mutate(ctx, mu)
if err != nil {
log.Fatal(err)
}
// User updated `FavQuote`. "FavCar" remains however contact details edge from user have dissapeared !?
}
To check data in Ratel I use
{
u(func: uid(0x2a85)) {
uid
quote
car
user.contact_details {
contact_details.mobile {
phone.country_code
phone.national_number
}
}
}
}
Graph before modifying user
{
"uid": "0x2a85",
"quote": "Moon",
"car": "Lambo",
"user.contact_details": {
"contact_details.mobile": {
"phone.country_code": "+33",
"phone.national_number": "98766543"
}
}
}
Graph after modifying user
{
"uid": "0x2a85",
"quote": "Jupiter",
"car": "Lambo"
}
Which no longer has contact details