Graph Traversal

    The first step is to generate the 3 schemas: , User, Group.

    Add the necessary fields and edges for the schemas:

    ent/schema/pet.go

    1. // Pet holds the schema definition for the Pet entity.
    2. type Pet struct {
    3. ent.Schema
    4. }
    5. // Fields of the Pet.
    6. func (Pet) Fields() []ent.Field {
    7. return []ent.Field{
    8. field.String("name"),
    9. }
    10. }
    11. // Edges of the Pet.
    12. func (Pet) Edges() []ent.Edge {
    13. return []ent.Edge{
    14. edge.To("friends", Pet.Type),
    15. edge.From("owner", User.Type).
    16. Ref("pets").
    17. Unique(),

    ent/schema/group.go

    1. // Group holds the schema definition for the Group entity.
    2. type Group struct {
    3. ent.Schema
    4. }
    5. // Fields of the Group.
    6. func (Group) Fields() []ent.Field {
    7. return []ent.Field{
    8. field.String("name"),
    9. }
    10. }
    11. // Edges of the Group.
    12. func (Group) Edges() []ent.Edge {
    13. return []ent.Edge{
    14. edge.To("users", User.Type),
    15. edge.To("admin", User.Type).
    16. Unique(),
    17. }

    Let’s write the code for populating the vertices and the edges to the graph:

    Let’s go over a few traversals, and show the code for them:

    er-traversal-graph-gopher

    1. func Traverse(ctx context.Context, client *ent.Client) error {
    2. owner, err := client.Group. // GroupClient.
    3. Query(). // Query builder.
    4. Where(group.Name("Github")). // Filter only Github group (only 1).
    5. QueryAdmin(). // Getting Dan.
    6. QueryFriends(). // Getting Dan's friends: [Ariel].
    7. QueryPets(). // Their pets: [Pedro, Xabi].
    8. QueryFriends(). // Pedro's friends: [Coco], Xabi's friends: [].
    9. QueryOwner(). // Coco's owner: Alex.
    10. Only(ctx) // Expect only one entity to return in the query.
    11. if err != nil {
    12. return fmt.Errorf("failed querying the owner: %w", err)
    13. }
    14. fmt.Println(owner)
    15. // Output:
    16. // User(id=3, age=37, name=Alex)
    17. return nil
    18. }

    What about the following traversal?

    We want to get all pets (entities) that have an owner (edge) that is a (edge) of some group admin (edge).

    The full example exists in GitHub.