SearchAsh (search_ash v0.1.0)

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 (the stemmers Rust NIF);
  • 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 read (:tenant, :domain, :authorize?, …); :tenant is also used for the upsert.

search(body)

(macro)