Filtri nelle query di testo

Un filtro fornisce criteri basati su valori per includere o escludere il contenuto prima dell'esecuzione della query. Ad esempio, inclusi o esclusi documenti in base a date, località o lingua. I filtri vengono specificati in singoli campi. Una definizione di campo deve essere attribuita come "filtrabile" se si vuole usarla nelle espressioni di filtro.

Viene specificato un filtro usando la sintassi dell'espressione filtro OData. A differenza della ricerca full-text, un filtro ha esito positivo solo se la corrispondenza è esatta.

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:

  • Sezionare 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 di 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 filtri 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 si verifica 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 efficacemente 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 di intelligenza artificiale di Azure.

È possibile specificare un filtro per ogni operazione di ricerca , ma il filtro stesso può includere più campi, più criteri e se si usa una ismatch funzione, 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). Se si tenta di riorganizzare i predicati in una particolare sequenza, non è possibile ottenere prestazioni ottimali.

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 al 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 di dimensioni non associate.

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);

Criteri 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 esiste alcuna analisi lessicale o linguistica, nessun punteggio e nessuna 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 piedi) introduce i punteggi di ricerca nei risultati, dove 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 non diversa da quella di . 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 filtri usando and invece di or, ma questo è funzionalmente equivalente 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 è attivabile 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 successivo, l'attributo viene impostato sulla BaseRate proprietà di una classe 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 di intelligenza artificiale 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 un'analisi lessicale o un'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 di sole", $filter=f eq 'sunny' non corrisponda, ma $filter=f eq 'sunny day' lo farà.

Le stringhe di testo fanno distinzione tra maiuscole e minuscole, il che significa che i filtri di testo fanno distinzione tra maiuscole e minuscole per impostazione predefinita. Ad esempio, $filter=f eq 'Sunny day' non troverà "giorno di sole". Tuttavia, è possibile usare un normalizzatore per renderlo in modo che il filtro non faccia distinzione tra maiuscole e minuscole.

Approcci per filtrare il testo

Approccio Descrizione Quando utilizzarlo
search.in Funzione che corrisponde a un campo rispetto a un elenco delimitato di stringhe. Consigliato per i filtri di sicurezza e per 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 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 quando si desidera trovare corrispondenze esatte tra un campo stringa e un valore stringa.

Concetti fondamentali sui filtri numerici

I campi numerici non searchable sono 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. Pertanto, se si dispone di dati numerici, si presuppone che vengano 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 punto è che la ricerca full-text non è applicabile ai tipi di campo 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 filtro OData.

Vedi anche