sql >> Databasteknik >  >> RDS >> Mysql

Mysql fulltext sökrelevans över flera tabeller

Ja, du kan förena dem mycket bra med en sökmotor som Apache Lucene och Solr.

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

Om du bara behöver göra det i MySQL kan du göra detta med en UNION. Du kommer förmodligen att vilja undertrycka alla nollrelevanta resultat.

Du måste bestämma hur du vill påverka relevansen beroende på vilken tabell som matchar.

Anta till exempel att du vill att artiklarna ska vara viktigast, händelserna ska vara medelviktiga och sidorna ska vara minst viktiga. Du kan använda multiplikatorer så här:

set @articles_multiplier=3;
set @events_multiplier=2;
set @pages_multiplier=1;

Här är ett fungerande exempel som du kan prova som visar några av dessa tekniker:

Skapa exempeldata:

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.");

Gör det sökbart:

ALTER TABLE articles ADD FULLTEXT(content);
ALTER TABLE events ADD FULLTEXT(content);
ALTER TABLE pages ADD FULLTEXT(content);

Använd en UNION för att söka i alla dessa tabeller:

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;

Resultatet:

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


  1. Varför ska jag inte använda mysql_*-funktioner i PHP?

  2. Konvertera en juliansk dag till ett datum i PostgreSQL

  3. MariaDB Varning:'[email protected]' har både ... Lösenordet kommer att ignoreras

  4. PHP, ORM, MSSQL och Unicode, är det möjligt att få dessa att fungera tillsammans?