2012-12-12 3 views
1

classé par l'utilisateur, je briserai cela en deux parties:Trouvez le meilleur match de MySQL pour la liste

  1. J'ai un utilisateur avec une liste de produits « caractéristiques » qu'il désire. L'utilisateur est invité à classer ces fonctionnalités de 1-10. J'ai aussi une table pleine de produits. Chacun de ces produits a diverses caractéristiques. Certains produits auront toutes les fonctionnalités 1-10, mais certains n'en auront que quelques-uns. Je voudrais déterminer quel produit correspond le mieux au classement de l'utilisateur, et fournir un ensemble de résultats ordonné à l'utilisateur, avec la meilleure correspondance en premier et la pire en dernier.

  2. La requête mentionnée ci-dessus n'est en fait qu'une partie de ce que fait l'utilisateur. L'utilisateur fournit également d'autres critères de recherche (par exemple, catégorie de produit, prix, etc.) avec le classement des caractéristiques. Par conséquent, j'aimerais que la fonctionnalité de correspondance ne s'applique qu'aux produits qui passent par cet ensemble de filtres. Comment pourrais-je les combiner?

J'ai trouvé des questions similaires comme this et this, mais ils ne sont pas assez près pour moi de comprendre comment appliquer ces solutions à ma situation.

Les tables impliquées ressembler à quelque chose comme ceci:

produits (id, produits)

caractéristiques (id, fonctionnalité)

product_features (id, product_id, feature_id)

et la l'utilisateur soumettra sa recherche à travers un tableau comme celui-ci (où les clés sont en fait des identifiants de caractéristiques, et le rang est la valeur):

[users_features] => Array 
    (
     [1] => Array 
      (
       [rank] => 9 
      ) 

     [2] => Array 
      (
       [rank] => 1 
      ) 

     [3] => Array 
      (
       [rank] => 3 
      ) 

(ce sera un tableau 10 de l'élément en ce moment, mais pourrait changer à l'avenir)

) 
+0

Un problème que je vois ici est que les produits qui ont toutes les caractéristiques seront toujours classés en haut de la liste - sauf si c'est OK. –

+0

Vous avez besoin d'un moyen d'appliquer les classements aux fonctionnalités. Par exemple, si un produit ne correspond qu'à rank = 1 mais qu'un autre correspond à rank = 2 et 3, lequel est choisi? –

+0

@EricPetroelje c'est correct si tous les produits ayant toutes les caractéristiques se classent en haut. – HipN

Répondre

0

Je ne peux pas tout à fait que cela fonctionne en utilisant uniquement SQL mais une solution simple de PHP serait similaire à ce qui suit (non testé):

//Array of $productId => list of feature ids 
$products; 
$userFeatures; 
$scores = array(); 
//For every product work out a score based on features and user ranking. 
foreach($products as $productId => $prodFeatures){ 
    $score = 0; 
    foreach($prodFeatures as $feature){ 
     //Could also perhaps penalise products lacking features. 
     $score += $userFeatures[$feature]["rank"]; 
    } 
    $scores[$productId] = $score; 
} 
arsort($scores); 
echo "Best match is ".$scores[0]; 

Évidemment, c'est un peu rude et prêt mais j'espère que cela aide.

Éditer: Cela suppose qu'un classement de 10 est le meilleur.

+0

votre concept de notation et l'utilisation de 10 comme le meilleur rang a beaucoup de sens.J'ai exécuté quelques scénarios de tableur, et il semble fonctionner assez bien. recommanderiez-vous d'abord d'exécuter les requêtes 'filter', puis de construire un tableau de produits à partir de cet ensemble de résultats et de sauter dans cette fonction de notation? – HipN

+0

J'ai fini par aller avec votre approche. J'ai exécuté mes requêtes de filtre, puis utilisé un tableau d'identifiants de produit à partir de ce résultat pour commencer cette routine d'évaluation. Merci! – HipN

0

Une solution consiste à diviser 1 par le rang de l'utilisateur. Par exemple 1/R. Puis additionnez toutes les possibilités et triez la liste par ordre descendant. 1/R est également l'occasion de ne pas choisir ce produit dans la liste. Lorsque vous devez normaliser la valeur ou rendre la somme des valeurs égale à 1, vous devez multiplier la valeur par la somme de tous les reziprokes des valeurs. Par exemple, r1 = 30 et r2 = 15. 1/(1/30 + 1/15) = 10, donc P1 = 10 * 1/30 = 1/3 et P2 = 10 * 1/15 = 2/3. Lorsque vous normaliser la valeur, cela signifie également qu'un produit avec moins d'attributs est également moins probable.

+0

Cela semble intéressant, mais pour la vie de moi, je ne peux pas tout à fait comprendre comment l'appliquer. Dans votre exemple, r1 et r2 sont-ils les rangs des entités 1 et 2? Les produits P1 et P2 sont-ils 1 et 2? – HipN

+0

1) oui 2) non. P1 et p2 sont aussi les rangs des caractéristiques mais normalisés de sorte que la somme de tous est de 1. – Bytemain

+0

ah! Je l'obtiens maintenant ... est logique comme un moyen de marquer chaque produit en fonction de ses caractéristiques, et toujours utiliser un rang de 1 comme le plus élevé. Avez-vous des recommandations sur la façon de structurer la requête? – HipN