2016-07-12 6 views
1

Ich habe eine Django-App, in die Benutzer Fotos hochladen, damit die allgemeine Öffentlichkeit sie sehen und kommentieren kann. Eine Voraussetzung ist, dass das hochgeladene Foto nicht etwas ist, das die Website in letzter Zeit bereits gesehen hat. Um dies zu erreichen, berechne ich die average (perceptual) hash von jedem Bild für das Hochladen und speichert es in der DB. Später, wenn ein neues Bild erstellt wird, wird der durchschnittliche Hashwert mit dem von 1000 letzten Bildern verglichen.Hinzufügen von Elementen zu einem sortierten Redis-Set in Python

Jetzt möchte ich diesen Prozess schneller machen, indem Sie die neuesten avg Hashes in einem sortierten Redis Set statt meiner Postgresql DB speichern.

Ich versuche herauszufinden, wie dies zu tun ist. Der erste Schritt besteht darin, eine Reihe von avg-Hashes zu erstellen, um zu vergleichen, dass die Satzgröße bei 1000 bleibt und die letzten 1000 kay-value-Paare enthält.

Wie würde der Code aussehen?

import redis 

POOL = redis.ConnectionPool(host='127.0.0.1', port=6379, db=0) 

def insertValue(photo_hash): 
    my_server = redis.Redis(connection_pool=POOL) 
    try: 
     size = my_server.zcard("my_set") 
     if size < 1001: 
      my_server.zadd("my_set", int(time.time() * 1000), photo_hash) #time.time() equals seconds since epoch 
     else: 
      #zrem the element with the lowest score, and then ... 
      my_server.zadd("my_set", int(time.time() * 1000), photo_hash)  
    except: 
     my_server.zadd("my_set", int(time.time() * 1000), photo_hash) 

Zum einen, ist die Syntax für zadd richtig (ich nicht online Python Beispiele finden annähert, was ich versuche zu tun), und zweitens , wie kann man zrem das Element mit dem niedrigsten Punktzahl aus einem sortierten Set?

Bitte beraten.

Antwort

1

Ja, zadd ist ein bisschen schwierig.

Hinweis: Die Reihenfolge der Argumente unterscheidet sich von dem des offiziellen ZADD Befehl. Für die Rückwärtskompatibilität akzeptiert diese Methode Argumente in die Form von Name1, Score1, Name2, Score2, während die offizielle Redis Dokumente Score1, Name1, Score2, Name2 erwartet. Wenn Sie die Standardsyntax verwenden möchten, sollten Sie die StrictRedis-Klasse in Betracht ziehen. Weitere Informationen finden Sie im Abschnitt "API-Referenz" der Dokumentation. Weitere Informationen finden Sie unter .

Da Sie nicht verwenden StrictRedis was oben Doess Code ist ein Element time,time()*1000 in den Satz genannt my_set mit einem Wert von photo_hash, die in Ordnung zu sein scheint, genannt hinzuzufügen. Weil Sie sowohl eine zrank als auch eine zscore Funktion haben, mit der Sie die Existenz entweder durch einen Namen oder durch einen Wert überprüfen können. Diese Vorgänge sind sehr schnell. Viel schneller als Memcached, wo Sie vorher das gesamte Set abholen müssten.

Auf ähnliche Elemente zu entfernen, können Sie entweder zremrangebyrank oder zremrangebyscore so im Wesentlichen, was Sie wählen den Wert zu sein, und was Sie wählen den Namen zu geben und was Sie wählen, um den Wert zu sein, sind nicht wirklich wichtig, vorausgesetzt, dass beide sind einzigartig. Und in Ihrem Fall können beide einzigartig sein.

Die einzige Verbesserung, die ich sehen kann, ist, den Primärschlüssel des Bildes anstelle der Zeit zu verwenden. Da es möglich ist, dass zwei Personen gleichzeitig ein Bild hochladen können.

+0

Hey wieder! Tatsächlich wurde mir klar, dass ich versuchte, die Python-Implementierung zu erraten, während ich mir die eigenen Dokumente von redis ansah - ich hätte mir dafür Redispy-Dokumente ansehen sollen. Ich habe gelesen über 'zrank',' zscore', 'zremrangebyrank' und' zremrangebyscore'.Also, um Extra-Set-Mitglieder loszuwerden, wenn ein Set meine voreingestellte 1000-Größe überschreitet, erhalte ich die Kardinalität (Größe) des Sets und verwende dann zremrangebyrank (my_set, 1000, size) '? –

+0

ja, das ist es ziemlich viel. Da Redisets jedoch blitzschnell sind, müssen Sie sich nicht zu sehr um das Löschen kümmern, sondern das, was Sie im Kommentar gesagt haben, funktioniert – e4c5

+0

Nun, ich möchte nach einer Weile löschen, weil ich nicht möchte, dass Benutzer Laden Sie kürzlich hochgeladene Fotos hoch, es ist in Ordnung, wenn sie es nach einem oder zwei Tagen tun. Recycling von Inhalten ist eine Tatsache des Lebens auf Websites wie 9gag (oder meins). Danke für den Tipp, ich hoffe nur, dass ich eine Menge anderer Sachen auf Redis auch verschieben kann. FAST ist gut, und Sie haben meine Website gesehen, es ist eher eine User-Timeline, für die ich denke, dass redis als Backend besser geeignet ist als postgresql. Aber natürlich muss man viel tiefer graben. –

Verwandte Themen