View Source AshPagify.Tsearch (ash_pagify v1.1.1)
AshPagify full-text search utilities.
This module provides utilities for full-text search in AshPagify. For a basic usage
you can use AshPagify.Tsearch
and implement the tsvector
calculation in your
resource.
defmodule MyApp.Resource do
use AshPagify.Tsearch
require Ash.Expr
calculations do
calculate :tsvector,
AshPostgres.Tsvector,
expr(
fragment(
"to_tsvector('simple', coalesce(?, '')) || to_tsvector('simple', coalesce(?, ''))",
name,
title
)
),
public?: true
end
end
end
AshPagify.Tsearch provides the following calculations which are used by AshPagify.search
for full-text search:
:tsquery
- The tsquery to search for.:full_text_search
- A boolean indicating whether the tsvector matches the tsquery.:full_text_search_rank
- The rank of the tsvector against the tsquery.
If you need to provide a custom implementation for one of these calculations, you can do so by
- not require the calculation in your resource
- implementing the calculation in your resource
defmodule MyApp.Resource do
use AshPagify.Tsearch, only: [:full_text_search, :full_text_search_rank]
require Ash.Expr
calculations do
calculate :tsquery,
AshPostgres.Tsquery,
# use english dictionary unaccent PostgreSQL extension
expr(fragment("to_tsquery('english', unaccent(?))", ^arg(:search))) do
public? true
argument :search, :string, allow_expr?: true, allow_nil?: false
end
...
end
end
Installation
If you do not use any PostgreSQL specific full-text search extensions, you can skip this step.
Otherwise, you need to add the required extensions to your Repo.installed_extensions list.
defmodule MyApp.Repo do
use AshPostgres.Repo, otp_app: :my_app
def installed_extensions do
["ash-functions", "uuid-ossp", "citext", "unaccent", AshUUID.PostgresExtension]
end
end
Configuration
You can configure the full-text search options globally, per resource, or locally. The options are merged in the following order:
- Function arguments (highest priority)
- Resource-level options (set in the resource module)
- Global options in the application environment (set in config files)
- Library defaults (lowest priority)
Have a look at tsearch_option/0
for a list of available options.
Features
:prefix (PostgreSQL 8.4 and newer only)
PostgreSQL's full text search matches on whole words by default. If you want to search for partial words, however, you can set :prefix to true in one of the configuration options described above.
Default: true
:negation
PostgreSQL's full text search matches all search terms by default. If you want to exclude certain words,
you can set :negation to true. Then any term that begins with an exclamation point !
will be excluded
from the results.
Default: true
:any_word
Setting this attribute to true will perform a search which will return all models containing any word in the search terms. If set to false, the search will return all models containing all words in the search terms.
Default: false
:tsvector_column
This option allows you to specify a custom tsvector column expression for dynamic tsvector column lookup.
Have a look at the Enhanced search
section for more information.
Default: nil
:dictionary
We do not provide a mechanisme to set the dictionary in the configuration options. You can set the dictionary
in a custom tsquery
calculation implementation in your resource.
:weighting
We do not provide a mechanisme to set the weighting in the configuration options. You can set the weighting
in your tsvector
calculation implementation in your resource (or in the tsvector column in your database).
Enhanced search
If you need to be able to change the tsvector
column dynamically (e.g. based on some user input), you can
use the :tsvector_column
option. This option should be specified in your resource module. Then you need
to pass the targeted tsvector calculation as full_text_search: [tsvector: :custom_tsvector]
option to your
AshPagify.validate_and_run/4
call (or other functions provided by AshPagify). This approach is mandatory so we
can serialize the custom tsvector in AshPagify.query_to_filters_map
and restore it in AshPagify.query_for_filters_map
accordingly.
defmodule MyApp.Resource do
use AshPagify.Tsearch
require Ash.Expr
def full_text_search do
[
tsvector_column: [
custom_tsvector: Ash.Expr.expr(custom_tsvector),
another_custom_tsvector: Ash.Expr.expr(another_custom_tsvector),
]
]
end
calculations do
# default tsvector calculation
calculate :tsvector,
AshPostgres.Tsvector,
expr(
fragment(
"to_tsvector('simple', coalesce(?, '')) || to_tsvector('simple', coalesce(?, ''))",
name,
title
)
),
public?: true
end
# custom tsvector calculation
calculate :custom_tsvector,
AshPostgres.Tsvector,
expr(
fragment(
"to_tsvector('simple', coalesce(?, ''))",
name
)
),
public?: true
end
# another custom tsvector calculation
calculate :another_custom_tsvector,
AshPostgres.Tsvector,
expr(
fragment(
"to_tsvector('simple', coalesce(?, ''))",
title
)
),
public?: true
end
end
end
The in your business logic:
def search(query, opts \\ []) do
opts = AshPagify.set_tsvector(:custom_tsvector, opts)
query
|> AshPagify.validate_and_run(MyApp.Resource, opts)
end
Summary
Types
A list of options for full text search.
Functions
Returns the default full text search options.
Merges the given options with the default options.
Replaces disallowed characters in the term with spaces.
Returns the keys for the full text search options.
Splits the search term into terms and returns a list of trimmed terms.
Handles the negation of the term.
Returns the tsquery expression for the given search term and options.
After this, the SQL expression evaluates to a string containing the term surrounded by single-quotes.
Returns the tsquery expression for the given term and options.
Returns the tsvector expression for the given options.
Types
@type tsearch_option() :: {:negation, boolean()} | {:prefix, boolean()} | {:any_word, boolean()} | {:tsvector_column, Ash.Expr.t() | [Ash.Expr.t()]}
A list of options for full text search.
:negation
- Whether to negate the search. Defaults totrue
.:prefix
- Whether to prefix the search. Defaults totrue
.:any_word
- Whether to combine multiple words with || or &&. Defaults tofalse
(&&).:tsvector_column
- Custom tsvector column expressions for dynamic tsvector column lookup. Defaults tonil
.
Functions
@spec default_opts() :: [tsearch_option()]
Returns the default full text search options.
The default options are:
:negation
-true
:prefix
-true
:any_word
-false
:tsvector_column
-nil
Merges the given options with the default options.
The options are merged in the following order:
- Function arguments (highest priority)
- Resource-level options (set in the resource module)
- Global options in the application environment (set in config files)
- Library defaults (lowest priority)
Replaces disallowed characters in the term with spaces.
Returns the keys for the full text search options.
Splits the search term into terms and returns a list of trimmed terms.
Handles the negation of the term.
Returns the tsquery expression for the given search term and options.
The search term is split into terms and each term is sanitized and normalized. The terms are then combined into a tsquery expression.
After this, the SQL expression evaluates to a string containing the term surrounded by single-quotes.
If :prefix is true, then the term will have :* appended to the end. If :negated is true, then the term will have ! prepended to the front and be surrounded by brackets.
Returns the tsquery expression for the given term and options.
Returns the tsvector expression for the given options.
Respects the :tsvector_column
option together with the :tsvector
option.
If both are set, the :tsvector
option is used to lookup the tsvector column
in the :tsvector_column
option. If the custom tsvector column is not found,
the default tsvector column is used.