Hi,
The problem I am encountering is, let’s say my search term is “pasta”, I get the following results:
ID: 3 NAME: a pasta carbonara CREATED_ON: 2022-03-13
ID: 1 NAME: pasta carbonara CREATED_ON: 2022-03-08
ID: 2 NAME: pasta CREATED_ON: 2022-03-13
But the expected results should be in the below order
ID: 2 NAME: pasta CREATED_ON: 2022-03-13
ID: 1 NAME: pasta carbonara CREATED_ON: 2022-03-08
ID: 3 NAME: a pasta carbonara CREATED_ON: 2022-03-13
I want the exact results to come first and then the best similar ones ordered next. Need help with making this work.
Currently I have the following function
def list_recipes(args, prefix_name) do
sort_params = get_sort_params(args)
from(f in Food)
|> order_by(^sort_params)
|> distinct(true)
|> put_query_prefix(prefix_name)
|> match_recipes(args, prefix_name)
|> Repo.all()
end
defp get_sort_params(%{sort: %{sort_by: sort_by, sort_order: sort_order}}) do
[{sort_order, sort_by}, desc_nulls_last: :created_on, asc: :id]
end
defp get_sort_params(_args) do
[desc_nulls_last: :created_on, asc: :id]
end
defp match_recipes(query, %{filter: filters}, prefix_name) do
Enum.reduce(filters, query, &text_filter(&1, &2, prefix_name))
end
defp match_recipes(query, _filter, _prefix_name), do: query
defp text_filter({:matching, term}, query, _prefix_name) do
where(
query,
[q],
ilike(q.name, ^"%#{term}%") or ilike(q.link, ^"%#{term}%")
)
end
I have the trigram gin index for recipes table(migration) as follows
def up do
execute("CREATE EXTENSION IF NOT EXISTS pg_trgm;")
execute(
"CREATE INDEX CONCURRENTLY IF NOT EXISTS name_idx_gin ON recipes USING gin (name gin_trgm_ops);"
)
execute(
"CREATE INDEX CONCURRENTLY IF NOT EXISTS link_idx_gin ON recipes USING gin (link gin_trgm_ops);"
)
execute("CREATE INDEX CONCURRENTLY IF NOT EXISTS name_idx ON recipes (name);")
execute("CREATE INDEX CONCURRENTLY IF NOT EXISTS link_idx ON recipes (link);")
end
def down do
execute("DROP INDEX CONCURRENTLY IF EXISTS link_idx;")
execute("DROP INDEX CONCURRENTLY IF EXISTS name_idx;")
execute("DROP INDEX CONCURRENTLY IF EXISTS link_idx_gin;")
execute("DROP INDEX CONCURRENTLY IF EXISTS name_idx_gin;")
end