1

J'utilise Google App Engine pour mon back-end de service REST et Google dataStore que la DB et objectiver pour accéder datastore. L'une des propriétés de mon entité estGoogle DataStore avec objectiver - requêtes composites sur HashMap

Map<String,String> customAttrs; 

Ceci est parce que je ne sais pas ce que la main avant de tous les paramètres peuvent provenir du client. Mon exigence est que je veux pouvoir indexer sur ces paramètres dans le HashMap. Je regardais la question suivante:

GAE w/ Objectify - Can you query a HashMap?

et essayé ce qui a été mentionné dans la réponse acceptée et il fonctionne pour moi, je suis en mesure d'indexer en fonction des attributs customAttrs en utilisant

filter("customAttrs .key1", "value1") 

en fonction de tous les sous-types passés par le client dans l'appel de l'API REST.

Cependant, le problème vient en cas de requêtes composites. Je ne sais pas grand-chose à ce sujet, mais de ce que je comprends, si vous combinez un tri ou un filtre d'inégalité avec un autre filtre, vous devez définir la combinaison dans un fichier appelé datastore-indexes.xml. Donc l'un des champs de l'entité est creationTime, et quand je fais une requête qui me renvoie une liste d'utilisateurs, je veux la trier par creationTime.

Alors disons une des clés de la carte customAttrs est-ville. Maintenant, si je veux juste filtrer tous les utilisateurs où dire city = London, cela fonctionne très bien pour moi. Cependant, si je tente d'obtenir tous les utilisateurs, où la ville = Londres trié par creationTime, elle renvoie une exception et ne fonctionne pas. Il ne fonctionne que si j'ajoute ce qui suit dans le fichier datastore-indexes.xml:

<datastore-index kind="User" ancestor="false" source="manual"> 
     <property name="customAttrs.city" direction="asc" /> 
     <property name="creationTime" direction="asc" /> 
    </datastore-index> 

Maintenant, ce déferait le but d'utiliser HashMap depuis ici, je dois connaître les champs à l'intérieur customAttrs avant la main.

Ainsi est-il possible d'effectuer des requêtes composites sans avoir à connaître les champs avant la main?

EDIT:

Comme mentionné dans la réponse par Sai, qu'il n'y a aucun moyen d'effectuer ce type de requêtes, sans l'ajouter avant la main et l'ajouter dans datastrore-indexes.xml.

Je pensais que d'une autre approche, mais je fais face à une question différente là-bas.

Dans cette approche, au lieu de définir la propriété comme

Map<String,String> customAttrs; 

Je l'ai défini comme une liste de chaînes

List<String> customAttrs; 

Voici les chaînes qui sont stockées sont de la forme clé »: valeur".Par exemple, la liste d'une entité peut être « ville: abc », « pays: xyz », « name: 123 »

Dans ce cas, j'ai juste besoin de définir ce qui suit dans mes indices datastore- .xml:

<datastore-index kind="User" ancestor="false" source="manual"> 
     <property name="customAttrs" direction="asc" /> 
     <property name="creationTime" direction="asc" /> 
    </datastore-index> 

ce qui est bien pour moi, puisque je suis nulle part coder en dur/prédéfinir ce que les attributs, pourraient être. Je suis en mesure de filtrer par ville = abc en utilisant

filter("customAttrs","city:abc") 

Avec cette approche, je peux filtrer par l'un des paramètres, ainsi que trier les résultats par creationTime.

Mais le problème avec cette approche est que je ne peux faire qu'un seul type de filtre personnalisé. Signification si je veux filtrer où ville est abc et pays est xyz (cela fonctionne si j'utilise l'approche Carte), je ne suis pas capable de le faire. Y a-t-il un moyen de le faire. Donc, ma requête est que si une entité a une propriété List, existe-t-il un moyen de filtrer toutes les entités qui ont les chaînes "str1" ET "str2" dans la liste?

Répondre

0

Cela n'a rien à voir avec Objectfy, mais le magasin de données lui-même. Chaque fois que votre requête effectue une recherche sur plusieurs propriétés ou a un tri comme vous l'avez mentionné (recherche et tri sur deux propriétés différentes), le magasin de données attend un index composite correspondant. Le magasin de données est conçu pour que toutes les requêtes obtiennent leurs résultats à partir d'un index unique pour les performances. Cela dit, si vous autorisez des propriétés dynamiques dont les noms ne sont pas connus à l'avance, il n'y a vraiment aucun moyen d'effectuer les requêtes comme vous le souhaitez. Si c'est une option, votre application doit limiter l'interrogation/le tri de ces propriétés dynamiques afin qu'elles ne nécessitent pas d'index composite. Dans le cas contraire, vous devrez explorer d'autres options telles que la recherche en texte intégral (recherche en texte intégral de AppEngine ou recherche élastique) et voir si elles pourraient aider avec votre cas d'utilisation.

+0

Merci. J'ai essayé une autre approche pour réaliser mon cas d'utilisation, mais je suis confronté à un problème différent. J'ai mis à jour les détails dans ma question. Est-ce possible de le faire fonctionner avec la nouvelle approche? –

0

Pour votre dernière question sur le filtrage sur les propriétés Array -

Il est possible de faire une requête AND sur un type Array pour voir si elle contient deux ou plusieurs éléments. Le GQL aimerait -

SELECT * FROM MyEntity WHERE ArrayProperty='value1' AND ArrayProperty='value2' 
+0

Mais je ne travaille avec ce objecitfy (qui est ce que je me sers dans mon code) J'ai essayé avec 'query = query.filter ("customAttrs", "pays: abc")' 'suivi par requête = query.filter ("customAttrs", "city: xyz") ' Ici j'avais deux entrées dans ma BD avec le pays: abc mais seulement un d'entre eux avait la ville: xyz. Cependant, j'ai les deux avec le pays: abc –