Question

Je suis en train d'interroger le datastore google pour quelque chose comme (avec h -> persistanceManager):

String filters = "(  field == 'value' ||  field == 'anotherValue' )";
Query query = pm.newQuery(myType.class, filters);

Quand j'execute - Je reviens:. App Engine datastore ne supporte pas l'opérateur OR

Quelle est la meilleure approche pour les gens d'expérience pour ce genre de questions?

Toute aide appréciée!

Était-ce utile?

La solution

Exécuter plusieurs requêtes. Le magasin de données, comme toutes les autres bases de données, ne sont pas en mesure d'exécuter efficacement disjonctions. Contrairement à d'autres bases de données, il expose cette difficulté à l'utilisateur, de préciser que ce que vous faites est pas efficace. Votre seule solution est d'exécuter plusieurs requêtes - un pour chaque ou -. Et les combiner

Autres conseils

Je ne sais pas si les implémentations JDO et JPA GAE soutiennent, mais en utilisant l'API de bas niveau, vous pouvez utiliser l'opérateur IN pour cela, dans une requête.

Query query = new Query("Issue");
List<String> list = Arrays.asList("NEW", "OPEN", "ACCEPTED");
query.addFilter("status", FilterOperator.IN, list);

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
PreparedQuery preparedQuery = datastore.prepare(query);
for (Entity entity : preparedQuery.asIterable()) {
    // should iterate over 'NEW', 'OPEN' and 'ACCEPTED' issues
}

Selon Google App Engine - Requêtes et index :

  

Filtres de requête

     

Filtre spécifie un nom de domaine,   un opérateur et une valeur. La valeur   doit être fournie par l'application; ça ne peut pas   se référer à une autre propriété, ou être   calculé en termes d'autres   Propriétés. L'opérateur peut être l'un des   ce qui suit: < <= == >= >

     
    

Remarque: L'interface Java datastore ne supporte pas = et     filtre     les opérateurs qui sont mis en œuvre dans le     interface Python datastore. (Dans le     interface Python, ces opérateurs sont     mis en œuvre dans le côté client     bibliothèques comme plusieurs datastore     requêtes; ils ne sont pas caractéristiques du     magasin de données lui-même.)

  
     

Le sujet d'un filtre peut être tout   champ de l'objet, y compris le primaire   clé et le parent de groupe d'entités (voir    Transactions ).

     

Une entité doit correspondre à tous les filtres être   un résultat. Dans la syntaxe de chaîne JDOQL,   plusieurs filtres sont spécifiés   séparés par && (logique « et »).   D'autres combinaisons logiques de filtres   (Logique « ou », « non ») ne sont pas   prise en charge.

     

En raison de la façon dont App Engine   datastore exécute des requêtes, un seul   requête ne peut pas utiliser des filtres d'inégalité   (< <= >= >) sur plus d'un   propriété. Plusieurs filtres d'inégalité   sur la même propriété (tels que l'interrogation   pour une plage de valeurs) sont autorisées.   Voir Restrictions sur les requêtes .

Fondamentalement, vous êtes soit allez devoir restructurer vos données afin que vous puissiez trouver ce que vous cherchez avec une condition ou multiple « et » les conditions ou vous allez devoir récupérer les données via deux (ou plus) requêtes et filtre / combiner dans votre code.

Désolé, je suis en retard dans le jeu .. Je viens couru à travers votre question aujourd'hui.

Une autre façon de « simuler » comportement « IN » et « OR » est d'utiliser le « bas niveau » API Datastore. Le DatastoreService prend en charge une méthode get () qui accepte une collection de clés et retourne une carte de toutes les entités qui correspondent à la passé Keys. Il est une interface, mais il y a un DatastoreServiceFactory à portée de main disponible qui dispenseront une instance prête à utiliser.

Malheureusement, Google a décidé qu'ils ne veulent pas promouvoir cette approche de l'API de bas niveau et préfèrent que les développeurs utilisent JDO ou JPA, donc il n'y a aucune documentation disponible autre que les JavaDocs et quel que soit des exemples de code que vous pourriez trouver lorsque vous Google "DatastoreService".

TL

Late Breaking Nouvelles .. au moins je suis juste obtenir. Comme je télécharge le dernier SDK Java pour GAE j'ai remarqué sur la publication note que « Numéro 29: Expose lot se » a été corrigé dans la dernière version (v1.2.1). Fondamentalement, il semble que nous (je suis à la recherche du même soutien il semble) peut avoir une solution de rechange JDO plutôt que d'avoir à descendre au « bas niveau » API Datastore. Je viens de télécharger le dernier SDK Java GAE donc je ne l'ai pas eu l'occasion de tester quoi que ce soit, mais je voulais vous donner un heads-up le plus tôt possible. Je vais poster quelque chose de plus j'apprendre après j'ai eu la chance de le confirmer « fixer ».

S'il vous plaît accepter mes excuses si je me suis cassé l'étiquette StackOverflow par de publier à nouveau mes commentaires comme une réponse, mais j'ai décidé de le faire pour deux raisons. Tout d'abord parce que, même si elle est me aborder la même question encore une fois, à mon humble avis que cette nouvelle information semble fournir un tout autre « réponse » au problème. Et d'autre part, je craignais que le formulaire de commentaire pourrait ne pas attirer votre attention avant que vous aviez passé beaucoup de temps à regarder dans la première réponse que je fournis.

La prochaine fois que je vais y réfléchir plus attentivement avant d'agir.

TL

Une façon de simplifier avoir à « faire vous-même » peut-être d'utiliser des requêtes paramétrées:

   Query query = pm.newQuery(mytype.class);
   query.setFilter("field == autoParam");
   query.declareParameters("String autoParam");

   List<String> params = myListOfThingsFieldCanBeEqualTo;

   Set merged = new HashSet();
   for (String f : params) {
     merged.addAll(q.execute(f));
   }

Contrairement à la réponse de Cletus, un OU œuvres , dans la version plus récente de App Engine de toute façon.

En effet, je trouve un OU ne fonctionne pas dans App Engine 1.3.0 que j'avais, mais selon Google App Engine - Requêtes et index (même Cletus source mentionnées dans sa réponse),

  

Une entité doit correspondre à tous les filtres être un résultat. Dans la syntaxe de chaîne JDOQL, vous pouvez séparer plusieurs filtres avec || ( « Ou » logique) et && ( « et » logique), bien garder à l'esprit que || ne peut être utilisé lorsque les filtres qu'il sépare tous ont le même nom de domaine. En d'autres termes, || est légal que dans les situations où les filtres qu'il sépare peuvent être combinés en un seul contient des filtres ().

Je me suis dit depuis sa réponse (et depuis que je mis à jour mon App Engine), App Engine doit avoir été mis à jour à ce sujet.

Mise à jour App Engine à 1.3.4, et les œuvres OU-ing! Bien que la limitation.

Merci à Cletus quand même:)

Vous pouvez utiliser la méthode contient

String filters = "( :values.contains(field) )";
Query query = pm.newQuery(myType.class, filters);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top