SearchAsh (search_ash v0.2.2)

Copy Markdown View Source

An Ash extension that adds multilingual full-text search to a resource with one search do … end block.

defmodule MyApp.Post do
  use Ash.Resource,
    domain: MyApp.Blog,
    data_layer: AshPostgres.DataLayer,
    extensions: [SearchAsh]

  search do
    fields [:title, :body]
    language_attribute :language
  end

  # ... attributes :title, :body, :language ...
end

From that block the extension generates, at compile time:

  • a :search_text string attribute (unless you defined one), holding the stemmed tokens;
  • a global change that keeps :search_text in sync on create/update, stemming each row in its own language via SearchCore;
  • a GIN expression index to_tsvector('simple', search_text) on the Postgres table — emitted into your migrations and tracked in the resource snapshot, so mix ash_postgres.generate_migrations round-trips it cleanly;
  • a :search read action taking query and language arguments, filtering on the tsvector with a tsquery built from the same pipeline (so a search for "chevaux" matches a row that stored "cheval").

Stemming happens in Elixir, so the Postgres side always uses the 'simple' configuration.

Summary

Functions

Backfill the unified index for all existing rows of a SearchAsh.Source resource.

Functions

reindex(source_resource, opts \\ [])

Backfill the unified index for all existing rows of a SearchAsh.Source resource.

Streams the source and upserts each row into its configured index. For a multitenant index, pass the tenant (call once per tenant):

SearchAsh.reindex(MyApp.Sales.BonDeCommande, tenant: "org_42")

Options are forwarded to the source read (:tenant, :domain, :authorize?, …), so you decide whose rows get backfilled; :tenant also scopes the index upsert, so mirrored rows land in the same tenant they came from.

The upsert itself is not authorized: it mirrors rows the read already let through, and the index's policies are about what a user may find, not about whether the mirror may happen.

search(body)

(macro)