module Clear::Model::FullTextSearchable

Overview

Full text search plugin offers full integration with tsvector capabilities of Postgresql.

It allows you to query models through the text content of one or multiple fields.

The blog example

Let's assume we have a blog and want to implement full text search over title and content:

create_table "posts" do |t|
  t.column :title, :string, null: false
  t.column :content, :string, null: false

  t.full_text_searchable on: [{"title", 'A'}, {"content", 'C'}]
end

This migration will create a 3rd column named full_text_vector of type tsvector, a gin index, a trigger and a function to update automatically this column.

Over the on keyword, '{"title", 'A'}' means it allows search of the content of "title", with level of priority (weight) "A", which tells postgres than title content is more meaningful than the article content itself.

Now, let's build some models:


  model Post
    include Clear::Model
    #...

    full_text_searchable
  end

  Post.create!({title: "About poney", content: "Poney are cool"})
  Post.create!({title: "About dog and cat", content: "Cat and dog are cool. But not as much as poney"})
  Post.create!({title: "You won't believe: She raises her poney like as star!", content: "She's cool because poney are cool"})

Search is now easily done

Post.query.search("poney") # Return all the articles !

Obviously, search call can be chained:

user = User.find! { email == "some_email@example.com" }
Post.query.from_user(user).search("orm")

Additional parameters

catalog

Select the catalog to use to build the tsquery. By default, pg_catalog.english is used.

# in your migration:
t.full_text_searchable on: [{"title", 'A'}, {"content", 'C'}], catalog: "pg_catalog.french"

# in your model
full_text_searchable catalog: "pg_catalog.french"

Note: For now, Clear doesn't offers dynamic selection of catalog (for let's say multi-lang service). If your app need this feature, do not hesitate to open an issue.

trigger_name, function_name

In migration, you can change the name generated for the trigger and the function, using theses two keys.

dest_field

The field created in the database, which will contains your ts vector. Default is full_text_vector.

# in your migration
t.full_text_searchable on: [{"title", 'A'}, {"content", 'C'}], dest_field: "tsv"

# in your model
full_text_searchable "tsv"

Direct including types

Defined in:

clear/extensions/full_text_searchable/model.cr

Class Method Summary

Macro Summary

Class Method Detail

def self.to_tsq(text) #

Parse client side text and generate string ready to be ingested by PG's to_tsquery.

Author note: pg to_tsquery is awesome but can easily fail to parse. search method use then a wrapper text_to_search used to ensure than request is understood and produce ALWAYS legal string for to_tsquery This is a good helper then to use with the input of your end-users !

However, this helper can be improved, as it doesn't use all the features of tsvector (parentesis, OR operator etc...)


[View source]

Macro Detail

macro full_text_searchable(through = "full_text_vector", catalog = "pg_catalog.english", scope_name = "search") #

Set this model as searchable using tsvector


[View source]