full text search com solr, mysql full text e postgresql full text
DESCRIPTION
Slides usados na palestra Full Text Search com Solr, MySQL Full text e PostgreSQL Full Text que apresentei hoje pela manha no #TheDevConf #TDCPOA #TDC2014TRANSCRIPT
Full Text Search com Solr, MySQL Fulltext e PostgreSQL
Fulltext searchPor que usar? Quando usar? Qual usar?
Rodrigo UrubatanProgramador desde 1997
Autor do livro: Ruby on Rails desenvolvimento fácil e rápido de aplicações web
http://urubatan.com.br
http://sobrecodigo.com
http://twitter.com/urubatan
http://github.com/urubatan
O que é FTS?
Full Text Search é um recurso utilizado quando precisamos buscar texto de forma mais eficiente em uma grande massa de dados
Engines de FTS permitem uma maior flexibilidade que um “like ‘%valor%’"
Normalmente também uma maior performance
Quais são as opções disponíveis?
Alguns bancos de dados como o MySQL, o Postgres e o Oracle possuem engines internas de FTS
Existem servidores externos também como o Solr, Sphinx entre outros
O que vamos ver hoje?
MySQLExtremamente fácil de configurar
Bastante rápido
Tem problemas com alguns caracteres, por exemplo não é possível pesquisar por AT&T
Não necessita esforço adicional para indexar, funciona com um índice simples
O critério de pesquisa precisa ser fixo para uma query (não é possível comparar com o valor de um campo)
PostgreSQLQuase tão fácil de configurar quanto o MySQL
Performance semelhante
Interpretador de consultas mais inteligente (é possível pesquisar por AT&T, mesmo ele buscando por /AT.T/ )
É necessário uma trigger para atualizar o campo de cache do ::tsvector
SolrMais difícil de configurar
Performance espetacular
Extremamente flexível
Necessita de código na aplicação para indexar e atualizar indices
Pesquisas extremamente rápidas, indexação bastante lenta se comparada com as outras opções
Ok, mas quando vou precisar disto?
Imagina se tu tem um site de noticias e quer que teus usuários pesquisem pelo texto das noticias?
Ou tu tem uma lista de empresas e os teus clientes podem procurar pelo nome ou pelo código das ações delas?
Já pensou em implementar um Google?
Pesquisar por: +“campo bom” & +agricultura
Ok, mas como faço isto?
MySQLalter table companies
add FULLTEXT KEY allfields (name,ticker_symbol,exchange_symbol);
select * from companies
where match(name,ticker_symbol,exchange_symbol) against("petrobras");
Qual a diferença?
select exchange_symbol, group_concat(name) from companies
where match(name) against("petrobras")
group by exchange_symbol;
3 linhas 0.021s
select exchange_symbol, group_concat(name) from companies
where name like "%petrobras%"
group by exchange_symbol;
3 linhas 4.101s
um like levou 195X o tempo do FTS
PostgreSQLalter table companies
add text tsvector;
CREATE INDEX companies_text ON companies USING gin(text);
update companies
set text = to_tsvector(concat(name,’ ’, ticker_symbol, ‘ ‘, exchange_symbol);
select * from companies
where text @@ ‘petrobras’::tsquery;
Qual a diferença?
select exchange_symbol, array_agg(name) from companies
where text @@ 'petrobras'::tsquery
group by exchange_symbol;
18ms
select exchange_symbol, array_agg(name) from companies
where name like '%petrobras%'
group by exchange_symbol;
2308ms
FTS 128X mais rapido que like
SolrInstalar sunspot_rails e sunspot_solr no projeto rails
Adicionar código para indexar classes:
class Company < ActiveRecord::Base searchable do text :name text :exchange_and_ticker do "#{self.exchange_symbol}:#{self.ticker_symbol}" end endend
Company.reindex #senta e espera#versão mais rápida: Company.find_in_batches{|batch| Sunspot.index!(batch)}
res = Company.search do
fulltext('petrobras')
end
13.5ms - com configuração de desenvolvimento (rake sunspot:solr:start)
Company.where("name like ?", “%petrobras%")
4080.5ms
Solr 302X mais rápido que like
boosting de resultadosPost.search do fulltext 'pizza' do boost(2.0) { with(:featured, true) } endend
Post.search do fulltext 'pizza' do fields(:body, :title => 2.0) endend
Resultados Facetadossearch = Post.search do fulltext "pizza" facet :author_idend
search.facet(:author_id).rows.each do |facet| puts "Author #{facet.value} has #{facet.count} pizza posts!" end
Exemplos ao vivo?
Qual o melhor?
A resposta é: quais as necessidades da sua aplicação?