2009-07-10 8 views
0

Je récupère périodiquement les derniers tweets avec un hashtag donné et les enregistre localement. Afin d'éviter d'enregistrer des doublons, j'utilise la méthode ci-dessous. Malheureusement, il ne semble pas fonctionner ... alors quel est le problème avec ce code:Suppression des doublons d'un tableau avant l'enregistrement

def remove_duplicates 
     before = @tweets.size 
     @tweets.delete_if {|tweet| !((Tweet.all :conditions => { :twitter_id => tweet.twitter_id}).empty?) } 
     duplicates = before - @tweets.size 
     puts "#{duplicates} duplicates found" 
    end 

Où @tweets est un tableau de Tweet objets tiré par les cheveux de twitter. J'apprécierais toute solution qui fonctionne et surtout celle qui pourrait être plus élégante ...

Répondre

2

vous pouvez validate_uniqueness_of :twitter_id dans le modèle de Tweet (où ce code devrait être). Cela entraînera l'échec de l'enregistrement des doublons.

+0

validate_uniqueness_of: twitter_id ce n'est pas une bonne solution. Entre le moment où il vérifie l'existence de l'enregistrement et qu'il crée un nouvel enregistrement, un autre processus peut créer un doublon. Vous devriez toujours utiliser cette méthode en conjonction avec un index de base de données. –

+0

@weppos: Comme je n'ai qu'un seul travail d'écriture séquentielle des tweets, ce n'est pas un problème. Cela semble être la solution la plus "sèche". J'ai bien travaillé sur sqlite3, mais en mode production/mysql il ne semble pas y avoir de doublons ... en train d'y jeter un coup d'oeil maintenant. – effkay

+0

pour la sécurité réelle, vous devez mettre des contraintes d'unicité sur la base de données et être juste prêt à gérer les exceptions qui sont levées –

0

array.uniq!

Supprime les éléments en double de self. Renvoie zéro si aucune modification n'est effectuée (c'est-à-dire qu'aucun doublon n'est trouvé).

+0

n'aidera pas pour les doublons dans la base de données. –

1

Comme il semble que vous utilisiez l'API de recherche Twitter, une meilleure solution consiste à utiliser le paramètre since_id. Gardez une trace du dernier identifiant d'état Twitter que vous avez reçu de votre requête précédente et utilisez-le comme paramètre since_id lors de votre prochaine requête.

Plus d'informations sont disponibles à Twitter Search API Method: search

0

Ok, se le problème était un peu de nature différente: Lorsque l'on regarde de plus près en elle, j'ai découvert que Tweets multipe ont été enregistrés avec le twitter_id 2147483647 ... C'est la limite supérieure pour les champs entiers :)

Changer le champ en bigint a résolu le problème. Il m'a fallu beaucoup de temps pour comprendre car MySQL a échoué silencieusement et est revenu à la valeur maximale aussi longtemps qu'il le pouvait. (jusqu'à ce que j'ajoute l'index unique). J'ai rapidement essayé avec postgres, qui a renvoyé une belle erreur "Integer out of range", qui m'a ensuite montré la véritable cause du problème ici.

Merci Ben pour les conseils de validation et d'indexation, car ils conduisent à un code beaucoup plus propre maintenant!

Questions connexes