CONNEXION
  • RetourJeux
    • Tests
    • Soluces
    • Previews
    • Sorties
    • Hit Parade
    • Les + attendus
    • Tous les Jeux
  • RetourActu
    • Culture Geek
    • Astuces
    • Réalité Virtuelle
    • Rétrogaming
    • Toutes les actus
  • RetourHigh-Tech
    • Actus JVTECH
    • Bons plans
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTECH
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch
    • Xbox Series
    • Overwatch 2
    • FUT 23
    • League of Legends
    • Genshin Impact
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • PS4
  • One
  • Switch
  • Wii U
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Etoile Abonnement RSS

Sujet : [Database]Sélection aléatoire d'un utilisateur avec contraintes

DébutPage précedente
1
Page suivantePage suivante
_Anjou _Anjou
MP
Niveau 9
03 mai 2016 à 05:39:06

Bonjour,
J'ai trouvé quelques solutions à un problème, énoncé ci-dessous, mais elles ne me semblent pas optimales du tout. J'aurais donc besoin de votre aide, si jamais vous avez des idées ou des modifications à apporter.

Pour info, j'utilise Node pour le serveur et MongoDB pour la database mais je vais essayer d'expliquer sans trop rentrer dans les spécificités du stack.

J'ai également posté sur SO, voici le lien : http://stackoverflow.com/questions/36993626/selecting-a-random-user-with-constraints

Ma base de données contient deux collections : users et pictures (une collection, c'est plus ou moins l'équivalent d'une table en SQL)

Je dois implémenter une fonction sendPicture(picture_id) qui envoie une photo à un utilisateur au hasard de la collection users.
C'est plutôt trivial pour le moment, il suffit de choisir un utilisateur au hasard et lui envoyer la photo.

Personnellement, ce que je fais pour choisir un utilisateur au hasard, j'index un certain champ du document user ( un document c'est plus ou moins l'équivalent d'un row en SQL) et cet index est représenté sur une sphère. Ensuite, je génère un point aléatoire sur la sphère et je récupère le document dont le point du champ indexé est le plus proche du point généré aléatoirement. Cette information n'a pas réellement d'importance, c'est juste pour ceux que ça intéresse.

Donc le problème vient du fait que la fonction sendPicture(picture_id) peut être exécutée plusieurs fois, je n'ai aucun moyen de prévoir le nombre, ça varie pour chaque photo. Ainsi, comme la photo peut être envoyée plusieurs fois, à chaque fois à un utilisateur au hasard, il se peut qu'un utilisateur reçoive plusieurs fois la même photo, ce que je veux éviter.

Donc la première solution que j'ai mis en place c'est d'avoir un tableau seenBy dans le document de chaque photo. Quand la fonction sendPicture(...) est exécutée, je sélectionne un utilisateur au hasard de ma collection users, je vérifie si son identifiant (user_id) est dans le tableau seenBy.
S'il est dans le tableau, c'est que l'utilisateur a déjà vu la photo donc j'en choisi un autre, et ainsi de suite.
S'il n'est pas dans le tableau, c'est qu'il n'a pas encore vu la photo donc je la lui envoie et je rentre son user_id dans le tableau.

Le problème avec cette approche c'est que, par exemple, si j'ai 100 utilisateurs et que 99 d'entres eux ont déjà vu la photo, il faudra, dans le pire des cas, que je sélectionne aléatoirement 99 utilisateurs avant de trouver celui qui n'a pas vu la photo. (à condition que la distribution soit uniforme)
C'est clairement pas efficace.

La deuxième consiste à faire l'inverse, pour chaque photo, on a un tableau notSeenBy, qui contient, au départ, lorsque la photo n'a été envoyée à personne, la liste de tous les utilisateurs. Ensuite, quand on envoie la photo, on a juste à prendre au hasard un utilisateur de ce tableau, on lui envoie la photo puis on retire son user_id du tableau.
C'est plus efficace lors de l'envoie puisqu'on trouve un utilisateur qui n'a pas vu la photo du premier coup mais ça pose un problème au niveau de la méthode de génération aléatoire de l'utilisateur puisqu'on ne peut plus utiliser d'index sphérique. De plus, ça augmente énormément la taille des documents puisqu'on doit stocker au départ, la liste de tous les utilisateurs et ce, pour chaque photo.
Et comme je ne sais pas combien de fois la fonction sendPicture(...) va être exécutée, ça peut être 2 fois comme 100, je ne pense pas que ce soit la meilleure option.

Après ce pavé, merci à ceux qui sont encore là :hap: que pensez-vous des solutions énoncées et en avez-vous une meilleure à proposer ? Merci d'avance.

Y'aurait-il un moyen d'utiliser la coordonnée Y pour différencier le utilisateurs qui ont vu une certaine photo de ceux qui ne l'ont pas vue ? (en simplifiant la sphère en plan cartésien).

_Anjou _Anjou
MP
Niveau 9
04 mai 2016 à 17:45:17

Quelqu'un a une idée ou c'est trop long à lire ?

Pour résumer la question en deux lignes c'est :

J'ai des utilisateurs et des photos. J'ai besoin d'une fonction qui prends une photo en argument et qui l'envoie à un utilisateur choisit au hasard. Le problème c'est que cette fonction peut être exécutée plusieurs fois avec la même photo en argument : comment je fais en sorte qu'un utilisateur ne reçoive pas deux fois la même photo (vu qu'il est choisit au hasard) ?

Merci d'avance :)

_Anjou _Anjou
MP
Niveau 9
04 mai 2016 à 18:30:21

Merci de ta réponse :)

Alors pour ce qui de l'idée c'est pas mal et ça me semble plus simple aussi mais je ne sais pas si je peux le faire avec Mongo de base. En plus, je complique tout en utilisant une méthode différente pour trouver un utilisateur au hasard, avec un point généré aléatoirement.
En fait, j'utilise cette méthode pour m'assurer de sélectionner un utilisateur qui s'est récemment connecté. Je place sur l'axe des X la date de la dernière visite de tous les utilisateurs et ensuite je génère un point entre [Date.Now - 2 jours, Date.Now]. De cette façon je suis sur de ne pas l'envoyer à quelqu'un qui ne s'est pas connecté depuis plus deux jours.

Je vais regarder si c'est possible de générer ce point et de sélectionner l'utilisateur le plus proche qui en même temps n'est pas dans seenBy. Je vous tiens au courant.

Sinon, à propose de ton commentaire, tu parles de Mongo en particulier ou de tous les systèmes NoSQL ?
J'utilise ça car c'est plutôt simple à coupler avec Node puis la plupart des tutoriels utilisent ce stack.

_Anjou _Anjou
MP
Niveau 9
14 mai 2016 à 01:03:33

Navré de ce up magistral, je n'ai pas vu que tu avais répondu.

Concernant ce que tu dis sur NoSQL, j'ai effectivement lu, à plusieurs reprises, que ce n'est pas forcément la meilleure des solutions puisque la plupart du temps c'est utilisé comme du SQL.

Mais comme c'était à la mode, j'avais envie d'essayer :hap:
Pour les quelques problèmes que tu as cité, j'utilise une librairie où tu dois définir des modèles à l'avance donc au final, c'est plus du SQL avec des Query différentes.

Je suis à quelques milliers de lignes pour le moment donc je vais réfléchir si je continue avec Mongo ou si je passe sur un système plus traditionnel, et je réécris la majorité du projet.

Ca dépendra si j'arrive trouvé une solution performante pour mon problème avec NoSQL mais vu comment tu l'as résolu en une Query avec SQL, je pense que le choix sera vite fait.

Merci encore :)

DébutPage précedente
1
Page suivantePage suivante
Répondre
Prévisu
?
Victime de harcèlement en ligne : comment réagir ?
Infos 0 connecté(s)

Gestion du forum

Modérateurs : godrik, LGV
Contacter les modérateurs - Règles du forum

Sujets à ne pas manquer

La vidéo du moment