Solveddgraph Support 1 to 1 associations at the schema level
โ๏ธAccepted Answer
Hmm... This looks like a very convincing argument. In essence, if you can have multiple edges from one node to another, the schema must be defined as [uid]
, and the result would be a list of JSON objects. Otherwise, if defined as uid
, then there can only be at most one edge and the result would be a JSON map.
I haven't thought through all the implications of this, but as an initial thought, it makes a lot of sense to be this way.
Other Answers:
Closing as the fix has been submitted. Feature should be available starting with the 1.1 release.
Given this is a breaking change, we will make it part of v1.1 release. Eta Jan 2019.
Dgraph stores values and nodes in posting list format. Multiple values for the same (sub, pred) are stored in a single posting list. Similarly, multiple nodes for the same (sub, pred) are stored in a single posting list as well.
We currently enforce that there's only one value when a user specifies a non-list data type (like string, or int). When a user specifies a list type (like [string]), then the posting list holds all the elements of the list in a single posting list object.
Currently, we don't enforce the singularity of a uid type in a posting list, and so for a node connection, a posting list can hold as many uids as provided. With this proposal, uid type would also start to enforce a single uid per posting list for the predicate. Hope that sheds some light on the internals.
Me and another member of the dgraph forum have been going back and forth on how exactly this should be done. Feel free to read
https://discuss.dgraph.io/t/return-single-object-instead-array-for-exactly-one-relation-between-node/2927/7
The solution proposed by bennyrio (the person I've been talking to in the forum) was elaborated on after creating this. I do not want to misrepresent his view on this so below is a direct link to his explanation:
https://discuss.dgraph.io/t/return-single-object-instead-array-for-exactly-one-relation-between-node/2927/8
The essence of my request is that I think we should change the schema so that uid associations are capable of being defined as 1 to 1. Unfortunately, my proposal will be a breaking change, but I think it will make uid predicates consistent with the other predicate types.
Currently a schema of this:
Exhibits these behaviors:
a is capable of returning 0 or more nodes
b is capable of returning 0 or more strings
c is capable of returning 0 or 1 integers
My proposal would look like this:
Exhibiting these behaviors:
a is capable of returning 0 or 1 nodes
b is capable of returning 0 or more strings
c is capable of returning 0 or 1 integers
d is capable of returning 0 or more nodes
This would also require that any mutation which would violate this 1 to 1 association should abort with an error.
This would also mean that existing schemas would have to be updated, but I believe this will make for consistency across all predicates types when defining a list vs a single item.