Weird behavior of reverse edge on one-to-one relation

Hi, everyone!

A month ago DGraph got an ability to set up 1-to-1 relations between nodes on a schema level (here’s the PR). That’s a great feature, and I wanted to incorporate it in my schema too.

However, I faced a strange behavior, when I query the reverse edge of such 1-to-1 relation. Here’s the schema I use:

<amount>: int .
<name>: string @index(exact) .
<op.destination>: uid @reverse .
<op.source>: uid @reverse .

And here’s the data:

{
  set {
      _:u1 <name> "Alice" .
      _:u2 <name> "Bob" .
      _:u3 <name> "Charlie" .
  
      _:op1 <amount> "1000" .
      _:op1 <op.source> _:u1 .
      _:op1 <op.destination> _:u2 .
  
      _:op2 <amount> "250" .
      _:op2 <op.source> _:u1 .
      _:op2 <op.destination> _:u3 .
    
      _:op3 <amount> "430" .
      _:op3 <op.source> _:u2 .
      _:op3 <op.destination> _:u1 .
  }
}

I want to get all operations, issued by Alice (that should be two operations). I send this query:

{
  alice_operations(func: eq(name, "Alice")) {
    ~op.source {
      amount
      op.destination { name }
    }
  }
}

That query returns me the next piece of data:

{
  "alice_operations": [
    {
      "uid": "0xde2c5",
      "~op.source": {
        "op.destination": {
          "name": "Bob"
        },
        "amount": 1000
      }
    }
  ]
}

So I’ve got a single object instead of an expected array. Also, it seems that the result varies between different data loading.

The more weird result I get, if I query only one predicate on ~op.source:

Query

{
  alice_operations(func: eq(name, "Alice")) {
    uid
    ~op.source {
      amount
    }
  }
}

Response

{
  "alice_operations": [
     {
       "uid": "0xde2c5",
       "~op.source": {
         "amount": [
           250,
           1000
         ]
       }
     }
  ]
}

I still got only one object in response, but now for some reason, amount predicate is an array. For me, it was entirely unexpected.

Is it a bug or I don’t understand something?

I realize that this particular feature isn’t released yet, I ran all of the examples above on the master branch of DGraph (I used go get ... command to install it)

I tried to find any tests on such cases in the codebase, but no luck. However, I am a total newbie to DGraph code so I might overlook it easily

Those features are not ready yet. I do not recommend using them.
Use only the binaries provided via Release page and Docker Hub.

Anyway, I’m going to look into the case. For it seems quite strange indeed.

Thanks for your report. I took a look and this turned indeed to be a bug. In query.go we were treating the reverse of a non-list predicate as a non-list predicate when it should be treated as a list as your example shows. That’s why only one of the results were being shown. The bug fix also fixed the second query that was provided.

PR with the fix: Fix bug retrieving reverse edges of non-list uid predicates. by martinmr · Pull Request #3005 · dgraph-io/dgraph · GitHub

2 Likes

I can see that PR above was merged, and I just tested examples I wrote here — all seem to work properly! Thank you for such quick fix!

1 Like