2009-06-24 11 views
8

Sto cercando di implementare una ricerca full-text di base con MySQL.MySQL Ricerca full-text in Ruby on Rails

Ho scritto questa migrazione:


def self.up 
    execute 'ALTER TABLE photos ENGINE = MyISAM' 
    execute 'CREATE FULLTEXT INDEX fulltext_photos ON photos (place, info)' 
end 

def self.down 
    execute 'ALTER TABLE photos ENGINE = InnoDB' 
    execute 'DROP INDEX fulltext_photos ON photos' 
end 

E qui è il mio modello:


def self.search(*args) 
    options = args.extract_options! 
    find_by_sql [ "SELECT * FROM photos WHERE MATCH (place, info) AGAINST (?)", options[:query] ] 
end 

Il problema è che il codice restituisce sempre un array vuoto.

Ad esempio:

% Photo.find(:first) 
=> Photo id: 1, place: "Baceno", info: "Era immerso in erba alta." ... 

% Photo.search(:all, :query => 'baceno') 
=> []
+0

Questo script di migrazione grandi opere, ma ricordatevi di riportare l'ordine nel metodo self.down, l'indice deve essere rimosso prima di modificare la tabella di nuovo a InnoDB altrimenti si ottiene un fallimento. –

risposta

9

ho creato un progetto (Rails 2.3.2, Ruby 1.9.1 MySQL 5.0) per emulare questo. Con un record nel database, ho ottenuto gli stessi risultati che hai fatto. Quando ho aggiunto più record, il comando Photo.search ha trovato il record.

Questo potrebbe essere dovuto al fatto che "le parole presenti nel 50% o più delle righe sono considerate comuni e non corrispondono". Ref.

La soglia del 50% non si applica in modalità binaria. Ref.

in modo binario appartiene all'interno delle parentesi: CONTRO ('Baceno' IN MODO BOOLEAN)

+0

Perfetto ... ora è tutto chiaro! – collimarco

1

Nella mia prova (solo in MySQL, non in Rails) quando aggiungo l'opzione IN MODALITÀ booleani per l'istruzione SELECT , sembra restituire righe.

SELECT * FROM photos WHERE MATCH (place, info) AGAINST (?) IN BOOLEAN MODE 

Vorrei inoltre consiglia di utilizzare un prodotto di ricerca separato come Solr o Sfinge per la ricerca.

2

Il codice seguente viene eseguito per la mia pagina Web e fornisce risultati corretti in ruby ​​su rail.

Adverse.find(:all, :conditions => ["match(related_company,client_name) against (? IN BOOLEAN MODE)",@chk])