View Source Vectorex (vectorex v0.1.0)
This module is a container for controls for a full text search for postgres.
It provides a fluent api to build full text search queries which can be transformed to a string
that can be passed for execution using &to_sql/1
The module contains four functions that can be used to build the query
- ts_and
- ts_or
- ts_not
- ts_followed_by
Same functions exist in Vectorex.Subquery
Depending on the function you pass to new/2
, the behaviour changes. If the control
is supported by the function, we append it to the query. If not, the parameter is ignored.
Check the official documentation to verify which controls are supported by the function
Only to_tsquery supports all 4 controls.
You can create a new instance of Vectorex using new/2
by passing the postgres function
you want to use and the parameter
Available Postgres functions are: :to_tsquery, :phraseto_tsquery, :plainto_tsquery, :websearch_to_tsquery
After that, you can start building the query.
Building queries
You can do that by using pipes
# and
Vectorex.new(:to_tsquery, "elixir") |> Vectorex.ts_and("ocaml")
# or
Vectorex.new(:to_tsquery, "elixir") |> Vectorex.ts_or("ocaml")
# not
Vectorex.new(:to_tsquery, "elixir") |> Vectorex.ts_not("ocaml")
# followed_by
Vectorex.new(:to_tsquery, "elixir") |> Vectorex.ts_followed_by("ocaml")
Obviously, you can pipe multiple times
Vectorex.new(:to_tsquery, "elixir")
|> Vectorex.ts_and("ocaml")
|> Vectorex.ts_and("scala")
Or you can use a list
Vectorex.new(:to_tsquery, "elixir")
|> Vectorex.ts_and(["ocaml", "scala"])
Building subqueries
You can also group operators together using Vectorex.Subquery.new/1
.
You can do this if you want parentheses around your terms
inner =
Vectorex.Subquery.new("ocaml")
|> Vectorex.Subquery.ts_and("scala")
result =
Vectorex.new(:to_tsquery, "elixir")
|> Vectorex.ts_and(inner)
Subqueries also support the list option
inner =
Vectorex.Subquery.new("ocaml")
|> Vectorex.Subquery.ts_or(["scala", "haskell"])
result =
Vectorex.new(:to_tsquery, "elixir")
|> Vectorex.ts_and(inner)
We can also pass a list of subqueries
inner =
Vectorex.Subquery.new("ocaml")
|> Vectorex.Subquery.ts_or(["scala", "haskell"])
inner2 =
Vectorex.Subquery.new("java")
|> Vectorex.Subquery.ts_or("c#")
result =
Vectorex.new(:to_tsquery, "elixir")
|> Vectorex.ts_and([inner, inner2])
Converting to sql
After we build the query we want, we need to convert it to a string. We can do that using to_sql/1
We can use that string in an Ecto fragment for execution
vectorex = Vectorex.new(:to_tsquery, "elixir")
from e in Event,
where: fragment("textsearchable_index_col @@ to_tsquery(?)", ^Vectorex.to_sql(vectorex))
Summary
Functions
Creates a new Vectorex instance which can be used to build a full text search query
Transforms a Vectorex instance to a sql string
Adds a AND clause.
Adds a FOLLOWED BY clause.
Adds a NOT clause.
Adds a OR clause.
Types
@type t() :: %Vectorex{ function: :to_tsquery | :phraseto_tsquery | :plainto_tsquery | :websearch_to_tsquery, params: [{atom(), String.t()}] | [{atom(), Vectorex.Subquery.t()}] | [String.t()] }
Functions
Creates a new Vectorex instance which can be used to build a full text search query
Examples
iex> Vectorex.new(:to_tsquery, "elixir")
%Vectorex{params: ["elixir"], function: :to_tsquery}
iex> Vectorex.new(:phraseto_tsquery, "elixir")
%Vectorex{params: ["elixir"], function: :phraseto_tsquery}
iex> Vectorex.new(:plainto_tsquery, "elixir")
%Vectorex{params: ["elixir"], function: :plainto_tsquery}
iex> Vectorex.new(:websearch_to_tsquery, "elixir")
%Vectorex{params: ["elixir"], function: :websearch_to_tsquery}
Transforms a Vectorex instance to a sql string
Examples
iex> Vectorex.new(:to_tsquery, "elixir") |> Vectorex.ts_and("ocaml") |> Vectorex.ts_and("haskell") |> Vectorex.to_sql()
"elixir & ocaml & haskell"
iex> Vectorex.new(:to_tsquery, "elixir") |> Vectorex.ts_and(Vectorex.Subquery.new("ocaml") |> Vectorex.Subquery.ts_or("scala")) |> Vectorex.to_sql()
"elixir & (ocaml | scala)"
@spec ts_and( vector :: t(), params :: [String.t()] | String.t() | Vectorex.Subquery.t() | [Vectorex.Subquery.t()] ) :: t()
Adds a AND clause.
If the operator is supported by the text search control, the parameter is applied to the builder. If not the parameter is ignored.
@spec ts_followed_by( vector :: t(), params :: [String.t()] | String.t() | Vectorex.Subquery.t() | [Vectorex.Subquery.t()] ) :: t()
Adds a FOLLOWED BY clause.
If the operator is supported by the text search control, the parameter is applied to the builder. If not the parameter is ignored.
@spec ts_not( vector :: t(), params :: [String.t()] | String.t() | Vectorex.Subquery.t() | [Vectorex.Subquery.t()] ) :: t()
Adds a NOT clause.
If the operator is supported by the text search control, the parameter is applied to the builder. If not the parameter is ignored.
@spec ts_or( vector :: t(), params :: [String.t()] | String.t() | Vectorex.Subquery.t() | [Vectorex.Subquery.t()] ) :: t()
Adds a OR clause.
If the operator is supported by the text search control, the parameter is applied to the builder. If not the parameter is ignored.