Ecto Plugin - Uni

setup do %Post{} |> Post.changeset(% title: "Elixir Full-Text Search", content: "This article explains how to implement full-text search" ) |> Repo.insert!()

Using PostgreSQL's Full-Text Search # lib/my_app/repo.ex defmodule MyApp.Repo do use Ecto.Repo, otp_app: :my_app Custom full-text search function def full_text_search(queryable, search_term, fields) do search_term = search_term |> String.trim() |> String.replace(~r/\s+/, " & ") # Convert spaces to & for AND operator

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

def index(conn, %"q" => query) do results = Blog.search_posts(query, category: conn.params["category"])

def render(assigns) do ~H""" <div> <form phx-submit="search" phx-change="search"> <input type="text" name="query" value=@search_term placeholder="Search posts..." class="w-full p-2 border rounded" /> <button type="submit">Search</button> </form> setup do %Post{} |&gt; Post

execute(""" CREATE INDEX posts_search_vector_idx ON posts USING GIN(search_vector) """) end end # lib/my_app/search/query_builder.ex defmodule MyApp.Search.QueryBuilder do import Ecto.Query def build_search_query(schema, params) do base_query = from s in schema

:noreply, assign(socket, search_term: query, results: results, searching: query != "" ) end setup do %Post{} |&gt

test "search finds relevant posts" do results = Blog.search_posts("elixir search") assert length(results) > 0 assert Enum.any?(results, &String.contains?(&1.title, "Elixir")) end