Ricerca e modelli di termini parziali con caratteri speciali (trattini, caratteri jolly, regex, pattern)

Una ricerca di termini parziale si riferisce a query costituite da frammenti di termini, in cui invece di un intero termine, si potrebbe avere solo l'inizio, la metà o la fine del termine (talvolta definita prefisso, prefisso o suffisso). Una ricerca di termini parziale può includere una combinazione di frammenti, spesso con caratteri speciali, ad esempio trattini, trattini o barre che fanno parte della stringa di query. I casi d'uso comuni includono parti di un numero di telefono, un URL, codici o parole composte sillabate.

I termini parziali e i caratteri speciali possono essere problematici se l'indice non ha un token che rappresenta il frammento di testo da cercare. Durante la fase di analisi lessicale dell'indicizzazione (presupponendo l'analizzatore standard predefinito), i caratteri speciali vengono eliminati, le parole composte vengono suddivise e gli spazi vuoti vengono eliminati. Se si sta cercando un frammento di testo modificato durante l'analisi lessicale, la query ha esito negativo perché non viene trovata alcuna corrispondenza. Si consideri questo esempio: un numero di telefono come +1 (425) 703-6214 (tokenizzato come "1", "425""703", , "6214") non verrà visualizzato in una "3-62" query perché tale contenuto non esiste effettivamente nell'indice.

La soluzione consiste nel richiamare un analizzatore durante l'indicizzazione che mantiene una stringa completa, inclusi spazi e caratteri speciali, se necessario, in modo da poter includere gli spazi e i caratteri nella stringa di query. La presenza di una stringa intera e non interrotta consente la corrispondenza dei criteri per le query "inizia con" o "termina con", in cui il modello fornito può essere valutato in base a un termine che non viene trasformato dall'analisi lessicale.

Se è necessario supportare scenari di ricerca che richiedono contenuti analizzati e non analizzati, è consigliabile creare due campi nell'indice, uno per ogni scenario. Un campo viene sottoposto ad analisi lessicale. Il secondo campo archivia una stringa intatta, usando un analizzatore di conservazione del contenuto che genera token di stringa interi per la corrispondenza dei criteri.

Ricerca di intelligenza artificiale di Azure analizza i termini interi con token nell'indice e non troverà una corrispondenza in un termine parziale, a meno che non si includano operatori segnaposto jolly (* e ?) o formattare la query come espressione regolare.

I termini parziali vengono specificati usando queste tecniche:

  • Le query di espressioni regolari possono essere qualsiasi espressione regolare valida in Apache Lucene.

  • Gli operatori con caratteri jolly con corrispondenza del prefisso fanno riferimento a un modello generalmente riconosciuto che include l'inizio di un termine, seguito da * o ? operatori suffisso, ad esempio search=cap* la corrispondenza in "Cap'n Jack's Waterfront Inn" o "Gacc Capital". La corrispondenza dei prefissi è supportata sia nella sintassi di query Lucene semplice che completa.

  • Il carattere jolly con prefisso e suffisso trova gli * operatori e ? all'interno o all'inizio di un termine e richiede una sintassi di espressione regolare (dove l'espressione è racchiusa con barre). Ad esempio, la stringa di query (search=/.*numeric.*/) restituisce i risultati su "alfanumerico" e "alfanumerico" come suffisso e corrispondenze di prefisso.

Per l'espressione regolare, il carattere jolly e la ricerca fuzzy, gli analizzatori non vengono usati in fase di query. Per questi moduli di query, che il parser rileva dalla presenza di operatori e delimitatori, la stringa di query viene passata al motore senza analisi lessicale. Per questi moduli di query, l'analizzatore specificato nel campo viene ignorato.

Nota

Quando una stringa di query parziale include caratteri, ad esempio barre in un frammento di URL, potrebbe essere necessario aggiungere caratteri di escape. In JSON una barra / viene preceduta da un carattere di escape con una barra \all'indietro. Di conseguenza, search=/.*microsoft.com\/azure\/.*/ è la sintassi per il frammento url "microsoft.com/azure/".

Risoluzione dei problemi di ricerca parziale/pattern

Quando è necessario cercare frammenti o modelli o caratteri speciali, è possibile eseguire l'override dell'analizzatore predefinito con un analizzatore personalizzato che opera in regole di tokenizzazione più semplici, mantenendo l'intera stringa nell'indice.

L'approccio è simile al seguente:

  1. Definire un secondo campo per archiviare una versione intatta della stringa (presupponendo che si voglia analizzare e non analizzare il testo in fase di query)
  2. Valutare e scegliere tra i vari analizzatori che generano token al livello di granularità corretto
  3. Assegnare l'analizzatore al campo
  4. Compilare e testare l'indice

1 - Creare un campo dedicato

Gli analizzatori determinano il modo in cui i termini vengono tokenizzati in un indice. Poiché gli analizzatori vengono assegnati in base ai singoli campi, è possibile creare campi nell'indice per ottimizzare per scenari diversi. Ad esempio, è possibile definire "featureCode" e "featureCodeRegex" per supportare la normale ricerca full-text sul primo e i criteri di ricerca avanzati al secondo. Gli analizzatori assegnati a ogni campo determinano il modo in cui il contenuto di ogni campo viene tokenizzato nell'indice.

{
  "name": "featureCode",
  "type": "Edm.String",
  "retrievable": true,
  "searchable": true,
  "analyzer": null
},
{
  "name": "featureCodeRegex",
  "type": "Edm.String",
  "retrievable": true,
  "searchable": true,
  "analyzer": "my_custom_analyzer"
},

2 - Impostare un analizzatore

Quando si sceglie un analizzatore che produce token a termine intero, gli analizzatori seguenti sono scelte comuni:

Analizzatore Comportamenti
analizzatori del linguaggio Mantiene i trattini in parole composte o stringhe, mutazioni vocali e forme verbo. Se i modelli di query includono trattini, l'uso di un analizzatore del linguaggio potrebbe essere sufficiente.
keyword Il contenuto dell'intero campo viene tokenizzato come singolo termine.
whitespace Separa solo gli spazi vuoti. I termini che includono trattini o altri caratteri vengono considerati come un singolo token.
analizzatore personalizzato (scelta consigliata) La creazione di un analizzatore personalizzato consente di specificare sia il tokenizer che il filtro del token. Gli analizzatori precedenti devono essere usati così come sono. Un analizzatore personalizzato consente di selezionare i tokenizer e i filtri di token da usare.

Una combinazione consigliata è il tokenizzatore di parole chiave con un filtro di token minuscolo. Da solo, l'analizzatore di parole chiave predefinito non fa in minuscolo alcun testo maiuscolo, che può causare l'esito negativo delle query. Un analizzatore personalizzato offre un meccanismo per l'aggiunta del filtro del token con lettere minuscole.

Usando un client REST, è possibile aggiungere la chiamata REST dell'analizzatore di test per esaminare l'output in token.

L'indice deve esistere nel servizio di ricerca, ma può essere vuoto. Dato un indice esistente e un campo contenente trattini o termini parziali, è possibile provare vari analizzatori su termini specifici per vedere quali token vengono generati.

  1. Prima di tutto, controllare l'analizzatore Standard per vedere come i termini vengono tokenizzati per impostazione predefinita.

    {
    "text": "SVP10-NOR-00",
    "analyzer": "standard"
    }
    
  2. Valutare la risposta per vedere in che modo il testo viene tokenizzato all'interno dell'indice. Si noti che ogni termine è con lettere minuscole, trattini rimossi e sottostringhe suddivise in singoli token. Nei risultati verranno restituite solo le query che corrispondono a questi token. Una query che include "10-NOR" avrà esito negativo.

    {
        "tokens": [
            {
                "token": "svp10",
                "startOffset": 0,
                "endOffset": 5,
                "position": 0
            },
            {
                "token": "nor",
                "startOffset": 6,
                "endOffset": 9,
                "position": 1
            },
            {
                "token": "00",
                "startOffset": 10,
                "endOffset": 12,
                "position": 2
            }
        ]
    }
    
  3. Modificare ora la richiesta per usare l'analizzatore whitespace o keyword :

    {
    "text": "SVP10-NOR-00",
    "analyzer": "keyword"
    }
    
  4. Questa volta, la risposta è costituita da un singolo token, con maiuscole e minuscole, con trattini mantenuti come parte della stringa. Se è necessario cercare un criterio o un termine parziale, ad esempio "10-NOR", il motore di query ora ha la base per trovare una corrispondenza.

    {
    
        "tokens": [
            {
                "token": "SVP10-NOR-00",
                "startOffset": 0,
                "endOffset": 12,
                "position": 0
            }
        ]
    }
    

Importante

Tenere presente che i parser di query spesso termini minuscoli in un'espressione di ricerca durante la compilazione dell'albero delle query. Se si usa un analizzatore che non inserisce input di testo in lettere minuscole durante l'indicizzazione e non si ottengono risultati previsti, questo potrebbe essere il motivo. La soluzione consiste nell'aggiungere un filtro token minuscolo, come descritto nella sezione "Usare analizzatori personalizzati" di seguito.

3 - Configurare un analizzatore

Indipendentemente dal fatto che si stia valutando gli analizzatori o si stia procedendo con una configurazione specifica, sarà necessario specificare l'analizzatore nella definizione del campo ed eventualmente configurare l'analizzatore stesso se non si usa un analizzatore predefinito. Quando si scambiano gli analizzatori, in genere è necessario ricompilare l'indice (eliminare, ricreare e ricaricare).

Usare analizzatori predefiniti

Gli analizzatori predefiniti possono essere specificati per nome in una analyzer proprietà di una definizione di campo, senza alcuna configurazione aggiuntiva necessaria nell'indice. Nell'esempio seguente viene illustrato come impostare l'analizzatore whitespace in un campo.

Per altri scenari e per altre informazioni su altri analizzatori predefiniti, vedere Analizzatori predefiniti.

    {
      "name": "phoneNumber",
      "type": "Edm.String",
      "key": false,
      "retrievable": true,
      "searchable": true,
      "analyzer": "whitespace"
    }

Usare analizzatori personalizzati

Se si usa un analizzatore personalizzato, definirlo nell'indice con una combinazione definita dall'utente di tokenizer, filtro di token, con possibili impostazioni di configurazione. Fare quindi riferimento a tale definizione in una definizione di campo, proprio come si farebbe con un analizzatore predefinito.

Quando l'obiettivo è la tokenizzazione a termine intero, è consigliabile un analizzatore personalizzato costituito da un tokenizzatore di parole chiave e da un filtro token minuscolo.

  • Il tokenizzatore di parole chiave crea un singolo token per l'intero contenuto di un campo.
  • Il filtro del token minuscolo trasforma le lettere maiuscole in testo minuscolo. I parser di query in genere minuscoli in qualsiasi input di testo maiuscolo. La combinazione di maiuscole e minuscole omogeneizza gli input con i termini con token.

L'esempio seguente illustra un analizzatore personalizzato che fornisce il tokenizer di parole chiave e un filtro token minuscolo.

{
"fields": [
  {
  "name": "accountNumber",
  "analyzer":"myCustomAnalyzer",
  "type": "Edm.String",
  "searchable": true,
  "filterable": true,
  "retrievable": true,
  "sortable": false,
  "facetable": false
  }
],

"analyzers": [
  {
  "@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
  "name":"myCustomAnalyzer",
  "charFilters":[],
  "tokenizer":"keyword_v2",
  "tokenFilters":["lowercase"]
  }
],
"tokenizers":[],
"charFilters": [],
"tokenFilters": []
}

Nota

Il keyword_v2 tokenizer e lowercase il filtro token sono noti al sistema e usano le relative configurazioni predefinite, motivo per cui è possibile farvi riferimento in base al nome senza dover prima definirli.

4 - Compilare e testare

Dopo aver definito un indice con analizzatori e definizioni di campo che supportano lo scenario, caricare documenti con stringhe rappresentative in modo da poter testare query di stringa parziali.

Usare un client REST per eseguire query su termini parziali e caratteri speciali descritti in questo articolo.

Le sezioni precedenti illustrano la logica. Questa sezione illustra ogni API che è necessario chiamare durante il test della soluzione.

  • Elimina indice rimuove un indice esistente con lo stesso nome in modo da poterlo ricreare.

  • Crea indice crea la struttura di indice nel servizio di ricerca, incluse le definizioni dell'analizzatore e i campi con una specifica dell'analizzatore.

  • Caricare documenti importa i documenti con la stessa struttura dell'indice, nonché il contenuto ricercabile. Dopo questo passaggio, l'indice è pronto per eseguire query o test.

  • L'analizzatore di test è stato introdotto in Impostare un analizzatore. Testare alcune delle stringhe nell'indice usando vari analizzatori per comprendere come vengono tokenizzati i termini.

  • I documenti di ricerca illustrano come costruire una richiesta di query usando una sintassi semplice o una sintassi Lucene completa per le espressioni regolari e con caratteri jolly.

    Per le query con termini parziali, ad esempio l'esecuzione di query su "3-6214" per trovare una corrispondenza in "+1 (425) 703-6214", è possibile usare la sintassi semplice: search=3-6214&queryType=simple.

    Per le query di prefisso e suffisso, ad esempio l'esecuzione di query su "num" o "numeric per trovare una corrispondenza in "alfanumerico", usare la sintassi Lucene completa e un'espressione regolare: search=/.*num.*/&queryType=full

Ottimizzare le prestazioni delle query

Se si implementa la configurazione consigliata che include il tokenizer di keyword_v2 e il filtro token minuscolo, è possibile notare una diminuzione delle prestazioni delle query a causa dell'elaborazione aggiuntiva del filtro dei token sui token esistenti nell'indice.

Nell'esempio seguente viene aggiunto un EdgeNGramTokenFilter per rendere più veloci le corrispondenze di prefisso. I token vengono generati in combinazioni di caratteri da 2 a 25 che includono caratteri. Ecco un esempio di progressione da due a sette token: MS, MSFT, MSFT, MSFT/, MSFT/S, MSFT/SQ, MSFT/SQL.

La tokenizzazione aggiuntiva comporta un indice più grande. Se si dispone di capacità sufficiente per supportare l'indice più grande, questo approccio con tempi di risposta più rapidi potrebbe essere la soluzione migliore.

{
"fields": [
  {
  "name": "accountNumber",
  "analyzer":"myCustomAnalyzer",
  "type": "Edm.String",
  "searchable": true,
  "filterable": true,
  "retrievable": true,
  "sortable": false,
  "facetable": false
  }
],

"analyzers": [
  {
  "@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
  "name":"myCustomAnalyzer",
  "charFilters":[],
  "tokenizer":"keyword_v2",
  "tokenFilters":["lowercase", "my_edgeNGram"]
  }
],
"tokenizers":[],
"charFilters": [],
"tokenFilters": [
  {
  "@odata.type":"#Microsoft.Azure.Search.EdgeNGramTokenFilterV2",
  "name":"my_edgeNGram",
  "minGram": 2,
  "maxGram": 25,
  "side": "front"
  }
]
}

Passaggi successivi

Questo articolo illustra in che modo gli analizzatori contribuiscono sia ai problemi di query che a risolvere i problemi di query. Come passaggio successivo, esaminare più in dettaglio gli analizzatori influiscono sull'indicizzazione e sull'elaborazione delle query.