Open talivodworks opened 4 years ago
This is related: https://github.com/hasura/graphql-engine/issues/1498 but not complete for your use-case as it involves GROUP BY
also.
One way is to create a view:
CREATE VIEW room_operating_hours_count AS
SELECT roh.room_id, count(roh.room_id)
FROM room_operating_hours AS roh
WHERE (roh.day_of_week IN ('monday', 'tuesday', 'wednesday'))
GROUP BY roh.room_id
Now you can filter on field like room_id and count.
@tirumaraiselvan I am sorry but I should have mentioned this in the Question that days are being decided on the basis of user selection. Like monday, tuesday. It could be all of the week days or just one week day, depending on the user selection. What do you suggest on that?
More discussion here: https://github.com/hasura/graphql-engine/issues/3478
I feel custom functions are the best bet here since group by is not explicitly supported in Hasura yet.
The way I get around this Use case is, I have created Materialized Views.
--
-- MATERIALIZED VIEW
--
CREATE MATERIALIZED VIEW monday_op_hrs_rooms as
SELECT * from public.room_operating_hours
WHERE day_of_week = 'monday';
CREATE UNIQUE INDEX ON monday_op_hrs_rooms (id);
CREATE MATERIALIZED VIEW tuesday_op_hrs_rooms as
SELECT * from public.room_operating_hours
WHERE day_of_week = 'tuesday' ;
CREATE UNIQUE INDEX ON tuesday_op_hrs_rooms (id);
CREATE MATERIALIZED VIEW wednesday_op_hrs_rooms as
SELECT * from public.room_operating_hours
WHERE day_of_week = 'wednesday';
CREATE UNIQUE INDEX ON wednesday_op_hrs_rooms (id);
CREATE MATERIALIZED VIEW thursday_op_hrs_rooms as
SELECT * from public.room_operating_hours
WHERE day_of_week = 'thursday';
CREATE UNIQUE INDEX ON thursday_op_hrs_rooms (id);
CREATE MATERIALIZED VIEW friday_op_hrs_rooms as
SELECT * from public.room_operating_hours
WHERE day_of_week = 'friday';
CREATE UNIQUE INDEX ON friday_op_hrs_rooms (id);
CREATE MATERIALIZED VIEW saturday_op_hrs_rooms as
SELECT * from public.room_operating_hours
WHERE day_of_week = 'saturday';
CREATE UNIQUE INDEX ON saturday_op_hrs_rooms (id);
CREATE MATERIALIZED VIEW sunday_op_hrs_rooms as
SELECT * from public.room_operating_hours
WHERE day_of_week = 'sunday';
CREATE UNIQUE INDEX ON sunday_op_hrs_rooms (id);
--
-- Trigger TO UPDATE THE MATERIALIZED VIEW
--
CREATE OR REPLACE FUNCTION refresh_operating_hours_materialized_views()
RETURNS trigger AS $BODY$
BEGIN
REFRESH MATERIALIZED VIEW CONCURRENTLY monday_op_hrs_rooms;
REFRESH MATERIALIZED VIEW CONCURRENTLY tuesday_op_hrs_rooms;
REFRESH MATERIALIZED VIEW CONCURRENTLY wednesday_op_hrs_rooms;
REFRESH MATERIALIZED VIEW CONCURRENTLY thursday_op_hrs_rooms;
REFRESH MATERIALIZED VIEW CONCURRENTLY friday_op_hrs_rooms;
REFRESH MATERIALIZED VIEW CONCURRENTLY saturday_op_hrs_rooms;
REFRESH MATERIALIZED VIEW CONCURRENTLY sunday_op_hrs_rooms;
RETURN NULL;
END;
$BODY$ LANGUAGE plpgsql;
CREATE TRIGGER update_operating_hours_materialized_views
AFTER INSERT OR
UPDATE OR
DELETE
ON "room_operating_hours"
FOR EACH ROW EXECUTE PROCEDURE refresh_operating_hours_materialized_views();
Then I added the Object relationship between room
and MATERIALIZED views
. This way I can specify my where clause like this:
query roomOnMondayTuesdayWednesday {
rooms(
where: {
# Coming Form Hasura relationship between room AND (monday_op_hrs_rooms, tuesday_op_hrs_rooms, wednesday_op_hrs_rooms)
monday_hours: {
hour_start: { _lte: "09:00:00+00" },
hour_end: { _gte: "19:00:00+00" }
}
tuesday_hours: {
hour_start: { _lte: "09:00:00+00" },
hour_end: { _gte: "19:00:00+00" }
}
wednesday_hours: {
hour_start: { _lte: "09:00:00+00" },
hour_end: { _gte: "19:00:00+00" }
}
}
) {
room_operating_hours{
day_of_week
}
}
}
query roomOnSaturday {
rooms(
where: {
# Coming Form Hasura relationship between room AND saturday_op_hrs_rooms
saturday_hours: {
hour_start: { _lte: "09:00:00+00" },
hour_end: { _gte: "19:00:00+00" }
}
}
) {
room_operating_hours{
day_of_week
}
}
}
Now I can leverage the Hasura's out of the box provided features as well without creating a custom function.
Few things to note about MATERIALIZED VIEWS
CONCURRENTLY
in the trigger function up there. It requires Postgres version 9.4. It allows you to select the rows even database is running Update operation concurrently. More Details here.Hope this will help someone. Happy Coding. 🙂
I am trying to achieve a use case. I have 2 tables:
Here is the schema of both of the tables.
rooms
rooms_operating_hours
room hasMany rooms_operating_hours.
Sample data
room data
room_operating_hours data
Now I want to query the room which are available on
monday
,tuesday
andwednesday
through GraphQL. Postgres query something looks like this:I have tried couple of graphql query but none of them work.
I have been googling that and my findings are that:
I am actually trying to find out what are the odds for not creating a custom SQL function as this use case is part of big complex query which is working fine with whatever hasura provides at this point. Doing Custom SQL would require me to do all the things that hasura is already doing.
Please help me with this. Thank You.