#343 Full-Text Search in PostgreSQL pro
Postgres offers full-text searching right out of the box. This episode shows how to write queries from scratch, apply tools like Texticle and pg_search, and optimize performance through indexes.
- Download:
- source codeProject Files in Zip (109 KB)
- mp4Full Size H.264 Video (47.1 MB)
- m4vSmaller H.264 Video (21.3 MB)
- webmFull Size VP8 Video (21.8 MB)
- ogvFull Size Theora Video (51 MB)
Resources
terminal
rails db rails g migration add_unaccent_extension rake db:migrate rails g migration add_search_index_to_articles rm db/schema.rb rake db:structure:dump rake db:structure:load
rails db
select 'ninja turtles' @@ 'turtles'; select 'ninja turtles' @@ 'turtle'; select to_tsvector('ninja turtles') @@ plainto_tsquery('turtle'); select to_tsvector('english', 'ninja turtles') @@ plainto_tsquery('english', 'turtle'); select to_tsvector('simple', 'ninja turtles') @@ plainto_tsquery('simple', 'turtles'); select to_tsvector('simple', 'ninja turtles') @@ to_tsquery('simple', 'ninja & !turtles'); select ts_rank(to_tsvector('ninjaturtles'), to_tsquery('turtles'));
models/article.rb
def self.text_search(query) if query.present? rank = <<-RANK ts_rank(to_tsvector(name), plainto_tsquery(#{sanitize(query)})) + ts_rank(to_tsvector(content), plainto_tsquery(#{sanitize(query)})) RANK where("to_tsvector('english', name) @@ :q or to_tsvector('english', content) @@ :q", q: query).order("#{rank} desc") else scoped end end
migrations/*_add_search_index_to_articles.rb
class AddSearchIndexToArticles < ActiveRecord::Migration def up execute "create index articles_name on articles using gin(to_tsvector('english', name))" execute "create index articles_content on articles using gin(to_tsvector('english', content))" end def down execute "drop index articles_name" execute "drop index articles_content" end end
Texticle
Gemfile
gem 'texticle', require: 'texticle/rails'
models/article.rb
search(query)
PgSearch
Gemfile
gem 'pg_search'
models/article.rb
include PgSearch pg_search_scope :search, against: [:name, :content], using: {tsearch: {dictionary: "english"}}, associated_against: {author: :name, comments: [:name, :content]}, ignoring: :accents
migrations/*_add_unaccent_extension.rb
class AddUnaccentExtension < ActiveRecord::Migration def up execute "create extension unaccent" end def down execute "drop extension unaccent" end end