Version: 20.11.2
Client: Go
This may be a bug, but I’ll start this out as a question. We have a very particular set of requirements on the graph structure we store in dgraph. Nearly all the [uid] predicates we have in our Types are @reverse indexed and what we want to do is select a node and query for everything connected to it by either a forward or reverse [uid] predicate. We have a custom versioning scheme on top of this that sandwhiches an extra node in between two uids and we assign a least one Type we call “ConnVersion” and if that version is the latest, we also add a Type “Latest”. The reason we add the latest type is we don’t know a priori which predicates we want to find the connection for so we expand(all) to get outgoing predicates from that node. This means we can’t filter based on a boolean prediate such as “latest” and instead filter on a Type “Latest” that is set on the latest ConnVersion node. In the end it looks something like this. For a connection between node A and B:
schema:
<predicate_name>: [uid] @reverse .
type PredicateType {
<predicate_name>
<~predicate_name>
}
type ConnVersion {
}
type Latest {
}
A —predicate_name—> C —predicate_name—>B
A —predicate_name—> C’ —predicate_name—>B
A, B, and C, and C’ has some type “PredicateType” that includes both <predicate_name> and <~predicate_name>.
C also has a Type ConnVersion and Latest.
C’ has dgraph.type ConnVersion, but DOES NOT have draph.type Latest
Let’s assume this is the entire graph.
If I query for connections on A, I do query like
{
connections(func:uid(0xa)) {
uid
expand(_all_) @filter(type(ConnVersion) AND type(Latest)) {
uid
expand(_all_) {
uid
expand(_all_) {
uid
}
}
}
}
}
Which gets me all forward and reverse connections that connect A and B, but removes the path that includes C’. This is perfect.
The problem comes when I do the same exact query, but starting with node B:
{
connections(func:uid(0xb)) {
uid
expand(_all_) @filter(type(ConnVersion) AND type(Latest)) {
uid
expand(_all_) {
uid
expand(_all_) {
uid
}
}
}
}
}
This ONLY returns B and nothing else. If I remove the @filter
:
{
connections(func:uid(0xb)) {
uid
expand(_all_) {
uid
expand(_all_) {
uid
expand(_all_) {
uid
}
}
}
}
}
I get everything, but I also get C’. The point of those filters is so that I only get C, not C’. This feels like a bug to me, but we thought maybe this was by design? If so, why? Are there any workarounds for our use case that you can think of?