Hi everyone, I have opened issue to this on dgo github, but I feel it will get more exposure here.
The problem: updating a node causes loss of deeper nested edges using dgo.
Graph before editing quote
{
"uid": "0x2a85",
"quote": "Moon",
"car": "Lambo",
"user.contact_details": {
"contact_details.mobile": {
"phone.country_code": "+33",
"phone.national_number": "98766543"
}
}
}
Graph after editing quote
{
"uid": "0x2a85",
"quote": "Jupiter",
"car": "Lambo"
}
Update worked, but user.contact_details
edge was disconnected
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
withquote
,car
and Contact details. (All good) - Knowing UID of
User
I updatequote
. (quote
updated,car
remains, however edge to Contact details disappeared)
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 !?
}
For querying data in Ratel I use
{
u(func: uid(0x2a85)) {
uid
quote
car
user.contact_details {
contact_details.mobile {
phone.country_code
phone.national_number
}
}
}
}
Any ideas much appreciated!