Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Relevância da pesquisa de texto completo do MySQL em várias tabelas


Sim, você pode unificá-los muito bem usando um mecanismo de pesquisa como Apache Lucene e Solr.

http://lucene.apache.org/solr/

Se você precisa fazer isso apenas no MySQL, você pode fazer isso com um UNION. Você provavelmente desejará suprimir quaisquer resultados de relevância zero.

Você precisará decidir como deseja afetar a relevância dependendo de qual tabela corresponde.

Por exemplo, suponha que você queira que os artigos sejam mais importantes, os eventos sejam de importância média e as páginas sejam menos importantes. Você pode usar multiplicadores assim:
set @articles_multiplier=3;
set @events_multiplier=2;
set @pages_multiplier=1;

Aqui está um exemplo de trabalho que você pode tentar que demonstra algumas dessas técnicas:

Crie dados de amostra:
create database d;
use d;

create table articles (id int primary key, content text) ENGINE = MYISAM;
create table events (id int primary key, content text) ENGINE = MYISAM;
create table pages (id int primary key, content text) ENGINE = MYISAM;

insert into articles values 
(1, "Lorem ipsum dolor sit amet"),
(2, "consectetur adipisicing elit"),
(3, "sed do eiusmod tempor incididunt");

insert into events values 
(1, "Ut enim ad minim veniam"),
(2, "quis nostrud exercitation ullamco"),
(3, "laboris nisi ut aliquip");

insert into pages values 
(1, "Duis aute irure dolor in reprehenderit"),
(2, "in voluptate velit esse cillum"),
(3, "dolore eu fugiat nulla pariatur.");

Torne-o pesquisável:
ALTER TABLE articles ADD FULLTEXT(content);
ALTER TABLE events ADD FULLTEXT(content);
ALTER TABLE pages ADD FULLTEXT(content);

Use um UNION para pesquisar todas essas tabelas:
set @target='dolor';

SELECT * from (
  SELECT 
    'articles' as 'table_name', id, 
    @articles_multiplier * (MATCH(content) AGAINST (@target)) as relevance
    from articles
  UNION
  SELECT 
    'events' as 'table_name', 
    id,
    @events_multiplier * (MATCH(content) AGAINST (@target)) as relevance
    from events
  UNION
  SELECT 
    'pages' as 'table_name', 
    id, 
    @pages_multiplier * (MATCH(content) AGAINST (@target)) as relevance
    from pages
)
as sitewide WHERE relevance > 0;

O resultado:
+------------+----+------------------+
| table_name | id | relevance        |
+------------+----+------------------+
| articles   |  1 | 1.98799377679825 |
| pages      |  3 | 0.65545331108093 |
+------------+----+------------------+