MySQL match () against () – ordre par pertinence et colonne?

Ok, donc j’essaie de faire une recherche en texte intégral dans plusieurs colonnes, quelque chose de simple comme ceci:

SELECT * FROM pages WHERE MATCH(head, body) AGAINST('some words' IN BOOLEAN MODE) 

Maintenant, je veux commander par pertinence (combien de mots sont trouvés?), Ce que j’ai pu faire avec quelque chose comme ceci:

 SELECT * , MATCH (head, body) AGAINST ('some words' IN BOOLEAN MODE) AS relevance FROM pages WHERE MATCH (head, body) AGAINST ('some words' IN BOOLEAN MODE) ORDER BY relevance 

Maintenant, voici la partie où je me perds, je veux donner la priorité à la pertinence dans la colonne de head .

Je suppose que je pourrais créer deux colonnes de pertinence, une pour la head et une pour le body , mais à ce moment-là, je ferais trois fois la même recherche dans le tableau et pour ce que je fais, les performances sont importantes. puisque la requête sera à la fois jointe et comparée aux autres tables.

Ma principale question est donc la suivante : existe-t-il un moyen plus rapide de rechercher la pertinence et de hiérarchiser certaines colonnes? (Et en tant que bonus, même en faisant de la pertinence le nombre de fois que les mots apparaissent dans les colonnes?)

Toute suggestion ou conseil serait génial.

Remarque: je vais l’exécuter sur un serveur LAMP. (WAMP dans les tests locaux)

Cela peut donner une pertinence accrue à la partie principale que vous souhaitez. Cela ne le doublera pas, mais cela pourrait être suffisant pour vous:

 SELECT pages.*, MATCH (head, body) AGAINST ('some words') AS relevance, MATCH (head) AGAINST ('some words') AS title_relevance FROM pages WHERE MATCH (head, body) AGAINST ('some words') ORDER BY title_relevance DESC, relevance DESC -- alternatively: ORDER BY title_relevance + relevance DESC 

Une alternative que vous souhaitez également étudier, si vous avez la possibilité de changer de moteur DB, est Postgres . Cela permet de définir le poids des opérateurs et de jouer avec le classement.

Je ne l’ai jamais fait, mais il semble que

 MATCH (head, head, body) AGAINST ('some words' IN BOOLEAN MODE) 

Doit donner un double poids aux allumettes trouvées dans la tête.


Il suffit de lire ce commentaire sur la page de document , Pensé que cela pourrait être utile pour vous:

Publié par Pasortingck O’Lone le 9 décembre 2002 6h51

Il convient de noter dans la documentation que IN BOOLEAN MODE renverra presque toujours une pertinence de 1,0. Pour obtenir une pertinence significative, vous devez:

 SELECT MATCH('Content') AGAINST ('keyword1 keyword2') as Relevance FROM table WHERE MATCH ('Content') AGAINST('+keyword1+keyword2' IN BOOLEAN MODE) HAVING Relevance > 0.2 ORDER BY Relevance DESC 

Notez que vous effectuez une requête de pertinence régulière pour obtenir des facteurs de pertinence combinés avec une clause WHERE qui utilise BOOLEAN MODE. Le MODE BOOLEAN vous donne le sous-ensemble qui répond aux exigences de la recherche BOOLEAN, la requête de pertinence remplit le facteur de pertinence et la clause HAVING (dans ce cas) garantit que le document est pertinent pour la recherche (c.-à-d. sont considérés comme non pertinents). Cela vous permet également de commander par pertinence.

Cela peut être ou ne pas être un bogue dans le fonctionnement d’IN BOOLEAN MODE, bien que les commentaires que j’ai lus sur la liste de diffusion suggèrent que le classement de pertinence d’IN BOOLEAN MODE n’est pas très compliqué, se prêtant mal aux documents pertinents. BTW – Je n’ai pas remarqué de perte de performance pour cela, car il semble que MySQL n’effectue qu’une seule fois la recherche FULLTEXT, même si les deux clauses MATCH sont différentes. Utilisez EXPLAIN pour le prouver.

Il semblerait donc que vous n’ayez pas à vous soucier d’appeler la recherche de texte intégral deux fois, même si vous devez toujours “utiliser EXPLAIN pour le prouver”

Il suffit d’append pour qui pourrait avoir besoin .. N’oubliez pas de modifier la table!

 ALTER TABLE table_name ADD FULLTEXT(column_name); 

Je jouais juste avec ça aussi. Vous pouvez append un poids supplémentaire dans la zone ORDER BY du code.

Par exemple, si vous correspondez à 3 colonnes différentes et souhaitez pondérer plus fortement certaines colonnes:

 SELECT search.*, MATCH (name) AGAINST ('black' IN BOOLEAN MODE) AS name_match, MATCH (keywords) AGAINST ('black' IN BOOLEAN MODE) AS keyword_match, MATCH (description) AGAINST ('black' IN BOOLEAN MODE) AS description_match FROM search WHERE MATCH (name, keywords, description) AGAINST ('black' IN BOOLEAN MODE) ORDER BY (name_match * 3 + keyword_match * 2 + description_match) DESC LIMIT 0,100;