create or replace function find_articles( _search text default null, _filter json default '{}', direction text default 'desc', sort text default 'created_at', "limit" int default 50, "offset" int default 0, out resource json, out total int ) language plpgsql as $$ begin select json_agg(t), ( select count(id) from article a where (_search is null or _search = '' or a ==> dsl.multi_match('{title^3, content, description, tags}', _search)) and (_filter->>'created_by_id' is null or a.created_by_id = (_filter->>'created_by_id')::uuid) and (_filter->>'workgroup_id' is null or a.workgroup_id = (_filter->>'workgroup_id')::uuid) and a.last_version = true ) into resource, total from ( select a.id, a.title, a.deleted_at, a.draft, find_citizen_by_id_with_user(a.created_by_id) as created_by, find_workgroup_by_id(a.workgroup_id) as workgroup, count_vote(a.id) as votes, zdb.score(a.ctid) _score from article as a left join vote_cache ca using (id) where ( _search is null or _search = '' or a ==> dsl.multi_match('{title^3, content, description, tags}', _search) ) and (_filter->>'created_by_id' is null or a.created_by_id = (_filter->>'created_by_id')::uuid) and (_filter->>'workgroup_id' is null or a.workgroup_id = (_filter->>'workgroup_id')::uuid) and a.last_version = true order by _score desc, case direction when 'asc' then case sort when 'title' then a.title when 'createdAt' then a.created_at::text when 'vote' then ca.score::text when 'popularity' then ca.total::text else null end end, case direction when 'desc' then case sort when 'title' then a.title when 'createdAt' then a.created_at::text when 'vote' then ca.score::text when 'popularity' then ca.total::text end end desc, a.created_at desc limit "limit" offset "offset" ) as t; end; $$;