Uni Ecto Plugin May 2026

# Optional: Add precomputed tsvector column alter table(:posts) do add :search_vector, :tsvector end

defp apply_filters(query, []), do: query defp apply_filters(query, filters) do Enum.reduce(filters, query, fn :category, category, q -> from p in q, where: p.category == ^category :published_after, date, q -> from p in q, where: p.inserted_at >= ^date end) end uni ecto plugin

defp apply_full_text_search(query, %search_term: term) when is_binary(term) and term != "" do from q in query, where: fragment( "to_tsvector('english', ?) @@ plainto_tsquery('english', ?)", fragment("coalesce(?, '') || ' ' || coalesce(?, '')", q.title, q.content), ^term ) end defp apply_full_text_search(query, _), do: query :tsvector end defp apply_filters(query

<%= if @searching do %> <div class="mt-4"> <h3>Found @results results</h3> <div class="space-y-2"> <%= for result <- @results do %> <div class="p-4 border rounded"> <h4 class="font-bold"><%= result.title %></h4> <p><%= result.content %></p> </div> <% end %> </div> </div> <% end %> </div> """ end end # config/config.exs config :my_app, :search, language: "english", min_word_length: 2, stop_words: ["the", "a", "an", "and", "or"], highlight: true, highlight_tag: "<mark>" 10. Testing the Search # test/my_app/search_test.exs defmodule MyApp.SearchTest do use MyApp.DataCase alias MyApp.Blog alias MyApp.Blog.Post do: query defp apply_filters(query

render(conn, "index.html", query: query, results: results, total_count: length(results) ) end