Filtri in Ricerca cognitiva di Azure

Un filtro fornisce criteri basati su valori per la selezione dei documenti da includere nei risultati della ricerca. Un filtro può essere un singolo valore o un'espressione di filtro OData. A differenza della ricerca full-text, un filtro ha esito positivo solo se viene eseguita una corrispondenza esatta.

I filtri vengono specificati in singoli campi. Una definizione di campo deve essere attribuita come "filtrabile" se si vuole usarla nelle espressioni di filtro.

Quando usare un filtro

I filtri sono fondamentali per diverse esperienze di ricerca, tra cui la ricerca geospaziale "trova vicino all'utente", la navigazione in base a facet e i filtri di sicurezza che mostrano solo i documenti che un utente può visualizzare. Se si implementa una di queste esperienze, è necessario un filtro. Le coordinate di georilevazione, la categoria di facet selezionata dall'utente o l'ID di sicurezza del richiedente vengono forniti dal filtro associato alla query di ricerca.

Gli scenari comuni includono i seguenti:

  • Filtrare i risultati della ricerca in base al contenuto nell'indice. Dato uno schema con posizione, categorie e servizi dell'hotel, è possibile creare un filtro per corrispondere in modo esplicito ai criteri (a Seattle, sull'acqua, con una vista).

  • Implementare un'esperienza di ricerca include una dipendenza di filtro:

    • L'esplorazione in base a facet usa un filtro per passare la categoria di facet selezionata dall'utente.
    • La ricerca geospaziale usa un filtro per passare le coordinate della posizione corrente nelle app e nelle funzioni "trova vicino a me" che corrispondono all'interno di un'area o per distanza.
    • I filtri di sicurezza passano gli identificatori di sicurezza come criteri di filtro, in cui una corrispondenza nell'indice funge da proxy per i diritti di accesso al documento.
  • Eseguire una ricerca "numeri". I campi numerici sono recuperabili e possono essere visualizzati nei risultati della ricerca, ma non sono ricercabili (soggetti alla ricerca full-text) singolarmente. Se sono necessari criteri di selezione basati su dati numerici, usare un filtro.

Modalità di esecuzione dei filtri

In fase di query, un parser di filtro accetta criteri come input, converte l'espressione in espressioni booleane atomiche rappresentate come albero e quindi valuta l'albero dei filtri su campi filtrabili in un indice.

Il filtro avviene in combinazione con la ricerca, qualificando i documenti da includere nell'elaborazione downstream per il recupero dei documenti e l'assegnazione dei punteggi di pertinenza. Se abbinato a una stringa di ricerca, il filtro riduce in modo efficace il set di richiamo dell'operazione di ricerca successiva. Se usato da solo (ad esempio, quando la stringa di query è vuota con search=*), il criterio di filtro è l'unico input.

Definizione di filtri

I filtri sono espressioni OData, articolate nella sintassi del filtro supportata da Ricerca cognitiva.

È possibile specificare un filtro per ogni operazione di ricerca , ma il filtro stesso può includere più campi, più criteri e se si usa una funzione ismatch , più espressioni di ricerca full-text. In un'espressione di filtro in più parti è possibile specificare predicati in qualsiasi ordine (soggetto alle regole di precedenza dell'operatore). Il riposizionamento dei predicati in una sequenza specifica non offre un miglioramento delle prestazioni rilevante.

Uno dei limiti per un'espressione di filtro è il limite massimo di dimensioni della richiesta. L'intera richiesta, compreso il filtro, può avere dimensioni massime di 16 MB per POST o 8 KB per GET. Esiste anche un limite per il numero di clausole nell'espressione di filtro. In genere, se si hanno centinaia di clausole, è probabile che si superi il limite. È consigliabile progettare l'applicazione in modo che non generi filtri con dimensioni non vincolate.

Gli esempi seguenti rappresentano definizioni di filtro prototipo in diverse API.

POST https://[service name].search.windows.net/indexes/hotels/docs/search?api-version=2020-06-30
{
    "search": "*",
    "filter": "Rooms/any(room: room/BaseRate lt 150.0)",
    "select": "HotelId, HotelName, Rooms/Description, Rooms/BaseRate"
}
    parameters =
        new SearchParameters()
        {
            Filter = "Rooms/any(room: room/BaseRate lt 150.0)",
            Select = new[] { "HotelId", "HotelName", "Rooms/Description" ,"Rooms/BaseRate"}
        };

    var results = searchIndexClient.Documents.Search("*", parameters);

Modelli di filtro

Gli esempi seguenti illustrano diversi modelli di utilizzo per gli scenari di filtro. Per altre idee, vedere Esempi di sintassi > delle espressioni OData.

  • Elemento $filter autonomo, senza una stringa di query, utile quando l'espressione filtro è in grado di specificare il nome completo dei documenti di interesse. Senza una stringa di query, non ci sono un'analisi lessicale o linguistica, un'assegnazione del punteggio e una classificazione. Si noti che la stringa di ricerca è solo un asterisco, ovvero "corrisponde a tutti i documenti".

    {
      "search": "*",
      "filter": "Rooms/any(room: room/BaseRate ge 60 and room/BaseRate lt 300) and Address/City eq 'Honolulu"
    }
    
  • Combinazione di stringa di query e $filter, dove il filtro crea il subset e la stringa di query fornisce gli input dei termini per la ricerca full-text nel subset filtrato. L'aggiunta di termini (teatri a distanza a piedi) introduce i punteggi di ricerca nei risultati, in cui i documenti che meglio corrispondono ai termini vengono classificati in alto. L'uso di un filtro con una stringa di query è il modello di utilizzo più comune.

    {
      "search": "walking distance theaters",
      "filter": "Rooms/any(room: room/BaseRate ge 60 and room/BaseRate lt 300) and Address/City eq 'Seattle'"
    }
    
    
  • Query composte, separate da "or", ciascuna con i propri criteri di filtro (ad esempio, 'beagle' in 'cane' or 'siamese' in 'gatto'). Le espressioni combinate con or vengono valutate singolarmente, con l'unione di documenti corrispondenti a ogni espressione inviata nella risposta. Questo modello di utilizzo viene ottenuto tramite la search.ismatchscoring funzione . È anche possibile usare la versione senza punteggio, search.ismatch.

    # Match on hostels rated higher than 4 OR 5-star motels.
    $filter=search.ismatchscoring('hostel') and Rating ge 4 or search.ismatchscoring('motel') and Rating eq 5
    
    # Match on 'luxury' or 'high-end' in the description field OR on category exactly equal to 'Luxury'.
    $filter=search.ismatchscoring('luxury | high-end', 'Description') or Category eq 'Luxury'&$count=true
    

    È anche possibile combinare la ricerca full-text tramite search.ismatchscoring con i filtri che usano and invece di or, ma ciò equivale funzionalmente all'uso dei search parametri e $filter in una richiesta di ricerca. Ad esempio, le due query seguenti producono lo stesso risultato:

    $filter=search.ismatchscoring('pool') and Rating ge 4
    
    search=pool&$filter=Rating ge 4
    

Requisiti dei campi per il filtro

Nell'API REST, filtrabile è attivato per impostazione predefinita per i campi semplici. I campi filtrabili causano un aumento delle dimensioni dell'indice. Assicurarsi di impostare "filterable": false per i campi che non si prevede di usare in un filtro. Per altre informazioni sulle impostazioni delle definizioni di campo, vedere l'articolo relativo all'operazione Create Index.

In .NET SDK la proprietà filterable è disattivata per impostazione predefinita. È possibile rendere filtrabile un campo impostando la proprietà IsFilterable dell'oggetto SearchField corrispondente su true. Nell'esempio seguente l'attributo viene impostato sulla BaseRate proprietà di una classe del modello mappata alla definizione dell'indice.

[IsFilterable, IsSortable, IsFacetable]
public double? BaseRate { get; set; }

Rendere filtrabile un campo esistente

Non è possibile modificare i campi esistenti per renderli filtrabili. È invece necessario aggiungere un nuovo campo o ricompilare l'indice. Per altre informazioni sulla ricompilazione di un indice o sul ripopolamento dei campi, vedere Come ricompilare un indice di Ricerca cognitiva di Azure.

Concetti fondamentali sui filtri di testo

I filtri di testo corrispondono ai campi stringa rispetto alle stringhe letterali specificate nel filtro: $filter=Category eq 'Resort and Spa'

A differenza della ricerca full-text, non esiste alcuna analisi lessicale o interruzione di parole per i filtri di testo, quindi i confronti sono solo per corrispondenze esatte. Si supponga, ad esempio, che un campo f contenga "giorno soleggiato", $filter=f eq 'Sunny' non corrisponda, ma $filter=f eq 'sunny day' lo farà.

Per le stringhe di testo viene fatta distinzione tra maiuscole e minuscole. Non ci sono maiuscole e minuscole di parole maiuscole: $filter=f eq 'Sunny day' non troverà "giorno soleggiato".

Approcci per filtrare il testo

Approccio Descrizione Utilizzo
search.in Funzione che corrisponde a un campo rispetto a un elenco delimitato di stringhe. Consigliato per i filtri di sicurezza e per tutti i filtri in cui è necessario associare molti valori di testo non elaborati con un campo stringa. La funzione search.in è progettata per la velocità ed è molto più veloce rispetto al confronto esplicito del campo con ogni stringa usando eq e or.
search.ismatch Funzione che consente di combinare le operazioni di ricerca full-text con operazioni di filtro esclusivamente booleane nella stessa espressione filtro. Usare search.ismatch (o il relativo equivalente di punteggio , search.ismatchscoring) quando si desiderano più combinazioni di filtri di ricerca in una sola richiesta. Può essere usata anche con un filtro contains per applicare un filtro su una stringa parziale all'interno di una stringa più grande.
$filter=field operator string Espressione definita dall'utente composta da campi, operatori e valori. Usare questa opzione per trovare corrispondenze esatte tra un campo stringa e un valore stringa.

Concetti fondamentali sui filtri numerici

I campi numerici non sono di tipo searchable nel contesto della ricerca full-text. Solo le stringhe sono soggette a ricerca full-text. Se, ad esempio, si immette 99,99 come termine di ricerca, non si otterranno gli articoli con prezzo $99,99. Verranno invece visualizzati gli articoli con il numero 99 nei campi stringa del documento. Se quindi si hanno dati numerici, il presupposto è che verranno usati per i filtri, inclusi intervalli, facet, gruppi e così via.

I documenti che contengono campi numerici (prezzo, dimensioni, SKU, ID) forniscono tali valori nei risultati della ricerca se il campo è contrassegnato come retrievable. Il concetto è che la ricerca full-text non è applicabile ai tipi di campi numerici.

Passaggi successivi

Provare a usare Esplora ricerche nel portale per inviare query con parametri $filter. L'indice real-estate-sample fornisce risultati interessanti per le query di filtro seguenti quando le si incolla nella barra di ricerca:

# Geo-filter returning documents within 5 kilometers of Redmond, Washington state
# Use $count=true to get a number of hits returned by the query
# Use $select to trim results, showing values for named fields only
# Use search=* for an empty query string. The filter is the sole input

search=*&$count=true&$select=description,city,postCode&$filter=geo.distance(location,geography'POINT(-122.121513 47.673988)') le 5

# Numeric filters use comparison like greater than (gt), less than (lt), not equal (ne)
# Include "and" to filter on multiple fields (baths and bed)
# Full text search is on John Leclerc, matching on John or Leclerc

search=John Leclerc&$count=true&$select=source,city,postCode,baths,beds&$filter=baths gt 3 and beds gt 4

# Text filters can also use comparison operators
# Wrap text in single or double quotes and use the correct case
# Full text search is on John Leclerc, matching on John or Leclerc

search=John Leclerc&$count=true&$select=source,city,postCode,baths,beds&$filter=city gt 'Seattle'

Per altri esempi, vedere Esempi di sintassi > delle espressioni di filtro OData.

Vedi anche