I’m struggling to find a graceful way to accomplish the following. I need to use the UID_IN function with dynamic input. Per the docs, UID_IN can take only a UID literal rather than a variable.
When running queries, I need to filter to a subgraph based on user permissions and user selected filters. So I would like to run:
var(func: uid([USER UID])) {
validNs as HasAccessToNamespace
filteredNs as FiltersOutNamespace
}
results(func: eq(VertexType, "Entity")) @filter(UID_IN(Namespace, uid(validNs)) and NOT UID_IN(Namespace, (filteredns))) {
....
}
Currently, I have to run two dgraph queries…one to get validNs and filteredNs so that I can build a string of form:
@filter(UID_IN(Namespace, [UID1]) and UID_IN(Namespace, [UID2]) ... and UID_IN(Namespace, UIDn))
To then concatenate into the second query.
This seems unnecessary because the first query should resolve before the 2nd runs, meaning that when the second query runs, the input to UID_IN can be treated as constant values? Maybe there is a better way to do this that I’m not thinking of?
Thanks @pawan, this almost gets me there. The one issue is in this scenario I cannot guarantee that all of the other predicates I am returning in the results() block will be present, which in this case, using @cascade, would cause that entire result to fall out of the query, right? Not a huge deal as I can probably code around this to make sure all other attributes are present…but might be nice to be able to exclude certain predicates from the @cascade treatment.
You can request the _uid_ as that is guaranteed to be present, so then Entities which have both a _uid_ and len(Namespace) > 0 would be returned. Does that work for you?
To make sure I understand…If I run this modified query:
{
var(func: uid(USER_UID)) {
validNs as HasAccessToNamespace
filteredNs as FiltersOutNamespace
}
results(func: eq(VertexType, "Entity")) @cascade {
uid: _uid_
name
description
externalId
Namespace @filter(not uid(filteredNs) and uid(validNs))
}
}
If externalId is missing for a result, but all other attributes are present, would that result still be excluded by @cascade due to a missing externalId?
Yes if external id is missing for an entity it would be missing from the result. Basically, all children should have some value/uids for it to present in the result. You can get around that by using another query block if you like.
filteredResults as var(func: eq(VertexType, "Entity")) @cascade {
uid: _uid_
Namespace @filter(not uid(filteredNs) and uid(validNs))
}
results(func: uid(filteredResults)) {
...
# All that you want to retrieve here.
}
For anyone else looking for a solution, here’s the final query:
var(func: uid([USER UID])) {
validNs as HasAccessToNamespace
filteredNs as FiltersOutNamespace
}
filteredResults as var(func: eq(VertexType, "Entity")) @cascade {
uid: _uid_
Namespace @filter(not uid(filteredNs) and uid(validNs))
}
finalResults(func: uid(filteredResults)) {
...
# All that you want to retrieve here.
}