leaf

leaf

Use dynamics as an acc in reduce

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

Marked As Solved

peerreynders

peerreynders

This code strongly suggests that the problem is somewhere else in your code (something that you aren’t showing or even looking at):

defmodule Demo do
  def run(additional_on_clauses) do
    Enum.reduce(additional_on_clauses, true, fn {field, map}, query ->
      query =
        if Map.has_key?(map, "$in") do
          # dynamic([q], field(q, ^String_to_atom(field)) in ^map["$in"] and ^query)
          "#{field} in #{inspect(map["$in"])} and #{query}"
        else
          query
        end

      if Map.has_key?(map, "$between_equal") do
        # dynamic([q],
        #  field(q, ^String_to_existing_atom(field)) >= ^Enum.min(map["$between_equal"]) and
        #  field(q, ^String_to_existing_atom(field)) <= ^Enum.max(map["$between_equal"]) and
        #  ^query
        # )
        "#{field} >= #{Enum.min(map["$between_equal"])} and " <>
          "#{field} <= #{Enum.max(map["$between_equal"])} and " <>
          "#{query}"
      else
        query
      end
    end)
  end
end

data = %{
  "$additional_on_clauses" => %{
    "event_date" => %{"$between_equal" => [~N[2019-05-03 00:00:00], ~N[2019-05-04 00:00:00]]},
    "infection_category_id" => %{"$in" => [2, 3, 4]}
  }
}

data["$additional_on_clauses"]
|> Demo.run()
|> IO.inspect()
$ elixir demo.exs
"infection_category_id in [2, 3, 4] and event_date >= 2019-05-03 00:00:00 and event_date <= 2019-05-04 00:00:00 and true"

And to my earlier point changing to this:

data = %{
  "$additional_on_clauses" => %{
    "event_date" => %{"$between_equal" => [~N[2019-05-03 00:00:00], ~N[2019-05-04 00:00:00]]},
    "infection_category_id" => %{"$in" => [2, 3, 4]}
  },
  "$additional_on_clauses" => %{
    "infection_category_id" => %{"$in" => [2, 3, 4]}
  }
}

data["$additional_on_clauses"]
|> Demo.run()
|> IO.inspect()

has the following result:

$ elixir demo.exs
warning: key "$additional_on_clauses" will be overridden in map
  demo.exs:28

"infection_category_id in [2, 3, 4] and true"

Also Liked

al2o3cr

al2o3cr

Note: I’m assuming that that first code block is surrounded in some kind of Enum.reduce structure. If it isn’t, please post the rest of the code.

Probably want to pass the result of the previous iteration here instead of true.

Where Next?

Popular in Questions Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

We're in Beta

About us Mission Statement