marvinljw

marvinljw

Hi all,

Currently I need to create a function to get all the users with registration date between a given start_date to a given end_date regardless of the year. This means that the user with registration date of ~D[2016-06-19] should appear for the function get_users(~D[2022-06-12], ~D[2022-07-30]).

So, I am trying to create a new_date(year of start_date, reg_d.month, reg_d.day) before comparing with the interval. Let’s assume that both the start_date and end_date is always on the same year.

def get_users(start_date, end_date) do
start_year = start_d.year

query = from u in User, 
    where ^Date.from_erl!({ start_year, (fragment(“date_part(‘month’, ?)”, u.reg_d)), (fragment(“date_part(‘day’, ?)”, u.reg_d)) }) > ^start_date 
    and ^Date.from_erl!({ start_year, (fragment(“date_part(‘month’, ?)”, u.reg_d)), (fragment(“date_part(‘day’, ?)”, u.reg_d)) }) < ^end_date

Repo.all(query)
end

When i write the above, it shows “CompileError undefined function fragment/2 Stacktrace: | (elixir 1.12.3) src/elixir_locals.erl:114: anonymous fn/3 in :elixir_locals.ensure_no_undefined_local/3”

Thank you in advance!

Showing Posts 1 to 4

LostKobrakai

LostKobrakai

The following should just work.

from u in User, where: u.reg_d > ^start_date and u.reg_d < ^end_date
al2o3cr

al2o3cr

Ecto builds a whole query and then sends it to the database - you seem to be hoping to execute some Elixir for each matching row, which isn’t supported.

There are a couple different approaches you could take to solve this:

  • build a complex query using date_part and logical operators - basically re-implement date comparison by hand but without comparing the years.
    • pro: does everything in SQL
    • con: does everything in SQL; IIRC date_part isn’t particularly index-friendly
  • build a complex query by generating a copy of the supplied date range and combining the clauses with OR. In your example, it’d be checking “is reg_d between 2022-06-12 and 2022-07-30? What about 2021-06-12 and 2021-07-30, etc?”
    • pro: more index-friendly since it’s matching on the whole value of reg_d
    • con: if reg_d could be many many years ago, the query will get very large
  • change the data format: store a next_anniversary_d column that contains reg_d in the current year.
    • pro: the check becomes very very simple and index-friendly: “is next_anniversary_d in the supplied range?”
    • con: now you need code to update the anniversary column every year.
evadne

evadne

I think using date_part is the best solution and you could add an index on the function itself in postgres.

See:

So:

CREATE INDEX user_registration_doy ON users(date_part('doy', registration_date));

Then probably:

def query(from_date, to_date) do
  from_doy = Date.day_of_year(from_date)
  to_doy = Date.day_of_year(to_date)

  User
  |> where([x], fragment("date_part('doy', ?) >= ?", x.start_date, ^from_doy)
  |> where([x], fragment("date_part('doy', ?) <= ?", x.start_date, ^end_doy)
  |> Repo.all()
end

n.b. Must validate both pg and elixir algos agree on day of year.

marvinljw

marvinljw OP

Thanks for the reply. I changed the data format of reg_d to the current year by creating a subquery. From there, I compared the new_reg_d with the start_date and end_date and it works.

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
ryanwinchester
apply_graft/2 doesn’t rewrite an add_many sub-workflow’s deps on an add step. Grafted jobs cancel with “upstream job was deleted” Version...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
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

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews