I am building a query that use dynamics and then interpolate it in the join. I build it successfully. But I want to include dynamics for multiple fields .The reduce function iterates over the map take the fields and build a dynamic query. Here is my code so far:
Enum.reduce(additional_join, true, fn {field, map}, query ->
query =
if Map.has_key?(map, "$in") do
query = dynamic([q], field(q, ^String.to_atom(field)) in ^map["$in"] and ^query)
else
query
end
if Map.has_key?(map, "$between_equal") do
query =
dynamic(
[q],
field(q, ^FatHelper.string_to_existing_atom(field)) >= ^Enum.min(map["$between_equal"]) and
field(q, ^FatHelper.string_to_existing_atom(field)) <= ^Enum.max(map["$between_equal"]) and
^query
)
else
query
end
end)
These are the params:
"$additional_on_clauses" => %{
"event_date" => %{"$between_equal" => [start_date, end_date]}
}
"$additional_on_clauses" => %{
"infection_category_id" => %{"$in" => category_ids},
"event_date" => %{"$between_equal" => [start_date, end_date]}
}
It only takes the last map in the above params and returns the query. I think reduce is a better way but i don’t have any idea how to use the dynamics inside of it.
I want dynamics to include both the above maps inside additional_on_clauses
.
If I take the common part of the query outside of the reduce function and pass dynamics in the acc It won’t work because Enum not implemented for dynamics. dynamic([q, c], q.id == c.infection_id)
. I can’t use this as an accumulator.
Is there any other way I can build composite dynamic query with multiple dynamic conditions.?
Any help/suggestion will be much appreciated.
Thanks