Edge not created between two nodes

I’m trying to create an edge between two nodes that should have two facets set on it using dgo client, however, I’m failing miserably.

The code I’m trying to put together is seemingly rather simple and I’ve run out of ideas about what I’m doing wrong so I’m hoping some DGraph guru can give me a hand here.

I have the following schema

	type Entity {
		xid
		name
		namespace
		links
	}

	type Resource {
		name
		group
		version
		kind
		namespaced
	}

	xid: string @index(exact) .
	name: string @index(exact) .
	namespace: string @index(exact) .
	links: [uid] @count @reverse .
	created_at : datetime @index(hour) .
	group: string @index(exact) .
	version: string @index(exact) .
	kind: string @index(exact) .
	namespaced: bool .

Mapped to the following Go types:

type Resource struct {
	Name       string            `json:"name,omitempty"`
	Group      string            `json:"group,omitempty"`
	Version    string            `json:"version,omitempty"`
	Kind       string            `json:"kind,omitempty"`
	Namespaced bool              `json:"namespaced,omitempty"`
	DType      []string          `json:"dgraph.type,omitempty"`
}

type Entity struct {
	UID       string            `json:"uid,omitempty"`
	XID       string            `json:"xid,omitempty"`
	Name      string            `json:"name,omitempty"`
	Namespace string            `json:"namespace,omitempty"`
	Resource  Resource          `json:"resource,omitempty"`
	Links     []Entity          `json:"links,omitempty"`
	DType     []string          `json:"dgraph.type,omitempty"`

	// Links facets
	Relation string  `json:"links|relation,omitempty"`
	Weight   float64 `json:"links|weight,omitempty"`
}

Now, here’s the code which I was hoping it would create a link between two entities which were previously successfully stored in Dgraph:

	query := `
	{
		from as var(func: eq(xid, "` + from.Value() + `")) {
			fid as uid
		}

		to as var(func: eq(xid, "` + to.Value() + `")) {
			tid as uid
		}
	}
	`
	weight := 1.0
	relation := "Test"

	node := &Entity{
		UID:   "uid(fid)",
		DType: []string{"Entity"},
		Links: []Entity{
			{UID: "uid(tid)", DType: []string{"Entity"}, Relation: relation, Weight: weight},
		},
	}

	pb, err := json.Marshal(node)
	if err != nil {
		return fmt.Errorf("link json marshal: %w", err)
	}

	mu := &dgapi.Mutation{
		Cond:    `@if(gt(len(from), 0) AND gt(len(to), 0))`,
		SetJson: pb,
	}

	req := &dgapi.Request{
		Query:     query,
		Mutations: []*dgapi.Mutation{mu},
		CommitNow: true,
	}

	txn := s.c.NewTxn()

	var txnErr error
	defer func() { txnErr = txn.Discard(ctx) }()

	if _, err := txn.Do(ctx, req); err != nil {
		return fmt.Errorf("txn Link: %w", err)
	}

What I expect to happen is the edge is created between the two nodes. Funnily enough, the code succeeds without any errors, but when I query Dgraph for all the nodes including links and facets I get no links back (obviously, because of that I get no facets, either :slight_smile: )

{
  q(func: has(xid)) {
   uid
   links @facets
  }
}

The response I get back is following:

{
  "data": {
    "q": [
      {
        "uid": "0x2758"
      },
      {
        "uid": "0x275a"
      }
    ]
  },
  "extensions": {
    "server_latency": {
      "parsing_ns": 158600,
      "processing_ns": 3006400,
      "encoding_ns": 75800,
      "assign_timestamp_ns": 3160700,
      "total_ns": 6856100
    },
    "txn": {
      "start_ts": 10423
    },
    "metrics": {
      "num_uids": {
        "_total": 4,
        "links": 2,
        "uid": 2,
        "xid": 0
      }
    }
  }
}

Suspiciously enough I can see that the links might exist, at least judging by what I can see in metrics key in the response json. What I’d expect based on the docs is something like this

...
"data": {
    "q": [
      {
        "uid": "0x2758"
      },
      {
        "uid": "0x275a"
        "links|relation": "Test"
        "links|weight": 1.0
      }
    ]
...

Hey @milosgajdos, fancy bumping into you here!

I have reproduced your issue. However I see that in my version of Dgraph, things are correctly linked:

{
  "data": {
    "q": [
      {
        "uid": "0x2715",
        "xid": "foo",
        "name": "foo",
        "links": [
          {
            "uid": "0x2716",
            "links|relation": "Test",
            "links|weight": 1
          }
        ]
      },
      {
        "uid": "0x2716",
        "xid": "bar",
        "name": "bar"
      }
    ]
  },
  "extensions": {
    "server_latency": {
      "parsing_ns": 121906,
      "processing_ns": 635903,
      "encoding_ns": 164214,
      "assign_timestamp_ns": 790831,
      "total_ns": 1820709
    },
    "txn": {
      "start_ts": 10060
    },
    "metrics": {
      "num_uids": {
        "_total": 9,
        "links": 2,
        "name": 2,
        "uid": 3,
        "xid": 2
      }
    }
  }
}

I do note though that your query needs a bit of work. If you use the following, you would be able to get the facets data.

{
  q(func: has(xid)) {
   uid
   xid
   name
   links @facets {uid}  
  }
}

:wave: @chewxy small world :slight_smile:

Oh, this missing links block that actually returns the link.

Thanks, this makes sense.