Moteur de recherche sur plusieurs tables

Fredy07
Invité n'ayant pas de compte PHPfrance

17 août 2009, 08:06

Bonjour,

Je voudrais effectuer des recherches sur plusieurs tables, qui, plus ou moins, comportent les meme champs, mais se pose 2 problemes:

1- Soit que le mot recherche ne se trouve pas par la query, alors qu'il existe dans la table,
2- Soit il me donne des resultats doublons.

Voila les 2 tables:

Code : Tout sélectionner

CREATE TABLE IF NOT EXISTS `recherche1` ( `id` int(2) NOT NULL auto_increment, `titre` varchar(20) collate latin1_general_ci NOT NULL, `texte` longtext collate latin1_general_ci NOT NULL, `url` varchar(30) collate latin1_general_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=4 ; -- -- Dumping data for table `recherche1` -- INSERT INTO `recherche1` (`id`, `titre`, `texte`, `url`) VALUES (1, 'titre 1 de recherche', 'c''est la premiere fois que je code du php', 'code.php'), (2, 'titre 2 recherche 1', 'j''adore coder du php', 'code1.php'), (3, 'fonction php', 'fonction', 'code.php'); CREATE TABLE IF NOT EXISTS `recherche2` ( `id` int(2) NOT NULL auto_increment, `titre` varchar(20) collate latin1_general_ci NOT NULL, `texte` longtext collate latin1_general_ci NOT NULL, `url` varchar(30) collate latin1_general_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=3 ; -- -- Dumping data for table `recherche2` -- INSERT INTO `recherche2` (`id`, `titre`, `texte`, `url`) VALUES (1, 'titre 1 de recherche', 'c''est la premiere fois que je code du php2', 'code2.php'), (2, 'titre 2 recherche2', 'j''adore coder du php2', 'code3.php');
et le code de recherche simple:
// connexion et tout le blabla

$word = 'fonction'; // avec fonction, il me donne des resultats errones, et avec php il me donne de bons resultats

$query = "select * from recherche1, recherche2 where recherche1.texte LIKE '%$word%' OR recherche2.texte LIKE '%$word%'";

echo $query.'<br>';

$result = mysql_query ($query) or die (mysql_error());

$total = mysql_num_rows($result);

echo $total.' resultats<br>';
if ($total) {
	
	while ($row = mysql_fetch_array($result)) {
		
		$texte = $row['texte'];
		$titre = $row['titre'];
		$url = $row['url'];
		$id = $row['id'];
				
		
		echo 'id: '.$id.' '.$titre;
		echo '<br>'.$texte;
		echo '<br>'.$url.'<hr>';
			
			}

		
		}
		

else
{
	echo 'Aucun resultat';
}

?>

Modérateur PHPfrance
Modérateur PHPfrance | 6373 Messages

17 août 2009, 10:35

Il faut nous donner le résultat de cette ligne :
echo $query.'<br>';
Vérifie que ça donne ce que tu veux et teste direct dans phpMyAdmin (ou autre) avant de l'intégrer dans ton code PHP.

Voir ces conseils de débuggage généraux : sql-bases-donnees/php-sql-etapes-suivre ... 19378.html

Et regarde ce lien qui pourrait t'intéresser : http://dev.mysql.com/doc/refman/5.0/fr/ ... earch.html

Fredy07
Invité n'ayant pas de compte PHPfrance

18 août 2009, 08:33

Il faut nous donner le résultat de cette ligne :
voila le resultat de echo sur la requete:
select * from recherche1, recherche2 where recherche1.texte LIKE '%fonction%' OR recherche2.texte LIKE '%fonction%'

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

18 août 2009, 11:22

Comme il n'y a aucun critère permettant d'associer les enregistrements de tes tables, ta requête va générer un produit cartésien : tu vas retrouver chaque enregistrement de recherche1 qui contient "fonction" associé à tous les enregistrements de recherche2 (qu'ils contiennent "fonction" ou pas), ainsi que chaque enregistrement de recherche2 qui contient "fonction" associé à tous les enregistrements de recherche1...

Si tes deux tables n'ont pas de liens, il vaut mieux faire deux requêtes, que tu peux éventuellement regrouper à l'aide d'un union si les données récupérées sont au même format :

Code : Tout sélectionner

SELECT ... FROM recherche1 WHERE recherche1.texte LIKE '%fonction%' UNION SELECT ... FROM recherche2 WHERE recherche2.texte LIKE '%fonction%'
Nota : tu dois récupérer le même nombre de champs dans les selects :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

ViPHP
ViPHP | 4039 Messages

18 août 2009, 11:29

Et regarde ce lien qui pourrait t'intéresser : http://dev.mysql.com/doc/refman/5.0/fr/ ... earch.html
Et hop, j'appuie les dires d'Ouckileou. Encore une fois:
Et regarde ce lien qui pourrait t'intéresser : http://dev.mysql.com/doc/refman/5.0/fr/ ... earch.html
Jamais deux sans trois:
Et regarde ce lien qui pourrait t'intéresser : http://dev.mysql.com/doc/refman/5.0/fr/ ... earch.html
LIKE n'est PAS supposée être une fonctionnalité de recherche. Tout comme le <blink> en html, c'est un élément du langage mal interprété, abusé , violenté, parasité bien au delà du dégout. Sa seule application légitime que je peux concevoir pour le moment (alors que je suis en vacances), c'est pour éventuellement faire une recherche des plus globales sur la DB, quant on ne sait vraiment pas ou se cache l'information (genre quand on récupère une DB bien remplie qu'on ne sait même pas tout ce qu'il y a dedans).

MySQL possède une super interface de recherche en texte intégral, fait pour, pensé pour, et bien au delà des capacités du simple développeur web, sous la fome de "match.. against..." de la recherche booléenne, de la recherche naturelle, etc..

Alors voilà, je m'insurge contre toute pratique qui consiste à utiliser "LIKE" à des finalités de moteur de recherche. (pfouah, je me sens tout sale dans la bouche). Alors, encore une fois, le bon lien qu'il est bon de lire :

http://dev.mysql.com/doc/refman/5.0/fr/ ... earch.html

(et si je suis un peu incisif, c'est parce que je suis en vacances :wink: )
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

18 août 2009, 12:40

(et si je suis un peu incisif, c'est parce que je suis en vacances :wink: )
Ce n'est pas une raison, même si le propos est justifié... :non:

A la base, Like est effectivement un simple opérateur de comparaison.
MySQL propose de meilleurs outils pour effectuer des recherches (dont on aurait tort de se priver), mais ce n'est pas le cas de tous les SGBD. On va donc éviter de partir sur de grands chevaux à chaque fois qu'il y a un Like qui passe :)

(les vacances c'est fait pour se détendre ;))
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Fredy07
Invité n'ayant pas de compte PHPfrance

19 août 2009, 07:24

J'ai utlise cette requete:
$word = 'php'; // fonction

$query = "SELECT * FROM recherche1 WHERE MATCH (titre,texte) AGAINST ('$word') UNION SELECT * FROM recherche2 WHERE MATCH (titre,texte) AGAINST ('$word')";
si je cherche php, le resultat est aucun resultat, mais avec fonction comme mot clef, il me donne des resultats, voila la structure des tables:
CREATE TABLE IF NOT EXISTS `recherche1` (
  `id` int(2) NOT NULL auto_increment,
  `titre` varchar(20) collate latin1_general_ci NOT NULL,
  `texte` longtext collate latin1_general_ci NOT NULL,
  `url` varchar(30) collate latin1_general_ci NOT NULL,
  PRIMARY KEY  (`id`),
  FULLTEXT KEY `texte` (`titre`,`texte`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=4 ;# MySQL returned an empty result set (i.e. zero rows).


INSERT INTO `recherche1` (`id`, `titre`, `texte`, `url`) VALUES
(1, 'titre 1 de recherche', 'c''est la premiere fois que je code du php', 'code.php'),
(2, 'titre 2 recherche 1', 'j''adore coder du php', 'code1.php'),
(3, 'fonction php', 'fonction', 'code.php');# Affected rows: 3


CREATE TABLE IF NOT EXISTS `recherche2` (
  `id` int(2) NOT NULL auto_increment,
  `titre` varchar(20) collate latin1_general_ci NOT NULL,
  `texte` longtext collate latin1_general_ci NOT NULL,
  `url` varchar(30) collate latin1_general_ci NOT NULL,
  PRIMARY KEY  (`id`),
  FULLTEXT KEY `texte` (`titre`,`texte`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=4 ;# MySQL returned an empty result set (i.e. zero rows).


INSERT INTO `recherche2` (`id`, `titre`, `texte`, `url`) VALUES
(1, 'titre 1 de recherche', 'c''est la premiere fois que je code du php', 'code.php'),
(2, 'titre 2 recherche2', 'j''adore coder du php', 'code1.php'),
(3, 'fonction php', 'fonction', 'code.php');# Affected rows: 3