Building a dynamic query using recursion

Hi :waving_hand:, I’ve been playing around with Elixir and its ecosystem for a few weeks now and I really like it so far. Also, this is my first post here so please bear with me :man_bowing:t2:.

I’m trying to mimic how Amazon’s Amplify generates the filters for its GraphQL schemas using Absinthe.
So far I was able to get ne, eq, le, ge, gt, contains, and between to work. The hard part, however, is implementing and, or, and not (lines 88 - 90) since it involves recursion and Ecto.

I’ve created a small repl.it that shows what I’ve tried so far (maybe lots of code commented off as well :sweat_smile:). In the repl.it, I’m using strings to abstract things but the goal is to use Ecto’s dynamic query feature.

The input will look something like this:

input = %{
  and: [%{ and: [%{ b: %{ eq: "4"}}], c: %{ eq: "3"}}],
  or: [%{ d: %{ eq: "2"}}],
  a: %{ eq: "1"}
}

and the output will be expressed as something like:

# a and (b == 4 and c == 3) or (d == 2)

I think I’m on the right track. I know that I eventually have to reduce a tree-like structure to a single query, but I’m not sure how to deal with a binary operator such and and or within Enum.reduce so any help would be greatly appreciated.

Thank you.

Random thought:

I think it would be super neat if Absinthe could just build the tables and hook everything up including filtering, relay, etc with just a schema like Amplify… this would be a game changer.