Shortest path query problem

I am new to Dgraph and now exploring the tour. I created types as described on step 3 and loaded the data as in this lesson: Load Data | Intro | Dgraph Tour

I am trying to query shortest path between nodes as described in the article:

{
 path as shortest(from: 0xb, to: 0x2) {
  friend
 }
 path(func: uid(path)) {
   name
 }
}

With some node pairs it works as expected, e.g. from: 0xb (“Michael”), to: 0x1 (“Sarah”), but with others it gives weird output. Examples are:

  1. from: 0xb (“Amit”), to: 0x2 (“Hyung Sin”):
    Empty path array:
{
  "data": {
    "path": [],
    "_path_": [
      {
        "friend": {
          "friend": {
            "uid": "0x2"
          },
          "uid": "0x5"
        },
        "uid": "0xb",
        "_weight_": 2
      }
    ]
  }
  1. from: 0x4 (“Michael”), to: 0xb (“Amit”)
    Only one node in path (source only):
{
  "data": {
    "path": [
      {
        "name": "Michael"
      }
    ],
    "_path_": [
      {
        "friend": {
          "uid": "0xb"
        },
        "uid": "0x4",
        "_weight_": 1
      }
    ]
  }
  1. from: 0x4 (“Michael”), to: 0xb (“Amit”)
    Only one node in path (destination only):
{
  "data": {
    "path": [
      {
        "name": "Michael"
      }
    ],
    "_path_": [
      {
        "friend": {
          "uid": "0x4"
        },
        "uid": "0xb",
        "_weight_": 1
      }
    ]
  }

The _path_ content appears to be correct though.

It seems that only specific nodes can be shown in path (“Michael”, “Sarah” and “Catalina”) while others cannot, but I do not understand what is wrong with these nodes and how one category is different from another.

I am launching Dgraph in Docker, tested on image dgraph/dgraph, tags latest, master, v1.2.7 (all the same).

Is it a bug or I misunderstand something?

This issue seems to be relevant as it describes a specific case of my issue, but the thread suggests that it was fixed…

Setting data like below could assign a different/non-deterministic uid to nodes:

{
  set {
    _:michael <name> "Michael" .
    _:michael <dgraph.type> "Person" .
    _:michael <age> "39" .
    _:michael <friend> _:amit .

    _:amit <name> "Amit"@en .
    _:amit <dgraph.type> "Person" .
    _:amit <age> "35" .
    _:amit <friend> _:michael .
    _:amit <friend> _:sang .
  }
}

Therefore do not hardcode the uids in your shortest path query, instead you could follow this:

{ 
  var(func: eq(name, "Michael")){
   SOURCE as uid
  }
  var(func: eq(name, "Amit")){
   TARGET as uid
  }  

  path as shortest(from: uid(SOURCE), to: uid(TARGET)) {
    friend
  }
  
   path(func: uid(path)) {
    name
   } 
}

It is possible that the hardcoded uids you provide in shortest queries are assigned to some other node. You can check that by:

{
    query(func: uid("0xb")) {
    name
   } 
}
1 Like

Thanks for your suggestion Anurag, this improves readability greatly!

The UIDs are correct, do you have any thoughts on the matter of the issue? Is it a bug?

This is not a bug.
In the dataset, name field is not provided for all nodes of type Person.
The path query works well for Michael and Sarah because name field is defined for them.

For other entities like Amit, Hyung Sin, Luke, Artyom name@en field is defined using a facet.
To make the query work for them, you can either use the following shortest path query or add name field to all other entities.

{
 path as shortest(from: 0xb, to: 0x2) {
  friend
 }
 path(func: uid(path)) {
   name
   name@en
 }
}

The path query tries to see if name field is defined for the nodes on path. If it is not defined, it does not return any field for that node.

Oh… that absolutely makes sense!

Thanks for the explanation @rajas!

1 Like