Google App Engine: est-il possible de faire une requête de type Gql?
très Simple. En SQL, si je veux rechercher un champ de texte pour quelques caractères, je peux faire:
SELECT blah FROM blah WHERE blah LIKE '%text%'
la documentation pour App Engine ne fait aucune mention de la façon d'y parvenir, mais c'est sûrement un problème assez commun?
12 réponses
BigTable, qui est la base de données back end pour App Engine, sera échelle à des millions de dossiers. Pour cette raison, App Engine ne vous permettra pas de faire n'importe quelle requête qui résultera dans un scan de table, car la performance serait terrible pour une table bien peuplée.
En d'autres termes, chaque requête doit utiliser un index. C'est pourquoi vous ne pouvez faire que les requêtes =
, >
et <
. (En fait, vous pouvez également faire !=
mais L'API fait cela en utilisant un a combinaison des requêtes >
et <
. C'est aussi la raison pour laquelle l'environnement de développement surveille toutes les requêtes que vous faites et ajoute automatiquement les index manquants à votre fichier index.yaml
.
il n'y a aucun moyen d'indexer une requête LIKE
donc elle n'est tout simplement pas disponible.
Avoir une montre de Google IO session pour une bien meilleure explication de ce.
je fais face au même problème, mais j'ai trouvé quelque chose sur google app engine pages:
Astuce: les filtres de requête n'ont pas de façon explicite de faire correspondre juste une partie d'une valeur de chaîne, mais vous pouvez simuler une correspondance de préfixe en utilisant des filtres d'inégalité:
db.GqlQuery("SELECT * FROM MyModel WHERE prop >= :1 AND prop < :2",
"abc",
u"abc" + u"\ufffd")
cela correspond à chaque entité MyModel avec une propriété prop chaîne qui commence avec les caractères abc. La chaîne unicode u "\ufffd " représente le plus grand caractère Unicode possible. Lorsque l' les valeurs de propriétés sont triées dans un index, les valeurs qui tombent dans cette gamme sont toutes les valeurs qui commencent avec le préfixe donné.
http://code.google.com/appengine/docs/python/datastore/queriesandindexes.html
cela pourrait peut-être faire l'affaire ;)
Barbante App Engine ne prend pas en charge les requêtes de type, avoir un regard sur les "propriétés de la 151920920" ListProperty et StringListProperty . Quand un test d'égalité est fait sur ces propriétés, le test sera effectivement appliqué sur tous les membres de la liste, par exemple, list_property = value
tests si la valeur apparaît n'importe où dans la liste.
parfois, cette fonctionnalité peut être utilisée pour contourner le manque de requêtes similaires. Par exemple, il rend possibilité de faire recherche simple de texte, comme décrit sur ce post .
, Vous devez utiliser service de recherche pour effectuer une recherche plein texte des requêtes similaires à SQL LIKE
.
Gaelyk fournit un langage spécifique au domaine pour effectuer plus de user friendly requêtes de recherche . Par exemple, l'extrait suivant trouvera les dix premiers livres triés des derniers avec le titre contenant fern
et le genre correspondant exactement thriller
:
def documents = search.search {
select all from books
sort desc by published, SearchApiLimits.MINIMUM_DATE_VALUE
where title =~ 'fern'
and genre = 'thriller'
limit 10
}
comme est écrit comme opérateur de match de Groovy =~
.
Il supporte également des fonctions telles que distance(geopoint(lat, lon), location)
.
App engine a lancé un service universel full text search service dans la version 1.7.0 qui prend en charge le datastore.
Détails annonce .
plus d'informations sur la façon d'utiliser ce: https://cloud.google.com/appengine/training/fts_intro/lesson2
Avoir un coup d'oeil à Objectiver ici , c'est comme un Magasin de données d'accès de l'API. Il ya une FAQ avec cette question spécifiquement, voici la réponse
Comment dois-je faire une requête (COMME "foo%")
Vous pouvez faire quelque chose comme un startWith, ou endWith si vous inversez l'ordre lorsque stocké et recherché. Vous faites une requête de plage avec la valeur de départ que vous voulez, et une valeur juste au-dessus de celle que vous voulez.
String start = "foo";
... = ofy.query(MyEntity.class).filter("field >=", start).filter("field <", start + "\uFFFD");
suivez ici: init.py#354">http://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/ext/search / init .py # 354
ça marche!
class Article(search.SearchableModel):
text = db.TextProperty()
...
article = Article(text=...)
article.save()
To search the full text index, use the SearchableModel.all() method to get an
instance of SearchableModel.Query, which subclasses db.Query. Use its search()
method to provide a search query, in addition to any other filters or sort
orders, e.g.:
query = article.all().search('a search query').filter(...).order(...)
j'ai testé cela avec GAE Datastore low-level Java API. Moi et fonctionne parfaitement
Query q = new Query(Directorio.class.getSimpleName());
Filter filterNombreGreater = new FilterPredicate("nombre", FilterOperator.GREATER_THAN_OR_EQUAL, query);
Filter filterNombreLess = new FilterPredicate("nombre", FilterOperator.LESS_THAN, query+"\uFFFD");
Filter filterNombre = CompositeFilterOperator.and(filterNombreGreater, filterNombreLess);
q.setFilter(filter);
en général, même si c'est un ancien post, une façon de produire un 'LIKE' ou 'ILIKE' est de rassembler tous les résultats d'une requête'>=', puis les résultats de boucle en python (ou Java) pour les éléments contenant ce que vous recherchez.
disons que vous voulez filtrer les utilisateurs avec un q = 'luigi'
users = []
qry = self.user_model.query(ndb.OR(self.user_model.name >= q.lower(),self.user_model.email >= q.lower(),self.user_model.username >= q.lower()))
for _qry in qry:
if q.lower() in _qry.name.lower() or q.lower() in _qry.email.lower() or q.lower() in _qry.username.lower():
users.append(_qry)
il n'est pas possible de faire une recherche similaire sur le moteur d'app datastore, comment jamais créer un Arraylist ferait l'affaire si vous avez besoin de rechercher un mot dans une chaîne.
@Index
public ArrayList<String> searchName;
et ensuite chercher dans l'index en utilisant objectify.
List<Profiles> list1 = ofy().load().type(Profiles.class).filter("searchName =",search).list();
et cela vous donnera une liste avec tous les éléments que contient le monde que vous avez fait sur la recherche
si le LIKE '%text%'
se compare toujours à un mot ou quelques - uns (pensez permutations) et vos données changent lentement (lentement signifie qu'il n'est pas prohibitivement coûteux-à la fois prix-sage et performance - pour créer et mettre à jour des indices) alors Relation index Entity (RIE) peut être la réponse.
Oui, vous devrez construire une entité datastore supplémentaire et la remplir correctement. Oui, Il ya certaines contraintes que vous aurez à jouer autour (un est 5000 limite sur la longueur de la propriété list dans GAE datastore). Mais les recherches qui en résultent sont fulgurantes.
pour plus de détails, voir mes messages RIE avec Java et Ojbectify et RIE avec Python .
"j'Aime" est souvent utilise comme du pauvre substitut à la recherche de texte. Pour la recherche de texte, il est possible d'utiliser Whoosh-AppEngine .