Calculer les scores MATCH () CONTRE () à partir de la requête unifiée et non pour chaque table

10

J'essaie d'avoir un score pour toute la section des instructions SELECT

SELECT *,MATCH(`result`) AGAINST('keyword') as `score` FROM `table1` WHERE MATCH(`result`) AGAINST('keyword')
UNION
SELECT *,MATCH(`content`) AGAINST('keyword') as `score` FROM `table2` WHERE MATCH(`content`) AGAINST('keyword')
UNION
SELECT *,MATCH(`text`) AGAINST('keyword') as `score` FROM `table3` WHERE MATCH(`text`) AGAINST('keyword')

Dans ce cas, les scores sont par table + ils ne sont pas classés par pertinence

Mais j'ai essayé cette méthode qui fonctionne mais qui ne vaut pas la peine d'être produite

SELECT * FROM (
    SELECT *,MATCH(`result`) AGAINST('keyword') as `score` FROM `table1` WHERE MATCH(`result`) AGAINST('keyword')
    UNION
    SELECT *,MATCH(`content`) AGAINST('keyword') as `score` FROM `table2` WHERE MATCH(`content`) AGAINST('keyword')
    UNION
    SELECT *,MATCH(`text`) AGAINST('keyword') as `score` FROM `table3` WHERE MATCH(`text`) AGAINST('keyword')
) as `combined` ORDER BY `score` DESC

Le code ci-dessus n'est pas apprécié car les scores sont par table, ils sont joints et ordonnés. Une mauvaise approche.

J'ai donc essayé MATCH() AGAINST()pour dataen TOP NIVEAU SELECT et ce. (N'A PAS FONCTIONNÉ)

SELECT *,MATCH(`data`) AGAINST('keyword') as `good_score` FROM (
        SELECT *,`result` as `data`,MATCH(`result`) AGAINST('keyword') as `score` FROM `table1` WHERE MATCH(`result`) AGAINST('keyword')
        UNION
        SELECT *,`content` as `data`,MATCH(`content`) AGAINST('keyword') as `score` FROM `table2` WHERE MATCH(`content`) AGAINST('keyword')
        UNION
        SELECT *,`text` as `data`,MATCH(`text`) AGAINST('keyword') as `score` FROM `table3` WHERE MATCH(`text`) AGAINST('keyword')
    ) as `combined` ORDER BY `good_score` DESC

L'instruction ci-dessus est parfaite pour moi, mais elle ne fonctionne pas car la datacolonne est créée à la volée et elle ne prend pas en charge d'avoir un INDEX COMPLET.

Ma question est de savoir comment procéder pour faire fonctionner mon moteur.

  • Pouvez-vous en quelque sorte faire dataun FULLTEXT
  • Existe-t-il un moyen de le faire fonctionner autre qu'en mode booléen qui ne prend pas en charge les scores
  • Existe-t-il une approche de tout ce sujet qui le ferait fonctionner? La création d'une table temporaire ne résout pas ce problème, la règle de 50% de MATCH () AGAINST () fait qu'une requête renvoie 0 résultats, mais il y en a beaucoup
  • Peut-être qu'il y a un petit quelque chose qui me manque?
  • La création d'une VIEW ne fonctionne pas non plus, MySQL ne prend pas en charge les INDEX sur les VIEW.
  • Peut-être que c'est une bonne idée d'utiliser EN MODE BOOLÉEN et de créer un score manuellement?

Je travaille sur ce problème depuis plus de deux jours. Je demande donc de l'aide. Merci.

dachints
la source

Réponses:

2

Vous pourriez peut-être enregistrer les éléments suivants à partir des trois (3) tableaux

  • nom de la table
  • la colonne du nom de la table
  • Index FULLTEXT sur la colonne

Voici le code:

DROP TABLE IF EXISTS combined_data;
CREATE TABLE combined_data
(
    source_table VARCHAR(64),
    source_id INT NOT NULL,
    data TEXT NOT NULL,
    FULLTEXT (data)
) ENGINE=MyISAM;
--
ALTER TABLE combined_data DISABLE KEYS;
--
INSERT INTO combined_data (source_table,source_id,data) VALUES
SELECT 'table1',id,`result` FROM table1 WHERE MATCH(`result`) AGAINST('keyword');
--
INSERT INTO combined_data (source_table,source_id,data) VALUES
SELECT 'table2',id,`content` FROM table1 WHERE MATCH(`content`) AGAINST('keyword');
--
INSERT INTO combined_data (source_table,source_id,data) VALUES
SELECT 'table3',id,`text` FROM table1 WHERE MATCH(`text`) AGAINST('keyword');
--
ALTER TABLE combined_data ENABLE KEYS;

Vous pouvez maintenant exécuter une seule requête sur la même table

SELECT *,MATCH(`data`) AGAINST('keyword') as `good_score`
FROM combined_data
ORDER BY `good_score` DESC;

Essaie !!!

RolandoMySQLDBA
la source
J'ai fait quelque chose de similaire auparavant et cela n'a pas fonctionné. Celui-ci ne fonctionne pas non plus. SELECT final à partir des données combinées en tant que bon score avec MATCH () et AGAINST () donne un résultat 0. J'ai fait des recherches sur ce problème et j'ai découvert que le mode NON IN BOOLEAN applique la règle des 50%, qui, de par sa nature, ignore les résultats d'une table lorsqu'il existe une relation mathématique avec 50% des résultats. Merci encore pour vos suggestions, mais j'aimerais entendre d'autres idées. Merci encore.
dachints