PS: This is just an idea, you should not consider this as a valid or what.
Users requests:
1 Single predicate sharded across groups
2 Data Distribution Across to Servers
Not sure how good is that idea, cuz that could be done in the core level instead of a “transpile”. I believe that this post serves as an algorithm example. A transpiler would be interesting, as it would take advantage of some Dgraph features. As for example concurrency query per block.
PS. After thinking about it, I noticed that sharding at predicate level is hard for sure. Nesting for example, would make really big internal queries.
The Schema
name: String @atomShard(3000) #this will add count index too
friend: [uid] @atomShard(3000)
type User {
name : <name.dgraph.*> #This alias will be generated internally
friend : <friend.dgraph.*>
}
This means that:
The predicate “name
” will be divided into more predicates when the count reach 3k nodes.
Each new division will have an internal naming e.g:
<name.dgraph.0001>
The DQL query
The user will query
{
q(func: has(name)) @filter(eq(age, 31)) {
uid
name
}
}
Dgraph has to check if the predicate has @atomShard
directive. If so, apply the transpiling rules.
Dgraph will translate internally to
Assuming it has only two atomic shards.
<name.dgraph.0000>
and<name.dgraph.0001>
{
name_dgraph_a as var(func: has(<name.dgraph.0000>)) @filter(eq(age, 31))
name_dgraph_b as var(func: has(<name.dgraph.0001>)) @filter(eq(age, 31))
q(func: uid(name_dgraph_a, name_dgraph_b)){
uid
name
}
}
The predicate name would be solved in the schema level as a shortcut to <name.dgraph.0001>
and <name.dgraph.0000>
. e.g. Add aliases at the schema level (In type)
Edge example
{
q(func: has(name)) @filter(eq(age, 31)) {
uid
name
friend @filter(gt(age, "25")) {
uid
name
}
}
Dgraph will translate internally to
{
name_dgraph_a as var(func: has(<name.dgraph.0000>)) @filter(eq(age, 31))
name_dgraph_b as var(func: has(<name.dgraph.0001>)) @filter(eq(age, 31))
var(func: uid(name_dgraph_a, name_dgraph_b)) {
friend_dgraph_a as <friend.dgraph.0000> @filter(gt(age, "25"))
friend_dgraph_b as <friend.dgraph.0001> @filter(gt(age, "25"))
friend_dgraph_c as <friend.dgraph.0002> @filter(gt(age, "25"))
friend_dgraph_d as <friend.dgraph.0003> @filter(gt(age, "25"))
}
q(func: uid(name_dgraph_a, name_dgraph_b)){
uid
name
friend @filter(uid(friend_dgraph_a, friend_dgraph_b, friend_dgraph_c ,friend_dgraph_d)) {
uid
name
}
}
}