2009-07-25 5 views
5

J'ai un modèle, ci-dessous, et je voudrais obtenir toutes les valeurs distinctes area. L'équivalent SQL est select distinct area from tutorialsComment obtenir la valeur distincte d'un de mes modèles dans Google App Engine

class Tutorials(db.Model): 
    path = db.StringProperty() 
    area = db.StringProperty() 
    sub_area = db.StringProperty() 
    title = db.StringProperty() 
    content = db.BlobProperty() 
    rating = db.RatingProperty() 
    publishedDate = db.DateTimeProperty() 
    published = db.BooleanProperty() 

Je sais que Python que je peux faire

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

Mais cela me obligerait à déplacer les éléments de la zone hors de la requête dans une autre liste, puis en cours d'exécution mis sur la liste (semble très inefficace) et si j'ai un élément distinct qui est en position 1001 dans le datastore je ne le verrais pas à cause de la limite de fetch de 1000.

Je voudrais obtenir toutes les valeurs distinctes de la zone dans mon magasin de données pour le vider à l'écran comme l encres.

Répondre

7

Datastore ne peut pas le faire pour vous dans une seule requête. Une requête de banque de données renvoie toujours un bloc de résultats consécutifs d'un index, et un index est toujours constitué de toutes les entités d'un type donné, triées en fonction des commandes spécifiées. Il n'y a aucun moyen pour la requête d'ignorer des éléments simplement parce qu'un champ a des valeurs en double.

Une option consiste à restructurer vos données. Par exemple, introduisez un nouveau type d'entité représentant une "zone". En ajoutant un tutoriel, vous créez la "zone" correspondante si elle n'existe pas déjà, et en supprimant un tutoriel, supprimez la "zone" correspondante si aucun tutoriel ne reste avec la même "zone". Si chaque zone stockait un nombre de tutoriels dans cette zone, cela ne serait peut-être pas trop lourd (bien que garder les choses cohérentes avec les transactions, etc. serait en fait assez fastidieux). Je suppose que la clé de l'entité pourrait être basée sur la chaîne de zone elle-même, ce qui signifie que vous pouvez toujours effectuer des recherches de clés plutôt que des requêtes pour obtenir des entités de zone. Une autre option consiste à utiliser une tâche en attente ou un travail cron pour créer périodiquement une liste de toutes les zones, en l'accumulant le cas échéant sur plusieurs requêtes et en affichant les résultats dans le magasin de données ou dans memcache. Cela signifierait bien sûr que la liste des zones pourrait être temporairement obsolète à certains moments (ou s'il y a des changements constants, elle pourrait ne jamais être entièrement datée), ce qui peut ou non être acceptable pour vous. Enfin, s'il y a probablement très peu de domaines comparés aux tutoriels, vous pouvez le faire à la volée en demandant le premier Tutoriel (trié par zone), puis en demandant le premier Tutoriel dont la zone est supérieure à la zone de le premier, et ainsi de suite. Mais cela nécessite une demande par zone distincte, il est donc peu probable qu'elle soit rapide.

+0

Très bien. Je supprimerais le "pour autant que je sache", personnellement. :) –

+0

Merci pour votre réponse. Je pense que je peux faire l'idée de restructurer. Moi aussi j'espérais qu'il y avait un moyen obscur qui pourrait le faire – AutomatedTester

0

This has been asked before, et la conclusion était que l'utilisation d'ensembles est très bien.

+0

La question était de savoir comment utiliser Python pour filtrer le résultat. La question ici veut tenir compte du cas où il y a 1001 tutoriels ou plus, et par conséquent une seule requête ne peut pas les retourner. –

1

Le mot clé DISTINCT a été introduit dans la version 1.7.4.

Questions connexes