L'API Search fornisce un modello per
l'indicizzazione dei documenti che contengono dati strutturati. Puoi cercare un indice e
organizzare e presentare i risultati di ricerca. L'API supporta la corrispondenza esatta
nei campi stringa. I documenti e gli indici vengono salvati in un archivio permanente separato
ottimizzato per le operazioni di ricerca. L'API Search può indicizzare un numero qualsiasi di documenti. App Engine Datastore potrebbe essere più adatto alle applicazioni che devono recuperare set di risultati molto grandi. Per visualizzare i
contenuti del pacchetto search
, consulta il
riferimento al pacchetto search
.
Panoramica
L'API Search si basa su quattro concetti principali: documenti, indici, query e risultati.
Documenti
Un documento è un oggetto con un ID univoco e un elenco di campi contenenti dati utente. Ogni campo ha un nome e un tipo. Esistono diversi tipi di campi, identificati dai tipi di valori che contengono:
- Campo Atom: una stringa di caratteri indivisibile.
- Campo di testo: una stringa di testo semplice in cui è possibile eseguire ricerche parola per parola.
- Campo HTML: una stringa che contiene tag di markup HTML. È possibile eseguire ricerche solo nel testo al di fuori dei tag di markup.
- Campo numerico: un numero con rappresentazione in virgola mobile.
- Campo ora: un valore
time.Time
, memorizzato con una precisione di millisecondi. - Campo geopoint: un oggetto dati con coordinate di latitudine e longitudine.
La dimensione massima di un documento è 1 MB.
Indici
Un indice memorizza i documenti per il recupero. Puoi recuperare un singolo documento in base al suo ID, un intervallo di documenti con ID consecutivi o tutti i documenti in un indice. Puoi anche cercare in un indice per recuperare i documenti che soddisfano determinati criteri sui campi e sui relativi valori, specificati come stringa di query. Puoi gestire gruppi di documenti inserendoli in indici separati.
Non esiste un limite al numero di documenti in un indice o al numero di indici che puoi utilizzare. La dimensione totale di tutti i documenti in un singolo indice è limitata a 10 GB per impostazione predefinita. Gli utenti con il ruolo Amministratore App Engine possono inviare una richiesta dalla pagina App Engine Search della console Google Cloud per aumentare le dimensioni fino a 200 GB.
Query
Per cercare un indice, devi creare una query, che ha una stringa di query e, possibilmente, alcune opzioni aggiuntive. Una stringa di query specifica le condizioni per i valori di uno o più campi del documento. Quando esegui una ricerca in un indice, vengono restituiti solo i documenti dell'indice con campi che soddisfano la query.
La query più semplice, a volte chiamata "ricerca globale", è una stringa che contiene solo valori di campo. Questa ricerca utilizza una stringa che cerca documenti che contengono le parole "rosa" e "acqua":
Questa ricerca trova i documenti con campi data che contengono la data 4 luglio 1776 o campi di testo che includono la stringa "1776-07-04":
Una stringa di query può anche essere più specifica. Può contenere uno o più termini, ognuno dei quali specifica un campo e un vincolo sul valore del campo. La forma esatta di un termine dipende dal tipo di campo. Ad esempio, supponendo che esista un campo di testo denominato "Prodotto" e un campo numerico denominato "Prezzo", ecco una stringa di query con due termini:
Le opzioni di query, come suggerisce il nome, non sono obbligatorie. Consentono una serie di funzionalità:
- Controlla il numero di documenti restituiti nei risultati di ricerca.
- Specifica i campi del documento da includere nei risultati. L'impostazione predefinita prevede l'inclusione di tutti i campi del documento originale. Puoi specificare che i risultati includano solo un sottoinsieme di campi (il documento originale non viene modificato).
- Ordina i risultati.
- Crea "campi calcolati" per i documenti utilizzando
FieldExpressions
e campi di testo abbreviati utilizzando snippet. - Supporta la paginazione dei risultati di ricerca restituendo solo una parte dei documenti corrispondenti per ogni query (utilizzando offset e cursori)
Ti consigliamo di registrare le stringhe di query nella tua applicazione se vuoi tenere traccia delle query eseguite.
Risultati di ricerca
Una chiamataSearch
restituisce un valore
Iterator
,
che può essere utilizzato per restituire l'insieme completo di documenti corrispondenti.
Materiale di formazione aggiuntivo
Oltre a questa documentazione, puoi leggere il corso di formazione in due parti sull'API Search all'indirizzo Google Developer's Academy. Sebbene il corso utilizzi l'API Python, potresti trovare utile la discussione aggiuntiva sui concetti di ricerca.
Documenti e campi
I documenti sono rappresentati da strutture Go, che comprendono un elenco di campi. I documenti possono anche essere rappresentati da qualsiasi tipo che implementi l'interfacciaFieldLoadSaver
.
Identificatore documento
Ogni documento in un indice deve avere un identificatore univoco, ovvero docID
.
L'identificatore può essere utilizzato per recuperare un documento da un indice senza eseguire una ricerca. Per impostazione predefinita, l'API Search genera automaticamente un docID
quando
viene creato un documento. Puoi anche specificare tu stesso il docID
quando
crei un documento. Un docID
deve contenere solo caratteri ASCII visibili e stampabili (codici ASCII da 33 a 126 inclusi) e non deve superare i 500 caratteri. Un identificatore del documento non può iniziare con un punto esclamativo ("!"),
né iniziare e terminare con trattini bassi doppi ("__").
Sebbene sia comodo creare identificatori di documenti unici, significativi e leggibili,
non puoi includere docID
in una ricerca. Considera questo scenario: hai
un indice con documenti che rappresentano parti, utilizzando il numero di serie
della parte come docID
. Sarà molto efficiente recuperare il documento
per qualsiasi singolo componente, ma sarà impossibile cercare un intervallo di numeri
di serie insieme ad altri valori di campo, come la data di acquisto. L'archiviazione del numero
di serie in un campo atom risolve il problema.
Campi documento
Un documento contiene campi con un nome, un tipo e un singolo valore di quel tipo. Due o più campi possono avere lo stesso nome, ma tipi diversi. Ad esempio, puoi definire due campi con il nome "età": uno con un tipo di testo (il valore "ventidue") e l'altro con un tipo di numero (il valore 22).
Nomi dei campi
I nomi dei campi fanno distinzione tra maiuscole e minuscole e possono contenere solo caratteri ASCII. Devono iniziare con una lettera e possono contenere lettere, cifre o trattini bassi. Il nome di un campo non può contenere più di 500 caratteri.
Campi multivalore
Un campo può contenere un solo valore, che deve corrispondere al tipo del campo. I nomi dei campi non devono essere univoci. Un documento può avere più campi con lo stesso nome e lo stesso tipo, il che è un modo per rappresentare un campo con più valori. Tuttavia, i campi data e numerici con lo stesso nome non possono essere ripetuti. Un documento può contenere anche più campi con lo stesso nome e tipi di campi diversi.
Tipi di campo
Esistono tre tipi di campi che memorizzano stringhe di caratteri; collettivamente li chiamiamo campi stringa:
- Campo di testo: una stringa con una lunghezza massima di 1024**2 caratteri.
- Campo HTML: una stringa formattata in HTML con una lunghezza massima di 1024**2 caratteri.
- Campo Atom: una stringa con una lunghezza massima di 500 caratteri.
Esistono anche tre tipi di campi che archiviano dati non testuali:
- Campo numerico: un valore in virgola mobile a doppia precisione compreso tra -2.147.483.647 e 2.147.483.647.
- Campo ora: un valore
time.Time
, memorizzato con una precisione di millisecondi. - Campo Geopoint: un punto sulla Terra descritto dalle coordinate di latitudine e longitudine.
I tipi di campi stringa sono il tipo
string
integrato di Go e i tipi search
HTML
e
Atom
del pacchetto. I campi numerici
sono rappresentati con il tipo
float64
integrato di Go, i campi temporali utilizzano il tipo
time.Time
e i campi geopoint utilizzano
il tipo
GeoPoint
del pacchetto appengine
.
Trattamento speciale dei campi stringa e ora
Quando un documento con campi di ora, testo o HTML viene aggiunto a un indice, viene eseguita una gestione speciale. È utile capire cosa succede "sotto il cofano" per utilizzare l'API Search in modo efficace.
Tokenizzazione dei campi stringa
Quando un campo HTML o di testo viene indicizzato, i relativi contenuti vengono tokenizzati. La stringa viene suddivisa in token ovunque compaiano spazi vuoti o caratteri speciali (segni di punteggiatura, cancelletto, barra rovesciata e così via). L'indice includerà una voce per ogni token. In questo modo puoi cercare parole chiave e frasi che comprendono solo una parte del valore di un campo. Ad esempio, una ricerca di "buio" troverà un documento con un campo di testo contenente la stringa "era una notte buia e tempestosa", mentre una ricerca di "tempo" troverà un documento con un campo di testo contenente la stringa "questo è un sistema in tempo reale".
Nei campi HTML, il testo all'interno dei tag di markup non viene tokenizzato, quindi un documento con un
campo HTML contenente it was a <strong>dark</strong> night
corrisponderà a una
ricerca di "notte", ma non di "forte". Se vuoi poter cercare
il testo di markup, memorizzalo in un campo di testo.
I campi Atom non vengono tokenizzati. Un documento con un campo atom che ha il valore "bad weather" corrisponderà solo a una ricerca dell'intera stringa "bad weather". Non corrisponderà a una ricerca di "bad" o "weather" da soli.
Regole di tokenizzazione
I caratteri trattino basso (_) e e commerciale (&) non dividono le parole in token.
Questi caratteri di spazio vuoto dividono sempre le parole in token: spazio, ritorno a capo, avanzamento riga, tabulazione orizzontale, tabulazione verticale, avanzamento pagina e NULL.
Questi caratteri vengono trattati come punteggiatura e dividono le parole in token:
! " % ( ) * , - | / [ ] ] ^ ` : = > ? @ { } ~ $ I caratteri nella tabella seguente di solito dividono le parole in token, ma possono essere gestiti in modo diverso a seconda del contesto in cui vengono visualizzati:
Basato su caratteri Regola <
In un campo HTML, il segno "minore di" indica l'inizio di un tag HTML che viene ignorato. +
Una stringa di uno o più segni "più" viene trattata come parte della parola se appare alla fine della parola (C++). #
Il simbolo "#" viene considerato parte della parola se è preceduto da a, b, c, d, e, f, g, j o x (a# - g# sono note musicali; j# e x# sono linguaggi di programmazione, c# è entrambi). Se un termine è preceduto da "#" (#google), viene considerato un hashtag e il cancelletto diventa parte della parola. '
L'apostrofo è una lettera se precede la lettera "s" seguita da un'interruzione di parola, come in "il cappello di Giovanni". .
Se tra le cifre è presente un separatore decimale, questo fa parte di un numero. Può anche far parte di una parola se utilizzato in un acronimo (A.B.C). -
Il trattino fa parte di una parola se utilizzato in un acronimo (I-B-M). Tutti gli altri caratteri a 7 bit diversi da lettere e cifre ("A-Z", "a-z", "0-9") vengono gestiti come punteggiatura e dividono le parole in token.
Tutto il resto viene analizzato come carattere UTF-8.
Acronimi
La tokenizzazione utilizza regole speciali per riconoscere gli acronimi (stringhe come "I.B.M.", "a-b-c" o "C I A"). Un acronimo è una stringa di singoli caratteri alfabetici, con lo stesso carattere separatore tra tutti. I separatori validi sono il punto, il trattino o un numero qualsiasi di spazi. Il carattere separatore viene rimosso dalla stringa quando un acronimo viene tokenizzato. Quindi, le stringhe di esempio menzionate sopra diventano i token "ibm", "abc" e "cia". Il testo originale rimane nel campo del documento.
Quando tratti con gli acronimi, tieni presente che:
- Un acronimo non può contenere più di 21 lettere. Una stringa di acronimi valida con più di 21 lettere verrà suddivisa in una serie di acronimi, ciascuno di 21 lettere o meno.
- Se le lettere di un acronimo sono separate da spazi, tutte le lettere devono essere nello stesso caso. Gli acronimi costruiti con punto e trattino possono utilizzare lettere maiuscole e minuscole.
- Quando cerchi un acronimo, puoi inserire la forma canonica dell'acronimo (la stringa senza separatori) o l'acronimo con il trattino o il punto (ma non entrambi) tra le lettere. Pertanto, il testo "I.B.M" potrebbe essere recuperato con uno qualsiasi dei termini di ricerca "I-B-M", "I.B.M" o "IBM".
Precisione del campo Ora
Quando crei un campo ora in un
documento, imposti il relativo valore su un
time.Time
.
Ai fini dell'indicizzazione e della ricerca del
campo temporale, qualsiasi componente temporale viene
ignorato e la data viene convertita nel numero di giorni a partire dal 1° gennaio 1970 UTC. Ciò
significa che, anche se un campo ora
può contenere un valore di ora preciso, una query sulla data può specificare un
valore del campo ora solo nel formato
yyyy-mm-dd
. Ciò significa anche che l'ordine
di ordinamento dei campi
ora con la stessa data non è
ben definito. Mentre il tipo time.Time
rappresenta l'ora
con precisione al nanosecondo, l'API Search li memorizza solo con precisione al millisecondo.
Altre proprietà del documento
Il rank di un documento è un numero intero positivo che determina l'ordinamento predefinito
dei documenti restituiti da una ricerca. Per impostazione predefinita, il rango viene impostato
al momento della creazione del documento sul numero di secondi trascorsi dal 1° gennaio
2011. Puoi impostare il rango in modo esplicito quando crei un documento. È una cattiva
idea assegnare lo stesso ranking a molti documenti e non dovresti mai assegnare lo stesso ranking a più
di 10.000 documenti.
Se specifichi le opzioni di ordinamento, puoi utilizzare il ranking come chiave di ordinamento. Tieni presente che quando il ranking viene utilizzato in un'espressione
di ordinamento
o in un'espressione di campo,
viene fatto riferimento come _rank
.
Per ulteriori informazioni sull'impostazione del ranking, consulta la DocumentMetadata
.
La proprietà Language dello struct
Field
specifica
la lingua in cui è codificato il campo.
Collegamento da un documento ad altre risorse
Puoi utilizzare il docID
e altri campi di un documento come link ad altre risorse nella tua applicazione. Ad esempio, se utilizzi
Blobstore, puoi associare
il documento a un blob specifico impostando docID
o il valore di un
campo Atom su BlobKey dei dati.
Creare un documento
Il seguente esempio di codice mostra come creare un oggetto documento. Il tipo User
specifica la struttura del documento e un valore User
viene costruito nel modo
solito.
Utilizzare un indice
Inserire documenti in un indice
Quando inserisci un documento in un indice, questo viene copiato nello spazio di archiviazione
permanente e ogni suo campo viene indicizzato in base al nome, al tipo e al
docID
.
Il seguente esempio di codice mostra come accedere a un indice e inserire un documento.
Quando inserisci un documento in un indice e l'indice contiene già un documento
con lo stesso docID
, il nuovo documento sostituisce quello precedente. Non viene
fornito alcun avviso. Puoi chiamare
Index.Get
prima di creare o aggiungere un documento a un indice per verificare se esiste già un docID
specifico.
Il metodo Put
restituisce un docID
. Se non hai specificato docID
personalmente, puoi esaminare il risultato per scoprire il docID
che è stato
generato:
Tieni presente che la creazione di un'istanza del tipo Index
non garantisce l'esistenza effettiva di un indice persistente. Un indice persistente viene creato la prima volta
che aggiungi un documento con il metodo put
.
Aggiornamento dei documenti
Un documento non può essere modificato una volta aggiunto a un indice. Non puoi aggiungere o
rimuovere campi né modificare il valore di un campo. Tuttavia, puoi sostituire il documento
con un nuovo documento che abbia lo stesso docID
.
Recupero dei documenti per ID documento
Utilizza il metodo Index.Get
per recuperare un documento da un indice in base al suo docID
:
Ricerca di documenti in base ai contenuti
Per recuperare i documenti da un indice, crea una stringa di query e chiama
Index.Search
.
Search
restituisce un iteratore che genera documenti corrispondenti
in ordine di rango decrescente.
Eliminazione di un indice
Ogni indice è costituito dai documenti indicizzati e da uno schema dell'indice. Per eliminare un indice, elimina tutti i documenti in un indice, quindi elimina lo schema dell'indice.
Puoi eliminare i documenti in un indice specificando il docID
del
documento
che vuoi eliminare nel metodo Index.Delete
.
Questo approccio potrebbe richiedere molto tempo se devi eliminare un numero elevato di voci dell'indice di ricerca. Per risolvere il problema, prova quanto segue:
- Elimina il progetto e le relative dipendenze.
- Richiedi una quota più elevata per eliminazioni più rapide.
Coerenza finale
Quando inserisci, aggiorni o elimini un documento in un indice, la modifica viene propagata in più data center. In genere questa operazione è rapida, ma i tempi possono variare. L'API Search garantisce la coerenza finale. Ciò significa che in alcuni casi, una ricerca o un recupero di uno o più documenti potrebbe restituire risultati che non riflettono le modifiche più recenti.
Schemi di indice
Ogni indice ha uno schema che mostra tutti i nomi e i tipi di campo che appaiono nei documenti che contiene. Non puoi definire uno schema. Gli schemi vengono gestiti in modo dinamico e vengono aggiornati man mano che i documenti vengono aggiunti a un indice. Uno schema semplice potrebbe avere questo aspetto, in formato simile a JSON:
{'comment': ['TEXT'], 'date': ['DATE'], 'author': ['TEXT'], 'count': ['NUMBER']}
Ogni chiave nel dizionario è il nome di un campo del documento. Il valore della chiave è un elenco dei tipi di campo utilizzati con quel nome di campo. Se hai utilizzato lo stesso nome campo con tipi di campi diversi, lo schema elencherà più di un tipo di campo per un nome campo, ad esempio:
{'ambiguous-integer': ['TEXT', 'NUMBER', 'ATOM']}
Una volta visualizzato in uno schema, un campo non può mai essere rimosso. Non è possibile eliminare un campo, anche se l'indice non contiene più documenti con quel particolare nome di campo.
Uno schema non definisce una "classe" nel senso della programmazione orientata agli oggetti. Per quanto riguarda l'API Search, ogni documento è unico e gli indici possono contenere diversi tipi di documenti. Se vuoi trattare raccolte di oggetti con lo stesso elenco di campi come istanze di una classe, questa è un'astrazione che devi applicare nel tuo codice. Ad esempio, potresti assicurarti che tutti i documenti con lo stesso insieme di campi vengano conservati nel proprio indice. Lo schema dell'indice può essere considerato come la definizione della classe e ogni documento nell'indice sarebbe un'istanza della classe.
Visualizzazione degli indici nella console Google Cloud
Nella console Google Cloud , puoi visualizzare informazioni sugli indici della tua applicazione e sui documenti che contengono. Se fai clic sul nome di un indice, vengono visualizzati i documenti che contiene. Vedrai tutti i campi dello schema definiti per l'indice; per ogni documento con un campo di quel nome, vedrai il valore del campo. Puoi anche eseguire query sui dati dell'indice direttamente dalla console.
Quote dell'API Search
L'API Search ha diverse quote gratuite:
Risorsa o chiamata API | Quota gratuita |
---|---|
Capacità di archiviazione totale (documenti e indici) | 0,25 GB |
Query | 1000 query al giorno |
Aggiunta di documenti agli indici | 0,01 GB al giorno |
L'API Search impone questi limiti per garantire l'affidabilità del servizio. Queste norme si applicano sia alle app gratuite che a pagamento:
Risorsa | Quota di sicurezza |
---|---|
Utilizzo massimo delle query | 100 minuti aggregati di tempo di esecuzione delle query al minuto |
Numero massimo di documenti aggiunti o eliminati | 15.000 al minuto |
Dimensione massima per indice (numero illimitato di indici consentiti) | 10 GB |
L'utilizzo dell'API viene conteggiato in modi diversi a seconda del tipo di chiamata:
Index.Search
: ogni chiamata API viene conteggiata come una query; il tempo di esecuzione è equivalente alla latenza della chiamata.Index.Put
: Quando aggiungi documenti agli indici, le dimensioni di ogni documento e il numero di documenti vengono conteggiati ai fini della quota di indicizzazione.- Tutte le altre chiamate all'API Search vengono conteggiate in base al numero di operazioni che
comportano:
Index.Get
: 1 operazione conteggiata per ogni documento effettivamente restituito oppure 1 operazione se non viene restituito nulla.Index.Delete
: 1 operazione conteggiata per ogni documento nella richiesta oppure 1 operazione se la richiesta è vuota.
La quota di throughput delle query viene imposta in modo che un singolo utente non possa monopolizzare il servizio di ricerca. Poiché le query possono essere eseguite contemporaneamente, ogni applicazione può eseguire query che consumano fino a 100 minuti di tempo di esecuzione per un minuto di tempo reale. Se esegui molte query brevi, probabilmente non raggiungerai questo limite. Una volta superata la quota, le query successive non andranno a buon fine fino alla successiva finestra temporale, quando la quota viene ripristinata. La quota non viene imposta rigorosamente in intervalli di un minuto; viene utilizzata una variante dell'algoritmo leaky bucket per controllare la larghezza di banda di ricerca in incrementi di cinque secondi.
Per ulteriori informazioni sulle quote, consulta la pagina Quote. Quando un'app tenta di superare questi limiti, viene restituito un errore di quota insufficiente.
Tieni presente che, sebbene questi limiti vengano applicati al minuto, la console mostra i totali giornalieri per ciascuno. I clienti con assistenza Silver, Gold o Platinum possono richiedere limiti di velocità effettiva più elevati contattando il rappresentante dell'assistenza.
Prezzi dell'API Search
I seguenti addebiti vengono applicati all'utilizzo oltre le quote gratuite:
Risorsa | Costo |
---|---|
Capacità di archiviazione totale (documenti e indici) | 0,18 $ per GB al mese |
Query | 0,50 $ per 10.000 query |
Indicizzazione dei documenti disponibili per la ricerca | 2 $ per GB |
Ulteriori informazioni sui prezzi sono disponibili nella pagina Prezzi.