Ricerca con facet

La ricerca per facet consente di allegare informazioni relative alle categorie ai documenti. Un facet è una coppia attributo/valore. Ad esempio, il facet denominato "size" potrebbe avere valori "small", "medium" e "large".

Utilizzando i facet con la ricerca, puoi recuperare informazioni di riepilogo che consentono di perfezionare una query e visualizzare in dettaglio i risultati in una serie di passaggi.

Ciò è utile per applicazioni come i siti di shopping, in cui intendi offrire ai clienti una serie di filtri per limitare i prodotti che vogliono vedere.

I dati aggregati relativi a un facet mostrano come vengono distribuiti i valori di un facet. Ad esempio, le "dimensioni" dei facet potrebbero essere visualizzate in molti documenti del set di risultati. I dati aggregati per quel facet potrebbero mostrare che il valore "small" è comparso 100 volte, "medium" 300 volte e "large" 250 volte. Ogni coppia facet/valore rappresenta un sottoinsieme di documenti nel risultato della query. A ogni coppia è associata una chiave, chiamata perfezionamento. Puoi includere perfezionamenti in una query per recuperare documenti che corrispondono alla stringa di query e i cui valori dei facet corrispondono a uno o più perfezionamenti.

Quando esegui una ricerca, puoi scegliere i facet da raccogliere e visualizzare con i risultati oppure puoi consentire il rilevamento dei facet per selezionare automaticamente i facet che appaiono più spesso nei tuoi documenti.

Aggiunta di facet a un documento

Aggiungi facet a un documento prima di aggiungerlo a un indice. Esegui questa operazione nello stesso momento in cui specifichi i campi del documento:

def add_faceted_document(index):
    document = search.Document(
        doc_id="doc1",
        fields=[search.AtomField(name="name", value="x86")],
        facets=[
            search.AtomFacet(name="type", value="computer"),
            search.NumberFacet(name="ram_size_gb", value=8),
        ],
    )

    index.put(document)

Un facet è simile a un campo del documento; ha un nome e accetta un valore.

I nomi dei facet seguono le stesse regole dei campi del documento: i nomi sono sensibili alle maiuscole e possono contenere solo caratteri ASCII. Devono iniziare con una lettera e possono contenere lettere, numeri o trattini bassi. Un nome non può superare i 500 caratteri.

Il valore di un facet può essere una stringa atomica (non più lunga di 500 caratteri) o un numero (un valore in virgola mobile a precisione doppia compresa tra -2.147.483.647 e 2.147.483.647).

Puoi assegnare più valori a un facet in un documento aggiungendo un facet con lo stesso nome e tipo più volte, utilizzando ogni volta un valore diverso.

Non c'è limite al numero di valori che un facet può avere. Inoltre, non esiste alcun limite al numero di facet che puoi aggiungere a un documento o al numero di facet con nomi univoci in un indice.

Tieni presente che ogni volta che utilizzi un facet, può essere utilizzato un valore atomico o numerico. Un facet denominato "size" può essere allegato a un documento con valore stringa "small" e a un altro documento con valore numerico 8. Infatti, lo stesso facet può apparire più volte nello stesso documento con entrambi i tipi di valori. Sconsigliamo di utilizzare entrambi i valori atom e numerico per lo stesso facet, anche se è consentito.

Mentre un facet ha un tipo specifico quando lo aggiungi a un documento, i risultati di ricerca raccolgono tutti i suoi valori. Ad esempio, i risultati per "dimensione" del facet potrebbero mostrare che sono presenti 100 istanze del valore "small", 150 di "medium" e 135 istanze di valori numerici nell'intervallo [4, 8). Non vengono visualizzati i valori numerici esatti e la relativa distribuzione della frequenza.

Quando recuperi un documento utilizzando una query, non puoi accedere direttamente ai suoi facet e ai suoi valori. Devi richiedere che le informazioni sui facet vengano restituite con la query, come spiegato nella sezione successiva.

Utilizzo di una ricerca per facet per recuperare le informazioni sui facet

Puoi chiedere al backend di ricerca di trovare i facet usati più di frequente per te. Questa operazione è chiamata individuazione automatica dei facet. Puoi anche recuperare esplicitamente le informazioni sui facet selezionando un facet per nome o per nome e valore. Puoi combinare tutti e tre i tipi di recupero dei facet in un'unica query.

La richiesta di informazioni sui facet non influisce sui documenti restituiti dalla query. Può influire sulle prestazioni. L'esecuzione di una ricerca per facet con profondità predefinita di 1000 equivale a impostare il limite di punteggi delle opzioni di ordinamento su 1000.

Rilevamento automatico dei facet

Il rilevamento automatico dei facet cerca i facet che vengono visualizzati più spesso nell'aggregazione dei tuoi documenti. Ad esempio, supponi che i documenti corrispondenti alla tua query includano un facet "colore" visualizzato cinque volte con il valore "rosso", cinque volte con il valore "bianco" e cinque volte con il colore "blu". Questo facet ha un conteggio totale di 15. Ai fini del rilevamento, verrebbe classificato più in alto rispetto a un'altra "ombra" di facet che compare negli stessi documenti corrispondenti sei volte con il valore "scuro" e 7 volte con il valore "chiaro".

Devi abilitare il rilevamento dei facet impostandolo nella query:

def facet_discovery(index):
    # Create the query and enable facet discovery.
    query = search.Query("name:x86", enable_facet_discovery=True)
    results = index.search(query)

    for facet in results.facets:
        print("facet {}.".format(facet.name))
        for value in facet.values:
            print(
                "{}: count={}, refinement_token={}".format(
                    value.label, value.count, value.refinement_token
                )
            )

Quando recuperi i facet per rilevamento, per impostazione predefinita verranno restituiti solo i 10 valori più frequenti per un facet. Puoi aumentare questo limite fino a 100 utilizzando il parametro FacetOptions discovery_limit.

Tieni presente che il rilevamento automatico dei facet non ha lo scopo di restituire tutti i possibili facet e i relativi valori. I facet restituiti dal rilevamento possono variare da un'esecuzione all'altra. Se vuoi un set fisso di facet, utilizza un parametro return_facets nella query.

I valori stringa verranno restituiti singolarmente. I valori numerici di un facet rilevato vengono restituiti in un singolo intervallo [min max). Puoi esaminare questo intervallo e creare un sottointervallo più piccolo per una query successiva.

Selezione dei facet per nome

Per recuperare le informazioni su un facet solo in base al nome, aggiungi un parametro return_facets alla query, incluso il nome del facet nell'elenco:

def facet_by_name(index):
    # Create the query and specify to only return the "type" and "ram_size_gb"
    # facets.
    query = search.Query("name:x86", return_facets=["type", "ram_size_gb"])
    results = index.search(query)

    for facet in results.facets:
        print("facet {}".format(facet.name))
        for value in facet.values:
            print(
                "{}: count={}, refinement_token={}".format(
                    value.label, value.count, value.refinement_token
                )
            )

Quando recuperi i facet per nome, per impostazione predefinita verranno restituiti solo i 10 valori più frequenti per un facet. Puoi aumentare questo limite fino a 20 utilizzando il parametro FacetOptions discovery_value_limit.

Selezione dei facet per nome e valore

Per recuperare le informazioni solo su determinati valori di un facet, aggiungi un parametro return_facets che includa un oggetto FacetRequest con un elenco di valori:

def facet_by_name_and_value(index):
    # Create the query and specify to return the "type" facet with values
    # "computer" and "printer" and the "ram_size_gb" facet with value in the
    # ranges [0,4), [4, 8), and [8, max].
    query = search.Query(
        "name:x86",
        return_facets=[
            search.FacetRequest("type", values=["computer", "printer"]),
            search.FacetRequest(
                "ram_size_gb",
                ranges=[
                    search.FacetRange(end=4),
                    search.FacetRange(start=4, end=8),
                    search.FacetRange(start=8),
                ],
            ),
        ],
    )

    results = index.search(query)
    for facet in results.facets:
        print("facet {}".format(facet.name))
        for value in facet.values:
            print(
                "{}: count={}, refinement_token={}".format(
                    value.label, value.count, value.refinement_token
                )
            )

I valori in un singolo elemento FacetRequest devono essere tutti dello stesso tipo: un elenco di valori di stringa o, per i numeri, un elenco di FacetRanges, ovvero intervalli chiusi a sinistra (inizio) e aperti a destra (fine). Se il tuo facet ha una combinazione di valori di stringa e numero, aggiungi FacetRequests separate per ognuno.

Opzioni

Puoi controllare la ricerca per facet aggiungendo il parametro facet_options a una chiamata Query. Questo parametro accetta una singola istanza di FacetOptions. Utilizza questo parametro per eseguire l'override del comportamento predefinito della ricerca con facet.

options = FacetOptions(discover_facet_limit=5,
                       discover_facet_value_limit=10,
                       depth=6000);
Parametro Descrizione Predefinito
discover_facet_limit Numero di facet da scoprire se il rilevamento dei facet è attivo. Se il valore è 0, il rilevamento dei facet verrà disattivato. 10
discover_facet_value_limit Numero di valori da restituire per ciascuno dei primi facet rilevati. 10
depth Il numero minimo di documenti nei risultati della query da valutare per raccogliere informazioni sui facet. 1000

L'opzione depth si applica a tutti e tre i tipi di aggregazione dei facet: per nome, nome e valore e rilevamento automatico. Le altre opzioni riguardano solo il rilevamento automatico.

Tieni presente che la profondità dei facet di solito è molto maggiore del limite di query. I risultati dei facet vengono calcolati almeno in base al numero di documenti in profondità. Se hai impostato un limite di punteggio per le opzioni di ordinamento su un livello superiore alla profondità, verrà utilizzato il limite di punteggio.

Recupero dei risultati dei facet

Quando utilizzi parametri di ricerca con facet in una query, le informazioni aggregate sui facet vengono fornite insieme al risultato della query.

Una query avrà un elenco di FacetResult. Ci sarà un risultato nell'elenco per ogni facet visualizzato in un documento che corrisponde alla tua query. Per ogni risultato, potrai:

  • Il nome del facet
  • Un elenco dei valori più frequenti per il facet. Per ogni valore è presente un conteggio approssimativo del numero di volte che è stato visualizzato e una chiave di perfezionamento che può essere utilizzata per recuperare i documenti che corrispondono a questa query e al valore del facet.

Tieni presente che l'elenco dei valori includerà una stringa di facet e valori numerici. Se il facet è stato rilevato automaticamente, i relativi valori numerici vengono restituiti come intervallo singolo [min max). Se hai richiesto esplicitamente un facet numerico con uno o più intervalli nella query, l'elenco conterrà un intervallo chiuso-aperto [start end) per ogni intervallo.

L'elenco dei valori dei facet potrebbe non includere tutti i valori trovati nei documenti, poiché le opzioni di query determinano quanti documenti da esaminare e quanti valori restituire.

È possibile leggere le informazioni aggregate relative a ogni facet dai risultati di ricerca:

query = search.Query(...)
results = index.search(query)
for facet_info in results.facets:
  ...

Ad esempio, una query potrebbe aver trovato documenti che includevano un facet "size" con valori di stringa e valori numerici. Il FacetResult per questo facet verrà strutturato nel seguente modo:

FacetResult(name='size', values=[
  FacetResultValue(label='[8, 10)', 22, refinement=refinement_key),
  FacetResultValue(label='small', 100, refinement=refinement_key),
  FacetResultValue(label='medium', 300, refinement=refinement_key),
  FacetResultValue(label='large', 250, refinement=refinement_key)])

Il parametro label viene creato a partire da un valore facet. Per i valori numerici, label è la rappresentazione di un intervallo.

refinement_key è una stringa sicura per gli URL e/o web che può essere utilizzata in una query successiva per recuperare i documenti che corrispondono al nome e al valore del facet del risultato.

Utilizzo dei facet per perfezionare/filtrare una query

Il perfezionamento associato a ogni FacetResultValue può essere utilizzato per restringere ulteriormente i risultati in modo da includere solo i documenti che contengono quei valori dei facet. Per perfezionare le query con una o più di queste chiavi, passale all'oggetto query:

query = search.Query(..., facet_refinements=[refinement_key1, refinement_key2, refinement_key3])

Puoi combinare i perfezionamenti per uno o più facet diversi nella stessa richiesta. Tutti i perfezionamenti appartenenti allo stesso facet sono uniti con un OR. I perfezionamenti per facet diversi vengono combinati con AND.

È anche possibile creare manualmente una chiave FacetRefinement personalizzata. Per saperne di più, consulta la documentazione del corso.