2009-11-22 3 views
2

J'ai un réseau social mis en place et via une API je veux rechercher les entrées. La base de données du réseau social est mysql. Je souhaite que la recherche renvoie les résultats au format suivant: Les résultats correspondant à la requête ET amis de l'utilisateur effectuant la recherche doivent être priorisés par rapport aux résultats qui correspondent simplement à la requête.Quelle est la meilleure façon de rechercher un réseau social en priorisant les relations avec les utilisateurs d'abord?

Donc, cela peut-il être fait dans une requête ou devrais-je faire deux requêtes distinctes et fusionner les résultats et supprimer les doublons? Je pourrais éventuellement construire une structure de données en utilisant Lucene et rechercher cet index efficacement, mais je me demande si la pénalité de mettre à jour un document chaque fois qu'une nouvelle relation est créée va être trop?

Merci

Répondre

1

La référence à l'équation Lucene complique un peu. Résolvons-le (ou au moins obtenir une ligne de base) sans le premier.

En supposant que le

 
tblUsers 
    UserId PK 
    UserName 
    Age 
    ... 

tblBuddies 
    UserId  FK to tblUsers.UserId 
    FriendId tblUsers.Userid = Id of one of the friends 
    BuddyRating  float 0.0 to 1.0 (or whatever normalized scale) indicating 
        the level of friendship/similarity/whatever 

tblItems 
    ItemId PK 
    ItemName 
    Description 
    Price 
    ... 

tblUsersToItems 
    UserId FK to tblUsers.UserId 
    ItemId FK to 
    ItemRating float 0.0 to 1.0 (or whatever normalized scale) indicating 
       the "value" assigned to item by user. 

datamodel suivant (ou quelque chose d'approchant Une requête naïve (mais une bonne base pour une optimisation d'un) pourrait être:.

 
SELECT [TOP 25] I.ItemId, ItemName, Description, SUM(ItemRating * BuddyRating) 
FROM tblItems I 
LEFT JOIN tblUserToItems UI ON I.ItemId = UI.ItemId 
LEFT JOIN tblBuddies B ON UI.UserId = B.FriendId 
WHERE B.UserId = 'IdOfCurrentUser' 
    AND SomeSearchCriteria -- Say ItemName = 'MP3 Player' 
GROUP BY I.ItemId, ItemName, Description 
ORDER BY SUM(ItemRating * BuddyRating) DESC 

L'idée est qu'un élément donné est donné plus de poids si recommandé/utilisé par un ami.Le poids supplémentaire est le plus important si l'ami est un ami proche [BuddyRating] et/ou si l'ami recommande cet article plus fortement [ItemRating]

L'optimisation d'une telle requête dépend du nombre total d'éléments, du nombre moyen/maximum d'amis d'un utilisateur donné, du nombre moyen/maximum d'éléments qu'un utilisateur peut avoir dans sa liste.

Est-ce que ce type d'idées/d'informations vous intéresse ou est-ce que la question me manque?

+0

MJV, je n'ai pas posé la question, mais je suis à la recherche d'une réponse au problème que vous avez posté - l'esprit de fournir votre solution lucene? – EugeneMi

+0

@EugeneMi J'ai bien peur de ne pas avoir de solution Lucene. J'ai fourni cette approche SQL simple pour affirmer que c'était généralement ce que l'OP était après. A l'époque j'aurais ajouté des extraits ou des pointeurs re. Lucene mais ça faisait longtemps que je n'avais pas travaillé avec Solr ou Lucene et je ne suis certainement pas à jour avec les dernières fonctionnalités de ce système (boosting, classement automatique en particulier venu à l'esprit ...) donc je ne commencerais même pas . – mjv

1

Un moyen consiste à stocker tous les graphiques de votre réseau social séparément de Lucene. Exécutez votre requête de mots clés sur Lucene et recherchez tous les amis dans votre graphique de réseau. Pour tous les amis qui sont retournés, booster tous les résultats de recherche de ces amis par un facteur et un recours. Ce re-tri serait fait en dehors de Lucene. J'ai déjà fait des choses comme ça et ça marche plutôt bien.

Vous pouvez également créer un HitCollector personnalisé qui augmente le nombre de hits collectés dans Lucene. Vous devez construire une liste d'ID internes Lucene appartenant aux amis de l'utilisateur actuel.

Votre graphique de réseau social peut être stocké dans Mysql, en mémoire sous la forme d'une matrice d'adjacence éparse, ou vous pouvez jeter un oeil à Neo4j.

Questions connexes