2012-01-28 4 views
0

J'essaie de faire un mini moteur de recherche pour un site contenant des produits. J'ai déjà considéré la recherche de texte intégral, la clause LIKE, etc. mais je veux quand même continuer parce que la base de données va être ridiculement énorme (des centaines de millions de produits).complexe mysql instruction select

Le design ressemble à ceci: j'ai une table qui associe les mots aux ID de mot. J'ai une autre table contenant toutes les paires d'ID de mot aux ID de produit pour lesquels le produit correspond. Lorsqu'un utilisateur recherche, disons, "carte mémoire 2 Go", le script analyse "2 Go" "mémoire" et "carte".

Puis-je utiliser:

SELECT pid 
    FROM indx_0 
WHERE wid = 294 OR wid = 20591 OR wid = 330 

Je finis avec des paires de mots correspondant à des produits.

J'ai un algorithme PHP pour décider quels produits vont au sommet en fonction de plusieurs choses. mais quand je charge 380k résultats dans un tableau php, le temps d'exécution devient ridiculement lent. si clairement, je ne peux pas faire ça. mais si je limite à dire, 1000 résultats par mot, l'exécution est rapide - mais elle n'inclut pas tous les résultats possibles.

dans la table "indx_0" chaque "pid" (id produit) est unique à un "wid" (mot id) .. et clairement, certains produits vont avoir plus d'une correspondance. Je veux récupérer ces "pid" qui ont le plus de matches contre "wid" s. Supposons qu'il existe 2 000 produits correspondant à "2 Go" et 200 000 "carte" correspondante et 50 000 "mémoire" correspondants, mais seulement 20 produits correspondant à TOUS 3 de ces mots, et 200 produits correspondant à une combinaison de 2 de ces mots.

Est-il possible de récupérer ces 20 produits ainsi que les 200 produits qui correspondent en partie?

Répondre

2

Ce que vous avez probablement besoin de faire est de regrouper par l'ID de produit et d'obtenir un nombre correspondant. Alors l'ordre par le plus hit compte décroissant ... i.e. .: un produit correspond à tous les 3 Wids et les autres matches seulement 1, le 3 comte serait d'abord dans la liste

SELECT pid, count(*) WordMatchCount 
    FROM indx_0 
    WHERE pid in (294, 20591, 330) 
    group by pid 
    order by WordMatchCount desc 
    limit 1000 
+0

wow merci beaucoup! Une seule chose que j'avais besoin de changer .. le "WHERE pid in" est en fait "WHERE wid in". à part ça ça marche comme je le voulais. – nick