IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Ruby on Rails Discussion :

LiveSearch sur une grosse table : Ajax ? Ruby ? JS ?


Sujet :

Ruby on Rails

  1. #1
    Membre régulier Avatar de Miles Raymond
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2005
    Messages : 189
    Points : 83
    Points
    83
    Par défaut LiveSearch sur une grosse table : Ajax ? Ruby ? JS ?
    Bonjour,

    Voilà 2 jours que je tente différentes alternatives pour mon problème. Il se trouve que j'ai une table assez conséquente (environ 4000 enregistrements) et que j'aimerais pouvoir rechercher rapidement à l'intérieur de celle-ci.

    Dans mon application, en cliquant sur le bouton de recherche, une thickbox s'affiche contenant un champ de recherche et TOUT les éléments de ma table. Et quand on commence à taper dans le champ de recherche, ça me retourne les résultats au fur et à mesure. La pagination est hors de question, la recherche doit être quasiment instantanée. Pour le tri (car il y a du tri également) c'est pas mémorable niveau rapidité, mais ça peut passer (j'utilise le plugin tablesorter de jquery, si quelqu'un a une idée plus efficace).

    Pour la recherche par contre, je peut dire que j'ai essayer pas mal de chose différente. Ma première idée, et c'est toujours celle que j'imagine la plus rapide, était de pouvoir rechercher dans ma collection. C'est à dire que j'aimerais faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def list
    <div style="margin-left:40px">@clients = Client.find(:all)</div>end
     
    def live_search
    <div style="margin-left:40px">@results = @clients.find(params[:search_value]</div><div style="margin-left:40px">render :update do |page|</div><div style="margin-left:40px"><div style="margin-left:40px">page.replace_html "mon_div", :partial => @clients</div></div><div style="margin-left:40px">end</div>end
    En gros ! Seulement je n'ai rien trouvé là dessus sur Internet et en l'état, ça ne fonctionne pas. Soit j'ai un exception "wrong number of arguments" soit il ne m'affiche rien...

    Deuxième solution : on fait de l'ajax et chaque query est envoyé à la base. Mais dans ce cas là, il me fallait un truc rapide pour faire de la recherche dans du plain text. Première alternative : acts_as_ferret. Bof bof, ça marche pas top, l'indexation est bizarre, niveau rapidité c'est pas le nirvana, bref. Deuxième alternative : thinking_sphinx. Après un peu de difficulté à le mettre en place, c'est peut-être la solution la plus intéressante. Seulement sur 4000 enregistrements, ça reste assez long. Même si, évidemment, le temps de travail vient aussi du traitement des données récupérées (un simple requête postgres me prenant 200ms, Firebug lui, me dit que l'appel prend 600ms et l'affichage prends encore prêt d'une seconde...). Et comme j'ai eu d'autres problèmes avec thinking_sphinx (paging automatique, etc.) j'ai tenté une autre idée : la recherche en javascript. Après avoir essayer la librairie jquery quicksearch et un exemple de code qui ont,tous les deux, mis environ 10-15 secondes à me retourner un résultat (sur Safari, sur Firefox il me demandait si je voulais stopper le script), je suis en train de me dire que la recherche par JS c'est pas le top sur une grosse table.

    Donc j'en reviens à mon idée de base : rechercher dans ma collection. Mais vous, vous avez des idées ? D'autres librairies JS, une possibilité d'optimisation, etc. Je fais déjà du page caching pour le chargement initial de ma liste, mais pour la recherche... Et sinon j'ai un peu regardé de la doc sur tsearch2 de postgres mais je sais pas trop comment le mettre en place...

    Merci de votre aide (et félicitations à ceux qui m'ont lu jusqu'au bout !).

  2. #2
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 652
    Points
    652
    Par défaut
    Salut,

    Dans un projet, j'ai une table qui contient les 36000 communes de France, et je fais des recherche dedans avec text_field_with_auto_complete, et la réponse est quasi instantanée...
    Les communes arrivent triées dans l'ordre, et on peut meme envisager de croiser les critères...
    Tout ça avec 0 plugin, juste du Ror simple et natif...

  3. #3
    Membre régulier Avatar de Miles Raymond
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2005
    Messages : 189
    Points : 83
    Points
    83
    Par défaut
    Citation Envoyé par Zfred Voir le message
    Salut,

    Dans un projet, j'ai une table qui contient les 36000 communes de France, et je fais des recherche dedans avec text_field_with_auto_complete, et la réponse est quasi instantanée...
    Les communes arrivent triées dans l'ordre, et on peut meme envisager de croiser les critères...
    Tout ça avec 0 plugin, juste du Ror simple et natif...
    Salut,

    Désolé pour le délai de réponse sur le thread, j'étais en vacances ces 2 dernières semaines.

    Merci pour ta réponse, c'est intéressant seulement je ne peux pas uniquement utiliser de l'auto_complete. J'ai besoin d'avoir la liste des clients sous les yeux de l'utilisateurs et que celui-ci puisse la trier comme bon lui semble ou même la parcourir. Et ensuite, j'ai besoin que le live search me cache toutes les lignes qui ne coïncident pas avec les critères de recherches fournis par l'utilisateur et ce de manière quasi-instantanée. Comme je l'ai expliqué plus haut.

    EDIT: Ou deuxième solution, plus compliqué j'imagine, que l'utilisateur puisse travailler de la même manière que dans une listbox recherchable (hum). C'est à dire qu'en tapant la div contenant ma table va automatiquement scroller pour afficher le premier résultat le plus pertinent en fonction des critères (en le mettant en évidence avec du CSS même). Une idée sur cette possibilité là ?

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2003
    Messages : 127
    Points : 124
    Points
    124
    Par défaut
    Salut,

    Un datagrid ne pourrait pas être intéressant dans cette situation?
    http://www.2dconcept.com/jquery-grid-rails-plugin
    Mon blog sur Ruby on Rails : 2dconcept

  5. #5
    Membre régulier Avatar de Miles Raymond
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2005
    Messages : 189
    Points : 83
    Points
    83
    Par défaut
    Citation Envoyé par Mookie Voir le message
    Salut,

    Un datagrid ne pourrait pas être intéressant dans cette situation?
    http://www.2dconcept.com/jquery-grid-rails-plugin
    Très intéressant!
    Merci du lien. J'ai passé la dernière demi-heure à le mettre en place, je sais pas si c'est la taille de ma base qui pose problème, mais c'est pas vraiment le top. La pagination ne fonctionne pas (malgré les requêtes qui fonctionnent) et si je fais le fou en donnant un total :per_page de 5000 entrées, le programme n'affiche rien (mais là encore, la requête fonctionne). En fait si je dépasse 19 lignes par page le grid n'affiche rien.

    Je vais encore regarder, il n'y a pas beaucoup d'info sur le sujet sur le web. As-tu travaillé avec Mookie ?

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2003
    Messages : 127
    Points : 124
    Points
    124
    Par défaut
    Oui, je suis le développeur du plugin. ;-)

    Je peux te confirmer que cela fonctionne avec beaucoup d'entrées. J'ai une application qui en affiche 500 et les performances sont très bonnes.

    Le mieux est que tu télécharges l'application de test et bidouille un petit peu avec : http://github.com/ahe/jqgrid_demo_app/tree
    Mon blog sur Ruby on Rails : 2dconcept

  7. #7
    Membre régulier Avatar de Miles Raymond
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2005
    Messages : 189
    Points : 83
    Points
    83
    Par défaut
    Citation Envoyé par Mookie Voir le message
    Oui, je suis le développeur du plugin. ;-)
    Dans ce cas félicitation, c'est très réussi!
    Seulement dans mon cas je vais devoir traiter jusqu'à 50'000 entrées... sans pagination. J'ai testé, comme tu me l'a recommandé, l'appli de demo et j'ai rempli la table d'environ 20000 enregistrement. L'affichage par page fonctionne correctement jusqu'à 1000 enregistrements par page (même si c'est pas le nirvana niveau rapidité), dépassé ce stade, firefox et safari me demande si je désire arrêter le script...

    Retour au point de départ donc. Actuellement je tri ma table avec le plugin tablesorter de jquery et malgré les 4000 enregistrements c'est l'affaire d'une seconde. Là ou c'est un peu plus long, c'est le chargement (environ 2-3 secondes, mais là je peux faire du caching) et, toujours, la recherche qui me pose problème...

    Donc selon vous ça permettrait pas une recherche plus rapide de pouvoir rechercher (si c'est possible) dans ma variable @clients ? Sinon d'autres idées ? J'ai testé activescaffold, c'est très lent et je n'aime vraiment pas le concept (trop restrictif si on est pas prêt à mettre les mains dans le cambouis).

  8. #8
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 652
    Points
    652
    Par défaut
    Le noeud du problème est donc de pouvoir traiter un grand nombre d'entrées.
    Tellement grand que la plupart des solutions sont à genoux.
    Il est sans aucun doute maladroit, dans ce cas, d'extraire la totalité des entrées, pour les envoyer dans les tuyaux.
    La piste qui semble alors s'ouvrir est de laisser faire la base, qui est prévue pour supporter et faire des recherches sur des tera et des tera de données...
    Ca te donne déja une idée du montage.

    Dans un 2eme temps, pour ne pas inonder l'utilisateur avec une page de 3 kilomètres, il y a des solutions Ajax, pour envoyer juste le nécessaire, si l'utilisateur touche à l'ascenseur, ça charge au fur et à mesure...
    Voir le Reader de Google qui est fait comme ça par exemple...

  9. #9
    Membre régulier Avatar de Miles Raymond
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2005
    Messages : 189
    Points : 83
    Points
    83
    Par défaut
    Citation Envoyé par Zfred Voir le message
    Le noeud du problème est donc de pouvoir traiter un grand nombre d'entrées.
    Tellement grand que la plupart des solutions sont à genoux.
    Il est sans aucun doute maladroit, dans ce cas, d'extraire la totalité des entrées, pour les envoyer dans les tuyaux.
    La piste qui semble alors s'ouvrir est de laisser faire la base, qui est prévue pour supporter et faire des recherches sur des tera et des tera de données...
    Ca te donne déja une idée du montage.

    Dans un 2eme temps, pour ne pas inonder l'utilisateur avec une page de 3 kilomètres, il y a des solutions Ajax, pour envoyer juste le nécessaire, si l'utilisateur touche à l'ascenseur, ça charge au fur et à mesure...
    Voir le Reader de Google qui est fait comme ça par exemple...
    C'est à peu prêt là que j'en suis arrivé dans mes réflexions effectivement. Ca risque de pas être simple cette affaire, d'autant que j'ai en plus besoin d'une forme de tri assez spécifique (Exemple : on clique sur un position, on tri et l'ascenceur reste sur la position sélectionnée afin de pouvoir "croiser" les résultats).

    Mais en tout cas merci pour cette réponse et pour l'idée de l'ascenceur. Je vais jeter un oeil au Reader de google et je vais aller voir les railcasts de M. Bates (j'ai souvenir qu'il en avait fait un sur le sujet).

  10. #10
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 652
    Points
    652
    Par défaut
    Tu peux faire une zone de saisie, d'un coté, et une liste de résultats de l'autre.
    A chaque modif de la zone de saisie, avec un observe_field, ça envoit une requete Ajax, tu limites le nombre de réponses à 20 résultats, et tu refresh le partial.
    Dans le cas où il y a d'autres résultats, tu mets un petit message...("il existe d'autres réponses...")
    Il n'y a pas d'interet à afficher 40000 réponses.

    Sinon c'est le 114 : http://railscasts.com/episodes/114-endless-page

  11. #11
    Membre régulier Avatar de Miles Raymond
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    189
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2005
    Messages : 189
    Points : 83
    Points
    83
    Par défaut
    Citation Envoyé par Zfred Voir le message
    Tu peux faire une zone de saisie, d'un coté, et une liste de résultats de l'autre.
    A chaque modif de la zone de saisie, avec un observe_field, ça envoit une requete Ajax, tu limites le nombre de réponses à 20 résultats, et tu refresh le partial.
    Dans le cas où il y a d'autres résultats, tu mets un petit message...("il existe d'autres réponses...")
    Il n'y a pas d'interet à afficher 40000 réponses.
    Va dire ça à mon client
    Disons que je dois passer d'une appli personnalisée Access au temps de réponse nul à une appli web en perdant le moins de temps possible.
    J'ai réfléchis et comme tu me l'a recommandé, autant sollicité un max la base de données, le nombre de requête restera moindre (l'appli sera utilisé au max par 5 utilisateurs en simultanée).

    Mais si ce n'est effectivement pas une très bonne idée d'essayer d'afficher 40000 réponse, je peux, comme pour l'endless-page, charger ce qui intéresse mon client. En fait il faut que je "simule" une application traitant réellement mes 40000 résultats, afin qu'ils puissent effectuer les tris et recherches croisées. J'ai déjà réaliser mon endless-page (endless-div en fait) et c'est plutôt très efficace. Ensuite, pour mon affaire de tri (tri général ou tri avec sélection et pointage de celle-ci) je peux faire des requêtes sur ma base en fonction. Et, toujours, avec des requêtes limités à 50 résultats.

    Je vais essayer de mettre ça en place et j'essaierai de vous tenir au courant de mes travaux.

    Merci, je m'en suis déjà inspiré

Discussions similaires

  1. Suppression de doublons sur une grosse table
    Par CaptainT dans le forum SQL
    Réponses: 20
    Dernier message: 24/05/2008, 09h25
  2. Création d'un index sur une grosse table
    Par Jester dans le forum SQL Procédural
    Réponses: 5
    Dernier message: 02/04/2008, 12h44
  3. Requête lente sur une grosse table
    Par mr_keyser dans le forum PostgreSQL
    Réponses: 7
    Dernier message: 12/12/2007, 19h15
  4. Quellue interface pour travailler sur une grosse table ?
    Par grinder59 dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 22/12/2006, 16h25
  5. Update trés lent sur une grosse table
    Par neo.51 dans le forum Oracle
    Réponses: 21
    Dernier message: 14/12/2005, 11h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo