Skip to content

Instantly share code, notes, and snippets.

@ptpaterson
Last active July 8, 2019 19:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ptpaterson/b44176bfe58ec0e3e0ef5f6c1ef5a155 to your computer and use it in GitHub Desktop.
Save ptpaterson/b44176bfe58ec0e3e0ef5f6c1ef5a155 to your computer and use it in GitHub Desktop.

I need forward & backwards links between instances, properties on these "links", and they must be able to connect to many classes. I wish to query return the result for a GraphQL resolver, so I need to compose the results in one nice js object.

NOTE: lack of polymorphic types is why I am building my own GraphQL server. I need relationships to multiple types.

Would anyone have some guidance for how to do this the faunaDB way.

Example attempt at retrieving link information:

You may want to track a list of favorite toys and activities for your family (please don't judge test schema 😋).

with classes (with rough schemas):

  • members: { name: String, age: Int, ... }
  • toys: { title: String, bin: String, ... }
  • activities: { title: String, inside: Bool, ... }
  • favorites_link: { from: Ref(Class("members")), to: Ref(Class("toys")) | Ref(Class("activities")), ... }

with class index, all_members, and additional indexes

{
  ...
  "name": "favorites_link_out",
  "source": Class("favorites_link"),
  "terms": [{
    "field": ["data", "from" ]
  }]
  ...
}

{
  ...
  "name": "favorites_link_in",
  "source": Class("favorites_link"),
  "terms": [{
    "field": ["data", "to" ]
  }]
  ...
}

I am having trouble with the query to get all members and their list of activities. The result I want:

// returns a page
{
  data: 
    // array of members
    [
      {
        // member properties
        name: "Peter",
        age: 3,
        // linked values
        favorites: [
          // toy properties
          { title: "Blocks", bin: "Toy Chest" },
          // activity properties
          { title: "Bubbles", inside: false }
        ]
      },

      // another member (dogs are absolutely family members!)
      {
        name: "Fido",
        age: 6,
        favorites: [
          { title: "Squeaky Ball", bin: "Dog Basket" },
          { title: "Bubbles", inside: false }
        ]
      }
    ]
}
    

The query I am attempting:

Let(
  {
    // top level query
    members: Paginate(Match(Index("")))
  },

  // top level returns array.  Map over to return each result
  Map(
    Var("members"),
    Lambda(
      "members__ref",

      // compute values for properties and relationships
      Let(
        {
          // resolve ref to use multiple places
          members__it: Get(Var("members__ref")),

          // select individual properties
          members_name: Select(["data", "name"], Var("members_it")),
          members_age: Select(["data", "age"], Var("members_it")),

          /* moving in this direction does not seem to work like I thought it would */
          members_favorites: Map(
            Match(Index("favorites_link_out"), Var("members__ref")), // something wrong here?
            Lambda( /* logic to get either toy or activity properties */ )
          )
        },

        // return final result
        {
          name: Var("members_name"),
          age: Var("members_age"),
          favorites: Var("members_favorites")
        }
      )
    )
  )
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment