2009-04-15 8 views

Répondre

13

Depuis la version 1.3.6, il n'y a plus un plafond de 1000 sur les requêtes de comptage. Ainsi, vous pouvez faire ce qui suit pour obtenir un compte au-delà de 1000:

count = modelname.all(keys_only=True).count() 

Cela comptera tous de vos entités, ce qui pourrait être assez lent si vous avez un grand nombre d'entités. Par conséquent, vous devriez envisager d'appeler count() avec une limite spécifiée:

count = modelname.all(keys_only=True).count(some_upper_bound_suitable_for_you) 
+0

Bien sûr, vous avez seulement 300ms de le faire :( –

+1

300ms? Où avez-vous ce chiffre? Peu importe, cependant, cela démontre pourquoi les objets de comptage à la volée est pas une bonne idée. Je pense –

+0

il signifiait 30 000 ms, mais ce n'est vraiment pas le cas car si vous faites cela en raison de l'uploader en vrac, vous exécutez probablement le compte sur remote_api de toute façon - ce qui AFAIK n'est pas soumis au timeout de 30 secondes – dar

4

En GAE un compte, vous pourrez toujours faire défiler les résultats lorsque vous avez plus de 1000 objets. Le moyen le plus simple de résoudre ce problème consiste à ajouter une propriété de compteur à votre modèle ou à une autre table de compteurs et à la mettre à jour chaque fois que vous créez un nouvel objet.

3

je encore frappé la 1000 limite avec le nombre si adapté le code de dar (le mien est un peu rapide et sale):

class GetCount(webapp.RequestHandler): 
    def get(self): 
     query = modelname.all(keys_only=True) 

     i = 0 
     while True: 
      result = query.fetch(1000) 
      i = i + len(result) 
      if len(result) < 1000: 
       break 
      cursor = query.cursor() 
      query.with_cursor(cursor) 

     self.response.out.write('<p>Count: '+str(i)+'</p>') 
7
count = modelname.all(keys_only=True).count(some_upper_limit) 

Juste pour ajouter à la poste plus tôt par dar, ce « some_upper_limit » doit être spécifié. Dans le cas contraire, le nombre par défaut sera toujours un maximum de 1000.

+1

Bonne réponse. J'ai regardé un temps de journal pour cela et il semble également raisonnable de mettre en cache le résultat avec memcache si les mises à jour ne sont pas très fréquentes. –

17

Vous devez utiliser Datastore Statistics:

Query query = new Query("__Stat_Kind__"); 
query.addFilter("kind_name", FilterOperator.EQUAL, kind);  
Entity entityStat = datastore.prepare(query).asSingleEntity(); 
Long totalEntities = (Long) entityStat.getProperty("count"); 

S'il vous plaît noter que ces exigences ne fonctionne pas sur le développement Datastore mais il fonctionne dans la production (lors de la publication). Je vois que c'est un vieux message, mais j'ajoute une réponse au bénéfice des autres qui cherchent la même chose.

+0

Je reçois cette erreur sur la première ligne de votre code: "Impossible d'instancier le type de requête" Des idées? – steven

6

C'est un fil très vieux, mais juste au cas où il aide les autres personnes regardant, il y a 3 façons d'y parvenir:

  1. Accès aux statistiques de magasin de données
  2. Garder un compteur dans le magasin de données
  3. compteurs sharding

Chacune de ces méthodes. is explained in this link

+0

Les statistiques sont collectées quotidiennement (ou même toutes les 48 heures), comme indiqué ici: https://github.com/GoogleCloudPlatform/google-cloud-node/issues/413 Ainsi, il peut arriver que le nombre de statistiques ne corresponde pas au nombre réel. Même, il est dit que les statistiques ne pourraient pas être disponibles pour les grands ensembles de données ... – frb

2
DatastoreService ds = DatastoreServiceFactory.getDatastoreService(); 
Query query = new Query("__Stat_Kind__"); 
Query.Filter eqf = new Query.FilterPredicate("kind_name", 
           Query.FilterOperator.EQUAL, 
           "SomeEntity"); 
query.setFilter(eqf); 
Entity entityStat = ds.prepare(query).asSingleEntity(); 
Long totalEntities = (Long) entityStat.getProperty("count"); 
+0

Juste pour clarifier, remplacez "SomeEntity" avec le nom du genre que vous voulez obtenir le compte, tout le reste reste le même. En outre, cela ne fonctionnera que si vous êtes en cours d'exécution, entityStat reviendra à zéro lors de l'exécution locale. – Craigo

Questions connexes