Just to provide some examples, this also happens in DQL.
Here is an example GraphQL Schema:
GraphQL Schema
type Upper {
id: ID!
name: String @search(by: [regexp])
lowers: [Lower] @hasInverse(field: upper)
}
type Lower {
id: ID!
name: String @search(by: [regexp])
upper: Upper @hasInverse(field: lowers)
}
and here is some example data to use with the liveloader
feature:
RDF Data
<_:a1> <dgraph.type> "Upper" .
<_:a1> <Upper.name> "Upper 1" .
<_:xb> <dgraph.type> "Lower" .
<_:xb> <Lower.name> "Lower ab" .
<_:xb> <Lower.upper> <_:a1> .
<_:a1> <Upper.lowers> <_:xb> .
<_:a2> <dgraph.type> "Upper" .
<_:a2> <Upper.name> "Upper 2" .
<_:xc> <dgraph.type> "Lower" .
<_:xc> <Lower.name> "Lower abc" .
<_:xc> <Lower.upper> <_:a2> .
<_:a2> <Upper.lowers> <_:xc> .
<_:a3> <dgraph.type> "Upper" .
<_:a3> <Upper.name> "Upper 3" .
<_:xd> <dgraph.type> "Lower" .
<_:xd> <Lower.name> "Lower abcd" .
<_:xd> <Lower.upper> <_:a3> .
<_:a3> <Upper.lowers> <_:xd> .
<_:a4> <dgraph.type> "Upper" .
<_:a4> <Upper.name> "Upper 4" .
<_:xe> <dgraph.type> "Lower" .
<_:xe> <Lower.name> "Lower bdef" .
<_:xe> <Lower.upper> <_:a4> .
<_:a4> <Upper.lowers> <_:xe> .
<_:a5> <dgraph.type> "Upper" .
<_:a5> <Upper.name> "Upper 5" .
<_:xf> <dgraph.type> "Lower" .
<_:xf> <Lower.name> "Lower efg" .
<_:xf> <Lower.upper> <_:a5> .
<_:a5> <Upper.lowers> <_:xf> .
If you apply the schema, then load the data, you should be able to run the following DQL query, where we expect 2 results, but only get 1:
{
q(func: eq(dgraph.type,"Upper"), first:2) @cascade {
uid
Upper.name
Upper.lowers @filter(regexp(Lower.name, /.*a.*/)) {
uid
Lower.name
}
}
}
Same result if we query this using GraphQL (expect 2, get 1):
query {
queryUpper(first:2, offset:0) @cascade {
id
lowers(filter:{name:{regexp:"/.*a.*/"}}) {
id
name
}
}
}
Just through some further research, it appears that there may be other related issues, however, to illustrate our point, we feel that given the following GraphQL (ignoring @auth
rules):
query {
queryAccount(first:10, offset:0) @cascade {
id
client(filter:{name:{regexp:"/.*ben.*/"}}) {
name
}
}
}
we are really attempting to get the same result as this DQL:
{
var (func: type(Client)) @filter(regexp(Client.name, /.*ben.*/)) @cascade {
Client.accounts {
var flt1 as uid
}
}
accounts(func: type(Account), first: 10) @filter(uid(flt1)) {
uid
Account.name
}
}
This request should ensure that we get any clients where the name
is ‘like’ “%ben%”, ensuring that those clients returned have at least 1 account, then using the returned client uid
s, we can filter the accounts to get the top 10 that match.
We’d use the DQL, but it doesn’t respect the @auth
directive rules from the GQL Schema.