2008-10-27 6 views
7

Imaginez que vous ayez une entité dans le magasin de données Google App Engine, stockant des liens pour les utilisateurs anonymes. Vous souhaitez effectuer la requête SQL suivante, qui ne sont pas pris en charge:Python: DISTINCT sur le jeu de résultats GQuery (GQL, GAE)

SELECT DISTINCT user_hash FROM links 

vous pourriez plutôt utiliser:

user = db.GqlQuery("SELECT user_hash FROM links") 

Comment utiliser Python le plus efficacement possible pour filtrer le résultat, il renvoie un jeu de résultats DISTINCT? Comment compter le jeu de résultats DISTINCT?

Répondre

3

Un ensemble est une bonne façon de traiter que:

>>> a = ['google.com', 'livejournal.com', 'livejournal.com', 'google.com', 'stackoverflow.com'] 
>>> b = set(a) 
>>> b 
set(['livejournal.com', 'google.com', 'stackoverflow.com']) 
>>> 

Une suggestion w/r/t la première réponse, est que les ensembles et dicts sont mieux à la récupération des résultats uniques rapidement, l'appartenance à des listes est O (n) par rapport à O (1) pour les autres types, donc si vous voulez stocker des données supplémentaires ou faire quelque chose comme créer la liste unique_results mentionné précédemment, il peut être préférable de faire quelque chose comme:

unique_results = {} 
>>> for item in a: 
    unique_results[item] = '' 


>>> unique_results 
{'livejournal.com': '', 'google.com': '', 'stackoverflow.com': ''} 
+0

Un objet défini est une collection non ordonnée d'objets lavables distincts. (...) Nouveauté 2.4. http://www.python.org/doc/2.5.2/lib/types-set.html –

+1

L'ensemble est correct si le nombre d'enregistrements est relativement faible. Mais si vous avez des gazillions d'enregistrements dans le datastore, ce serait très inefficace! Une meilleure stratégie consisterait à pré-calculer et stocker le résultat au moment de l'insertion/mise à jour. – sudarkoff

1

Une option serait de mettre les résultats dans un objet ensemble:

http://www.python.org/doc/2.6/library/sets.html#sets.Set

L'ensemble résultant sera composé uniquement des valeurs distinctes transmises en elle. A défaut, la création d'une nouvelle liste contenant uniquement les objets uniques fonctionnerait. Quelque chose comme:

unique_results = [] 
for obj in user: 
    if obj not in unique_results: 
     unique_results.append(obj) 

Cette for boucle peut se résumer en une compréhension de la liste.

0

Désolé pour creuser cette question, mais dans GAE je ne peux pas comparer des objets comme ça, je dois nous e .key() à titre de comparaison comme ça:

Prenez garde, ce qui est très inefficace:

def unique_result(array): 
    urk={} #unique results with key 
    for c in array: 
     if c.key() not in urwk: 
      urk[str(c.key())]=c 
    return urk.values() 

Si quelqu'un a une meilleure solution, s'il vous plaît partager.

+0

Il y a une autre question demandant comment faire cela dans Datastore, et la réponse de base est que vous ne pouvez pas: http://stackoverflow.com/questions/1183102/how-to-get-the-distinct-value-of-one -de-mes-modèles-dans-google-app-engine. J'ai essayé de suggérer des idées vagues pour dénormaliser, mais il est possible que l'état de l'art ait évolué depuis. –

5

Raviver cette question pour la réalisation:

Le mot-clé DISTINCT a été introduit dans release 1.7.4.

Vous pouvez trouver la référence GQL mise à jour (par exemple pour Python) here.

Questions connexes