pesquisa de texto completo simples usando postgres on rails

Se seu aplicativo requer pesquisa de texto completo, eu recomendo fortemente o recurso out-of-the-box que o postgres oferece. É uma solução simples, mas poderosa, que remove dependências de sistemas externos (como solr, sphinx, etc.) para a funcionalidade de pesquisa básica.

Existem 4 partes:

  1. Crie uma coluna de vetor de pesquisa do tipo ‘tsvector’ para representar os dados.
  2. Crie um índice no vetor de pesquisa usando ‘gin’
  3. Pesquise usando ‘ts_vector’
  4. Crie um gatilho para atualizar a coluna do vetor de pesquisa. (opcional)

Tabela :

Minha tabela de produtos é semelhante a esta e desejo pesquisar em todas as colunas:

table name: products
title
:string
description
:text
awards
:text
keywords
:text

Migração :

class AddSearchVectorToProducts < ActiveRecord::Migration
def up
# 1. Create the search vector column
add_column
:products, :search_vector, 'tsvector'

# 2. Create the gin index on the search vector
execute
<<-SQL
CREATE INDEX products_search_idx

ON products

USING gin
(search_vector);
SQL


# 4 (optional). Trigger to update the vector column
# when the products table is updated
execute
<<-SQL
DROP TRIGGER IF EXISTS products_search_vector_update

ON products
;
CREATE TRIGGER products_search_vector_update

BEFORE INSERT OR UPDATE

ON products

FOR EACH ROW EXECUTE PROCEDURE

tsvector_update_trigger
(search_vector, 'pg_catalog.english', title, description, awards, keywords);
SQL


Product.find_each { |p| p.touch }
end

def down
remove_column
:products, :search_vector
execute
<<-SQL
DROP TRIGGER IF EXISTS products_search_vector_update on products
;
SQL

end
end

Seu modelo :

class Product
def self.search(terms = "")
sanitized
= sanitize_sql_array(["to_tsquery('english', ?)", terms.gsub(/s/,"+")])
Product.where("search_vector @@ #{sanitized}")
end
end

Recursos :

Postgres Docs – http://www.postgresql.org/docs/9.1/static/textsearch-intro.html
Texticle Gem – http://tenderlove.github.com/texticle