Moteur de recherche

Eléphant du PHP | 179 Messages

16 oct. 2005, 07:33

Bonjour à tous,

Je commence à créer les scripts pour mon moteur de recherche (recherche FULLTEXT). J'ai deux problèmes précis:

1. La requête n'est pas valide: il s'agit d'une erreur de syntaxe mais je n'ai pas réussi (d'après les tutoriaux) à la repérer.

2. Mon moteur de recherche fait appel à trois tables en même temps: une table "groupes", "societes" et "produits".

J'aimerais afficher dans un tableau les résultats. Il aurait deux colonnes: l'un donnant le nom de la "fiche" (ce peut être la fiche d'un groupe, d'une société ou d'un produit) où se trouve le résultat, l'autre affichant la phrase dans laquelle se trouve le mot recherché.

Est-ce que vous pourriez m'orienter pour la condition?

Merci d'avance pour votre aide.
<?php
// Récupération des données du formulaire
	$MotRech = $_POST['MotRech'];
?>

<input type="hidden" name="MotRech" value="<? echo $MotRech;?>">

<?php
//Connection à la base//
	$lien = mysql_connect("xx","xx","xx");
	mysql_select_db("xx", $lien);
//Requête
	$requete = "SELECT 
				g.NomGroupe, g.AutreNomGroupe, g.Presentation, g.InfCompl,
				s.NomSociete, s.AutreNomSociete, s.Presentation, s.InfCompl,
				p.NomProduit, p.Presentation
				FROM groupes AS g, societes AS s, produits AS p
				WHERE MATCH (g.NomGroupe, g.AutreNomGroupe, g.Presentation, g.InfCompl,
				s.NomSociete, s.AutreNomSociete, s.Presentation, s.InfCompl,
				p.NomProduit, p.Presentation IN BOOLEAN MODE)
				AGAINST ('".$MotRech."')";
	$result=mysql_query($requete);
//Si le mot recherché n'est pas présent dans la base, le signaler//
if ($result!=null && trim($result)!="")
	{
	echo "Il n'y a pas de résultat pour le mot recherché";
	}
//Sinon parcourir le tableau//
elseif 
	{
//Tant qu il y a des résultats, on affiche le nom des fiches et la phrase dans laquelle se trouve le mot//
	while ($val=mysql_fetch_array($result))
		{
		//Si la réponse appartient à une fiche "groupes" alors afficher le nom du groupe
		//Sinon tester si elle appartient à une fiches "societes" et afficher le nom de la societe
		//Sinon tester si elle appartient à une fiche "produits" alors afficher le nom du produit

		}
	}
?>

<tr>
	<td>
        </td>
	<td>
	</td>
</tr>

<?php
		}
	}
mysql_close($lien);
?>
	

Message pour la requête dans PHP-MyAdmin:

MySQL said: Documentation
#1064 - Erreur de syntaxe pr�s de 'IN BOOLEAN MODE)
AGAINST ('".$MotRech."') LIMIT 0, 30' � la ligne 8
Petit à petit, on devient moins petit... mais qu'est-ce qu'on vieillit!

Mammouth du PHP | 19672 Messages

16 oct. 2005, 08:59

Ben oui, regarde bien l'exemple de la doc: Tu as mal placé "IN BOOLEAN MODE" qui devrait être juste après le mot recherché de AGAINSTm ce qui donnerait :
//Requête
    $requete = "SELECT
                g.NomGroupe, g.AutreNomGroupe, g.Presentation, g.InfCompl,
                s.NomSociete, s.AutreNomSociete, s.Presentation, s.InfCompl,
                p.NomProduit, p.Presentation
                FROM groupes AS g, societes AS s, produits AS p
                WHERE MATCH (g.NomGroupe, g.AutreNomGroupe, g.Presentation, g.InfCompl,
                s.NomSociete, s.AutreNomSociete, s.Presentation, s.InfCompl,
                p.NomProduit, p.Presentation)
                AGAINST ('".$MotRech."' IN BOOLEAN MODE)";
À tester, je n'ai jamais utilisé ce type de recherche ;)
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 179 Messages

16 oct. 2005, 10:01

:oops: Disons que je cherchais une erreur de , ou de " ou de ' . A ma décharge, il était tôt... :wink: Merci !

Sinon quelqu'un a-t-il de la documentation ou connaît-il un lien qui pourrait m'aider à créer mes conditions?
Petit à petit, on devient moins petit... mais qu'est-ce qu'on vieillit!

Mammouth du PHP | 19672 Messages

16 oct. 2005, 10:07

En fin de compte, as-tu toujours un message d'erreur ?
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 179 Messages

16 oct. 2005, 10:16

Non c'était la bonne raison :P : ça passe parfaitement sous MyAdmin!
Petit à petit, on devient moins petit... mais qu'est-ce qu'on vieillit!

Mammouth du PHP | 19672 Messages

16 oct. 2005, 10:18

Alors un petit [Résolu] serait bienvenu :)

Pour les infos, à part la doc mentionnée plus haut, je ne sais personnellement pas vers où te diriger :-k
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 179 Messages

16 oct. 2005, 10:24

En fait, ce n'est pas vraiment résolu: j'ai du mal à créer mes conditions. Tu penses que je dois créer un nouveau topic?

Je voudrais faire qq chose qui traduise:
Si la réponse appartient à la table "Groupes" alors afficher le nom du groupe. Aprèsje pense que je parviendrai à me débrouiller.
Petit à petit, on devient moins petit... mais qu'est-ce qu'on vieillit!

Mammouth du PHP | 19672 Messages

16 oct. 2005, 10:33

En fait, j'ai du mal à saisir un élément: tu parles d'afficher un résultat sur deux colonnes alors que dans ta requêtes tu récupères 10 champs... ça va poser problème. D'autant qu'il n'y a aucune jointure entre les tables.

En clair, il faudrait à mon avis faire une requête pour chaque table: trois tables => trois requêtes.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 179 Messages

16 oct. 2005, 10:45

En fait, je voudrais faire ma recherche sur la totalité des champs sélectionnés, c'est pour cela que je n'ai pas besoin de jointures. En gros, je lui dis: cherche dans les champs désignés dans les trois tables puis affiche les résultats.

Ex d'affichage pour la recherche du mot "blabla"

Nom / Mot(s) dans la phrase

Groupe "Bonbon" (table Groupes) / Le groupe "Bonbon" a été créé par blabla.
Societe Chocolat (table société) / Blabla a pris la tête de la société en 2001.
Produit Cacao (table produits) / Sous l'impulsion de blabla, nous avons..

Je pensais pouvoir faire une seul requête de recherche.
Petit à petit, on devient moins petit... mais qu'est-ce qu'on vieillit!

Mammouth du PHP | 19672 Messages

16 oct. 2005, 10:49

Ce n'est pas logique: tu as les éléments requis pour une jointure: si tu cherches "Bonbon", tu ne t'attends pas à sortir la société "Les métaux ferreux du Cantal S.A." j'imagine: donc tu peux ajouter en clause WHERE la jointure entre les produits et les société et celle entre les sociétés et les groupes.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 179 Messages

16 oct. 2005, 10:54

Tu penses que je dois faire trois requêtes successives puis que je peux afficher les résultats en un seul tableau?
Petit à petit, on devient moins petit... mais qu'est-ce qu'on vieillit!

Mammouth du PHP | 19672 Messages

16 oct. 2005, 11:45

Personnellement, c'est ce que je ferais en stockant au fur et à mesure les résultats obtenus dans un tableau indexé et ensuite tu pourras facilement afficher les résultats en utilisant ce tableau indexé.

Mais d'un autre coté, rien n'interdirait à priori de faire une jointure pour la raison que j'ai mentionnée plus tôt, sinon tu auras un produit cartésien bizarre. Ça pourrait ressembler à ceci (à tester) :
<?php
//Requête
    $requete = "SELECT
                g.NomGroupe, g.AutreNomGroupe, g.Presentation, g.InfCompl,
                s.NomSociete, s.AutreNomSociete, s.Presentation, s.InfCompl,
                p.NomProduit, p.Presentation
                FROM groupes AS g, societes AS s, produits AS p
                WHERE MATCH (g.NomGroupe, g.AutreNomGroupe, g.Presentation, g.InfCompl,
                s.NomSociete, s.AutreNomSociete, s.Presentation, s.InfCompl,
                p.NomProduit, p.Presentation)
                AGAINST ('".$MotRech."' IN BOOLEAN MODE)
                AND g.idGroupe = s.idGroupe
                AND s.idProduit = p.idProduit";
?>
Note : vérifie les noms des champs identifiants que j'ai mis par rapport à tes propres noms de champ.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 179 Messages

17 oct. 2005, 13:54

Bonjour,
Mais d'un autre coté, rien n'interdirait à priori de faire une jointure pour la raison que j'ai mentionnée plus tôt, sinon tu auras un produit cartésien bizarre. Ça pourrait ressembler à ceci (à tester) :
Après divers essais j'ai tenté la formule "jointure" (si je n'y arrive pas, je tenterai l'autre méthode).

Le code que j'ai actuellement a l'air de fonctionner mais j'ai beaucoup de doublons. J'ai essayé de rajouter DISTINCT à la requête mais ça ne fonctionne pas. Si vous avez une suggestion, je suis preneuse.

Par ailleurs, je voudrais effectuer plusieurs conditions successives mais je ne connais que if...elseif...elseif...else. Or je voudrais que ces conditions ne dépendent pas les unes des autres (si...alors, si... alors). Est-ce que je peux les faire se succéder les unes les autres en toute indépendance?

Voici le début de mon code tel qu'il est actuellement:
<?php
// Récupération des données du formulaire
	$MotRech = $_POST['MotRech'];
?>

<input type="hidden" name="MotRech" value="<? echo $MotRech;?>">

<?php
//Connection à la base//
	$lien = mysql_connect("xx","xx","xx");
	mysql_select_db("xx", $lien);
//Requête
	$requete = "SELECT g.NomGroupe, g.AutreNomGroupe, g.Presentation, g.InfCompl, s.NomSociete, s.AutreNomSociete, s.Presentation, s.InfCompl, p.NomProduit, p.Presentation
FROM groupes AS g, societes AS s, produits AS p
WHERE MATCH (g.NomGroupe, g.AutreNomGroupe, g.Presentation, g.InfCompl, 
			s.NomSociete, s.AutreNomSociete, s.Presentation, s.InfCompl, 
			p.NomProduit, p.Presentation)
AGAINST ('".$MotRech."' IN BOOLEAN MODE)
AND IdGroupe = RefGroupe
AND IdSociete = RefSociete
ORDER BY cpt DESC ";
	echo $requete;
	$result=mysql_query($requete);
	
	$IdGroupe = mysql_result($result,0,'IdGroupe');
	$NomGroupe = mysql_result($result,0,'NomGroupe');
	$AutreNomGroupe = mysql_result($result,0,'AutreNomGroupe');
	$GPresentation = mysql_result($result,0,'g.Presentation');
	$GInfCompl = mysql_result($result,0,'g.InfCompl');
	$IdSociete = mysql_result($result,0,'IdSociete');
	$NomSociete = mysql_result($result,0,'NomSociete');
	$AutreNomSociete = mysql_result($result,0,'AutreNomSociete');
	$SPresentation = mysql_result($result,0,'s.Presentation');
	$SInfCompl = mysql_result($result,0,'s.InfCompl');
	$IdProduit = mysql_result($result,0,'IdProduit');
	$NomProduit = mysql_result($result,0,'NomProduit');
	$PPresentation = mysql_result($result,0,'p.Presentation');

//S'il n'y a pas de résultat//
	if(mysql_num_rows($result) == 0)
		{
    	echo "Il n'y a pas de résultat pour le(s) mot(s) recherché(s)";
    	}
//Sinon on parcourt le tableau de résultats//
	else
    	{
       	while($val=mysql_fetch_assoc($result))
    		{ 
			//Si le résultat appartient à la table "groupes"//
			if (array($result == $NomGroupe || $AutreNomGroupe || $GPresentation || $GInfCompl))
				{
	?>
	<a href="xx.php?IdGroupe=<?php print ($val["IdGroupe"]); ?>"><?php print ($val['NomGroupe']); ?><br />
	<?php 
		
				}
			}
		}
	mysql_close($lien);
	?>
Petit à petit, on devient moins petit... mais qu'est-ce qu'on vieillit!

Mammouth du PHP | 19672 Messages

17 oct. 2005, 14:14

Décidément, j'ai du mal à comprendre ce que tu essayes de faire: tu récupères le résultat de 12 champs mais tu n'en utilises que 2 dans la construction des liens. Je ne comprends pas beaucoup plus cette ligne-ci:
if (array($result == $NomGroupe || $AutreNomGroupe || $GPresentation || $GInfCompl))
:?:

Ton code simplifié devrait donc ressembler à ceci :
<?php
/* Récupération des données du formulaire */
$MotRech = $_POST['MotRech'];
?>
<input type="hidden" name="MotRech" value="<?php echo($MotRech); ?>">
<?php
/* Connection à la base */
$lien = mysql_connect("xx","xx","xx");
mysql_select_db("xx", $lien);
/* Requête */
$requete = "SELECT g.NomGroupe, 
                   g.AutreNomGroupe, 
                   g.Presentation, 
                   g.InfCompl, 
            FROM groupes AS g, societes AS s, produits AS p
            WHERE MATCH (g.NomGroupe, g.AutreNomGroupe, g.Presentation, g.InfCompl,
                         s.NomSociete, s.AutreNomSociete, s.Presentation, s.InfCompl,
                         p.NomProduit, p.Presentation)
            AGAINST ('".$MotRech."' IN BOOLEAN MODE)
            AND IdGroupe = RefGroupe
            AND IdSociete = RefSociete
            ORDER BY cpt DESC ";
echo $requete;
$result = mysql_query($requete);

if(mysql_num_rows($result) >= 0)
{
    /* On parcourt le tableau de résultats */
    while($val = mysql_fetch_assoc($result))
    {
?>
<a href="xx.php?IdGroupe=<?php print ($val["IdGroupe"]); ?>"><?php print ($val['NomGroupe']); ?></a><br />
<?php

    }
}
/* S'il n'y a pas de résultat */
else
{
    echo "Il n'y a pas de résultat pour le(s) mot(s) recherché(s)";
}
mysql_close($lien);
?>
Maintenant, tu parles de doublons : si tu utilises une clause DISTINCT, la requête doit être assortie d'un GROUP BY... Quel requête as-tu utilisée et quel message d'erreur as-tu eu en retour ?
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Eléphant du PHP | 179 Messages

17 oct. 2005, 15:19

Ah la pédagogie, ça a toujours été mon fort... :lol:

Je m'explique. Je dois probablement faire des erreurs de logique et de constructions.

Admettons que je cherche le mot "collecter" dans mes trois tables et dans les champs choisis.

1. Je sélectionne les champs des tables où je veux faire ma recherche.
$requete = "SELECT g.NomGroupe,
                   g.AutreNomGroupe,
                   g.Presentation,
                   g.InfCompl,
            FROM groupes AS g, societes AS s, produits AS p
            WHERE MATCH (g.NomGroupe, g.AutreNomGroupe, g.Presentation, g.InfCompl,
                         s.NomSociete, s.AutreNomSociete, s.Presentation, s.InfCompl,
                         p.NomProduit, p.Presentation)
            AGAINST ('".$MotRech."' IN BOOLEAN MODE)
            AND IdGroupe = RefGroupe
            AND IdSociete = RefSociete
            ORDER BY cpt DESC ";
echo $requete;
$result = mysql_query($requete); 
2. S'il n'y a pas de réponse, alors je le signale. Il est vrai que j'aurais pu faire comme tu me le soumets dans ta réponse. Mais je pensais que ce serait plus simple si je le plaçais avant.
//S'il n'y a pas de résultat//
    if(mysql_num_rows($result) == 0)
        {
        echo "Il n'y a pas de résultat pour le(s) mot(s) recherché(s)";
        } 
3. S'il y a des réponses
//Sinon on parcourt le tableau de résultats//
    else
        {
           while($val=mysql_fetch_assoc($result))
            { 
alors je les affiche --> trois suppositions:

Je vérifie si j'ai obtenu des réponses qui appartiennent à la table "groupes". Dans ce cas, j'affiche les noms des fiches "groupe" dans lesquelles j'ai trouvé des réponses.
//Si le résultat appartient à la table "groupes"//
            if ($result == $NomGroupe || $AutreNomGroupe || $GPresentation || $GInfCompl))
                {
    ?>
    <a href="xx.php?IdGroupe=<?php print ($val["IdGroupe"]); ?>"><?php print ($val['NomGroupe']); ?><br />
    <?php 
                }
    ?>
Puis je vérifie si j'ai obtenu des réponses qui appartiennent à la table "sociétés".

Enfin je vérifie si j'ai obtenu des réponses qui appartiennent à la table "produits".

Pour le moment, je teste seulement pour les réponses qui appartiennent à la table "groupe" avant de développer le reste.

Différents constats:
1. La requête fonctionne parfaitement sous myadmin et donne des résultats. Il semble qu'à chaque fois qu'il rencontre le mot recherché, il m'affiche l'enregistrement (donc l'id et le nom du groupe) dans lequel il l'a trouvé. Si le mot s'y trouve plusieurs fois, il me cite le même enregistrement. C'est pourquoi je parle de doublons.

2. Lorsque je teste le script en local, il m'affiche:
Warning: mysql_result(): supplied argument is not a valid MySQL result resource in c:\program files\easyphp1-8\www\161005\user\moteur2.php on line 25

Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in c:\program files\easyphp1-8\www\161005\user\moteur2.php on line 40
Voilà. Je suis perdue... :( [/php]
Petit à petit, on devient moins petit... mais qu'est-ce qu'on vieillit!