Revisit index syntax for new Type System

Hi Dgraph team,

Now that Dgraph has a Type System, is there a plan to revisit how predicate indexes are defined?

The Problem

type Player {
  name: string // want exact match here
  score: int
}
type Game {
  name: string // want term match here
}
<name>: string @index(exact, term) .

Player.name and Game.name are functionally independent predicates. The system may have 12 games and 1.2M players. This default approach will generate an index of at least 1.2M unnecessary terms from player names.

Workaround

A workaround is to add prefixes to predicate names:

...
type Game {
  Game.name: string
}
...
<Game.name>: string @index(term) .
<Player.name>: string @index(exact) .

Although this “prefixing” works, it breaks from GraphQL convention and leads to redundancy and verbosity in queries and mutations, e.g.:

q(func:type(Player)) {
  Player.name
  Player.score
  games {
    Game.name
  }
}

Proposed Solution

Ideally, we’d be able to define the indexes within the Dgraph type definition using GraphQL directives:

type Player {
  name: string @index(with: "exact")
  score: int
}
type Game {
  name: string @index(with: "term")
}

Multiple indexes could be added as:

type Game {
  name: string @index(with: ["term", "fulltext"])
}

@mrjn thoughts? Are we missing something?

Zak

1 Like

There’s a good point here about the wasted space of generating indices for the name predicate which is only required by one type but not the other.

CC: @michaelcompton

@michaelcompton any plans to revisit/resolve this concern of name conflicts for predicates and indices?

We use gverse JS library in our products which has it’s own type system for Dgraph 1.0.x. We are now upgrading to Dgraph 1.1 but this question remains an open design issue for us.

Hi Zak,

Thanks for the question.

If you look at our native GraphQL support https://graphql.dgraph.io/, it uses a similar system to what you are thinking of above. We then internally prefix edges with type names. That means it solves the problem a bit like you describe, but doesn’t have any of the drawbacks that you point out.

I’m not sure how we’d bubble that down into Dgraph. Your suggestion looks ok, but it’s edges, not types, that are the base thing in Dgraph, so I’m wondering how edges would be defined outside of types, or how multiple types could share the same edge.

In any case, I wonder if our GraphQL might be what you need anyway. Take a look and let me know if it’s missing bits you need.