Motore dell'applicazione Google:È possibile eseguire una query Gql LIKE?
-
09-06-2019 - |
Domanda
Semplice davvero.In SQL, se voglio cercare un campo di testo per un paio di caratteri, posso fare:
SELECT blah FROM blah WHERE blah LIKE '%text%'
La documentazione di App Engine non menziona come raggiungere questo obiettivo, ma sicuramente è un problema abbastanza comune?
Soluzione
BigTable, che è il back-end del database per App Engine, raggiungerà milioni di record.Per questo motivo, App Engine non ti consentirà di eseguire alcuna query che risulterà in una scansione della tabella, poiché le prestazioni sarebbero pessime per una tabella ben popolata.
In altre parole, ogni query deve utilizzare un indice.Ecco perché puoi solo fare =
, >
E <
interrogazioni.(In effetti puoi anche farlo !=
ma l'API lo fa utilizzando una combinazione di >
E <
query.) Questo è anche il motivo per cui l'ambiente di sviluppo monitora tutte le query eseguite e aggiunge automaticamente eventuali indici mancanti al tuo file index.yaml
file.
Non è possibile indicizzare a LIKE
query quindi semplicemente non è disponibile.
Guardalo questa sessione di Google IO per una spiegazione molto migliore e più dettagliata di questo.
Altri suggerimenti
sto affrontando lo stesso problema, ma ho trovato qualcosa sulle pagine di Google App Engine:
Mancia:I filtri di query non hanno un modo esplicito per corrispondere solo a parte di un valore di stringa, ma puoi simulare una corrispondenza di prefisso utilizzando filtri di disuguaglianza:
db.GqlQuery("SELECT * FROM MyModel WHERE prop >= :1 AND prop < :2",
"abc",
u"abc" + u"\ufffd")
Ciò corrisponde a ogni entità MyModel con una proprietà di stringa che inizia con i caratteri abc.La stringa Unicode u"\ufffd" rappresenta il carattere Unicode più grande possibile.Quando i valori delle proprietà vengono ordinati in un indice, i valori che rientrano in questo intervallo sono tutti i valori che iniziano con il prefisso specificato.
http://code.google.com/appengine/docs/python/datastore/queriesandindexes.html
forse questo potrebbe fare al caso tuo ;)
Sebbene App Engine non supporti le query LIKE, dai un'occhiata alle proprietà ElencoProprietà E StringListProperty.Quando viene eseguito un test di uguaglianza su queste proprietà, il test verrà effettivamente applicato a tutti i membri dell'elenco, ad esempio, list_property = value
verifica se il valore appare ovunque nell'elenco.
A volte questa funzionalità potrebbe essere utilizzata come soluzione alternativa alla mancanza di query LIKE.Ad esempio, rende possibile farlo semplice ricerca testuale, come descritto in questo post.
Devi usare servizio di ricerca per eseguire query di ricerca full-text simili a SQL LIKE
.
Gaelyk fornisce un linguaggio specifico del dominio per ottenere di più query di ricerca intuitive.Ad esempio, il seguente snippet troverà i primi dieci libri ordinati dagli ultimi con il titolo contenente fern
e il genere corrisponde esattamente 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
}
Like è scritto come operatore di corrispondenza di Groovy =~
.Supporta funzioni come distance(geopoint(lat, lon), location)
anche.
Il motore dell'app ha lanciato uno scopo generale servizio di ricerca del testo completo nella versione 1.7.0 che supporta il datastore.
Dettagli in annuncio.
Ulteriori informazioni su come utilizzarlo: https://cloud.google.com/appengine/training/fts_intro/lesson2
Dai un'occhiata a Objectify Qui , è come un'API di accesso al Datastore.C'è una FAQ con questa domanda specifica, ecco la risposta
Come faccio a eseguire una query Mi piace (LIKE "foo%")
Puoi fare qualcosa come startWith o endWith se inverti l'ordine quando viene archiviato e cercato.Esegui una query su un intervallo con il valore iniziale desiderato e un valore appena sopra quello desiderato.
String start = "foo";
... = ofy.query(MyEntity.class).filter("field >=", start).filter("field <", start + "\uFFFD");
Basta seguire qui:init.py#354">http://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/ext/search/dentro.py#354
Funziona!
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(...)
L'ho testato con l'API Java di basso livello di GAE Datastore.Io e funziona perfettamente
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);
In generale, anche se questo è un vecchio post, un modo per produrre un 'LIKE' o 'ILIKE' è raccogliere tutti i risultati da una query '>=', quindi ripetere i risultati in Python (o Java) per gli elementi contenenti ciò che desideri stai cercando.
Supponiamo che tu voglia filtrare gli utenti in base a 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)
Non è possibile eseguire una ricerca LIKE sul motore dell'app datastore, tuttavia la creazione di un Arraylist funzionerebbe se è necessario cercare una parola in una stringa.
@Index
public ArrayList<String> searchName;
e quindi cercare nell'indice utilizzando objectify.
List<Profiles> list1 = ofy().load().type(Profiles.class).filter("searchName =",search).list();
e questo ti darà un elenco con tutti gli elementi che contengono il mondo che hai fatto nella ricerca
Se la LIKE '%text%'
si confronta sempre con una o poche parole (si pensi alle permutazioni) e i tuoi dati cambiano lentamente (lentamente significa che non è proibitivamente costoso, sia in termini di prezzo che di prestazioni, per creare e aggiornare gli indici), quindi Relation Index Entity (RIE) potrebbe essere la risposta.
Sì, dovrai creare un'entità di archivio dati aggiuntiva e popolarla in modo appropriato.Sì, ci sono alcuni vincoli che dovrai aggirare (uno è il limite di 5000 sulla lunghezza della proprietà elenco nel datastore GAE).Ma le ricerche risultanti sono velocissime.
Per i dettagli vedere il mio RIE con Java e Ojbectify E RIE con Python post.
"Mi piace" viene spesso utilizzato come sostituto povero della ricerca testuale.Per la ricerca testuale è possibile utilizzare Whoosh-AppEngine.