Ricerca con facet

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

Utilizzando i facet con la ricerca, puoi recuperare informazioni di riepilogo per 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 restringere i prodotti che vogliono vedere.

I dati aggregati di un facet mostrano come vengono distribuiti i valori di un facet. Ad esempio, le "dimensioni" dei facet potrebbero apparire in molti dei documenti nel set di risultati. I dati aggregati per quel facet potrebbero mostrare che il valore "small" è apparso 100 volte, "medio" 300 volte e "grandi" 250 volte. Ogni coppia di 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 i documenti che corrispondono alla stringa di query e con i valori dei facet corrispondenti a uno o più perfezionamenti.

Quando esegui una ricerca, puoi scegliere i facet da raccogliere e mostrare insieme ai risultati oppure abilitare il rilevamento dei facet per selezionare automaticamente i facet che vengono visualizzati più spesso nei documenti.

Aggiunta di facet a un documento

Aggiungi facet a un documento prima di aggiungere il documento a un indice. Esegui questa operazione nel 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 di un documento: ha un nome e assume un valore.

I nomi dei facet seguono le stesse regole dei campi dei documenti: 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. Il nome non può contenere più di 500 caratteri.

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

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

Non esiste un limite al numero di valori che un facet può avere. Inoltre, non c'è 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ò assumere un valore atomico o numerico. Un facet con il nome "size" può essere allegato a un documento con il valore stringa "small" e a un altro documento con il valore numerico 8. Infatti, lo stesso facet può apparire più volte nello stesso documento con entrambi i tipi di valori. Sconsigliamo di utilizzare valori atom e numerici 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 relativi valori. Ad esempio, i risultati relativi al facet "size" potrebbero mostrare 100 istanze del valore "small", 150 istanze di "medium" e 135 istanze di valori numerici nell'intervallo [4, 8). Non vengono mostrati i valori numerici esatti e la loro distribuzione della frequenza.

Quando recuperi un documento utilizzando una query, non puoi accedere direttamente ai suoi facet e ai relativi valori. Devi richiedere la restituzione delle informazioni sui facet con la query, come spiegato nella prossima sezione.

Utilizzo di una ricerca facet per recuperare informazioni sui facet

Puoi chiedere al backend di ricerca di trovare i facet utilizzati più di frequente per te. Questa procedura è chiamata rilevamento dei facet automatico. Puoi anche recuperare le informazioni dei facet in modo esplicito selezionandolo per nome o per nome e valore. Puoi combinare tutti e tre i tipi di recupero dei facet in una singola query.

La richiesta di informazioni sui facet non influisce sui documenti restituiti dalla query. Può influire sulle prestazioni. L'esecuzione di una ricerca facet con profondità predefinita di 1000 ha lo stesso effetto dell'impostazione del limite del punteggio delle opzioni di ordinamento su 1000.

Rilevamento automatico dei facet

Il rilevamento automatico dei facet cerca i facet che compaiono più spesso nell'aggregato nei tuoi documenti. Ad esempio, supponiamo che i documenti che corrispondono alla tua query includano un facet "colore" che compare 5 volte con il valore "rosso", 5 volte con il valore "bianco" e 5 volte con il colore "blu". Questo facet ha un conteggio totale di 15. Ai fini della scoperta, verrebbe classificato più in alto di un'altra "sfumatura" di facet visualizzata negli stessi documenti corrispondenti sei volte con il valore "dark" e 7 volte con il valore "light".

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 vengono 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 dalla scoperta possono variare da una corsa all'altra. Se vuoi un insieme fisso di facet, utilizza un parametro return_facets nella query.

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

Selezionare i 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 vengono restituiti solo i 10 valori più frequenti per un facet. Puoi aumentare questo limite fino a 20 utilizzando il parametro FacetOptions discovery_value_limit.

Selezionare i 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 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 numerici, aggiungi FacetRequests separate per ciascuna.

Opzioni

Puoi controllare la ricerca con facet aggiungendo il parametro facet_options a una chiamata Query. Questo parametro utilizza 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 Predefinita
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 principali facet rilevati. 10
depth Il numero minimo di documenti da valutare nei risultati della query 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 sono solo per il rilevamento automatico.

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

Recupero dei risultati dei facet

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

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

  • Il nome del facet
  • Un elenco dei valori più frequenti per il facet. Per ogni valore è disponibile un conteggio approssimativo del numero di volte in cui è 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à la stringa di un facet e i valori numerici. Se il facet è stato rilevato automaticamente, i suoi valori numerici vengono restituiti come singolo intervallo [min max). Se hai richiesto esplicitamente un facet numerico con uno o più intervalli nella query, l'elenco conterrà un intervallo chiuso (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 esaminare e quanti valori restituire.

Le informazioni aggregate per ogni facet possono essere lette 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 i valori stringa e i valori numerici. Il FacetResult per questo facet sarà costruito in questo 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 è creato da un valore facet. Per i valori numerici, label è la rappresentazione di un intervallo.

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

Utilizzare i 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 hanno 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 una chiave FacetRefinement personalizzata a mano. Per saperne di più, consulta la documentazione del corso.