johninvictus

johninvictus

Hi Guys.

Am trying to fetch data from database where date string is 2days old and I have no Idea how to use the function I have written inside the ecto query.

function

def date_difference(date_string) do
    duration =
      date_string
      |> Timex.parse!("%Y-%m-%d", :strftime)
      |> Timex.to_datetime()
      |> DateTime.to_unix(:milliseconds)
      |> Timex.Duration.from_microseconds()

    Duration.diff(duration, Duration.zero(), :days)
  end

I hoped to use it like this.

  where: date_difference(p.payment_schedue) == 2

PS: Am a noobe :grinning:

Showing Posts 1 to 10

jswny

jswny

I’m certainly not an Ecto expert, but I’m pretty sure that you can’t define custom functions in Elixir and use them inside Ecto queries (feel free to correct me if I’m wrong though).

What I would do for now is get your results and use a filter function to do what you want. Something like this

query = ...
Enum.filter(query, fn p -> date_difference(p.payment_schedule) == 2 end)

That way, you will get all of the results initially from the Ecto query, and then you will use Elixir to filter those based on your custom Elixir function. This might not be the best way to do it but I am fairly sure it would work.

johninvictus

johninvictus OP

@jswny
Thank you for your answer.

After more research I have discovered it is not possible to use functions inside the query unless we use the Postgres defined types.

This is a great solution but I have chosen to refactor my db to use date and then use the interval type .
ie

  where:  fragment("now() - ? >= interval '-1 days' and now() - ? <= interval '1 days'",  p.payment_schedule, p.payment_schedule)
OvermindDL1

OvermindDL1

If you want interval’s I have a type library here:

/me loves intervals

shakram02

shakram02

What if I want to call a custom function?, for example; I want to check for 3 conditions when I’m joining two tables. Since this is lots of typing, I want to put that in a function.

However, the compiler complains that the binding variable is undefined.

  def filter(...) do
      # ...
      |> join(:inner, [tr, tt: tt], t in Tag,
        as: :tag,
        on: ^is_matching_tag(tt, t)
      )

    # ...
  end

  defp is_matching_tag(trt, tag) do
    Enum.map(2..0, fn level -> is_matching_tag(trt, tag, level) end)
    |> Enum.any?()
  end

  defp is_matching_tag(a,b,c) do
    # ...
  end

But I get the following error where the call occrus (the ecto join)

** (CompileError) ../trs.ex:62: undefined function t/0
    (elixir) src/elixir_locals.erl:108: :elixir_locals."-ensure_no_undefined_local/3-lc$^0/1-0-"/2
    (elixir) src/elixir_locals.erl:109: anonymous fn/3 in :elixir_locals.ensure_no_undefined_local/3
    (stdlib) erl_eval.erl:680: :erl_eval.do_apply/6

Can this be accomplished using Ecto?

thanks! (newbie here)

LostKobrakai

LostKobrakai

You‘ll need to provide this logic in sql. You cannot use elixir code within an ecto query. A query will be converted to sql and sent to the db.

johninvictus

johninvictus OP

Hi @shakram02

This not possible.

Am not sure what those conditions are but I would suggest using and or or to join those conditions. ie

 from v in query,
          join: vs in assoc(v, :visitor),
          join: vc in assoc(v, :visitor_company),
          join: h in assoc(v, :host),
          where:
            ilike(vs.first_name, ^"%#{term}%") or
              ilike(vs.second_name, ^"%#{term}%") or
              ilike(vs.email, ^"%#{term}%") or
              ilike(vs.phone, ^"%#{term}%") or
              ilike(h.first_name, ^"%#{term}%") or
              ilike(vc.name, ^"%#{term}%")

Hope that helps.

OvermindDL1

OvermindDL1

For note, a large set of ilike’s like that is going to be very slow especially as the data set grows. Converting it to using TS indexes or so would be a lot faster and various other lookup patterns for the others.

johninvictus

johninvictus OP

Hi @OvermindDL1

Thanks for the tip.

Do, you mean creating index with Ecto.Migration.index/2:.

OvermindDL1

OvermindDL1

Look at the tsvector/tsquery/etc types in PostgreSQL for efficient word style searches. :slight_smile:

I think someone made a library on hex.pm that simplifies it as well, but it’s optional, you can do it in straight Ecto too, but might be worth finding it. :slight_smile:

johninvictus

johninvictus OP

Thanks a lot, lemme look at that.

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
roeland
Kia ora, We have been using elixir-google-api to connect to Google Drive. However, with the updates to Tesla due to CVEs this is now bro...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
Onor.io
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
jaybe78
Hello, I’m developing a online persistent chat system (what’s app) like using elixir/dynamodb/aws for a mobile app(flutter). The diffic...
New
Trolleger
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New

Other Trending Topics Top

garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New
aseigo
ICal is a library for interacting with iCalendar data. It parses iCalendars into typed Elixir structs via ICal.from_ics, and can prepare ...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews