IBM Cloud Docs
Guida di riferimento per AQL (Annotation Query Language)

Guida di riferimento per AQL (Annotation Query Language)

AQL (Annotation Query Language) è il linguaggio primario utilizzato per creare estrattori di regole avanzati IBM Watson® Knowledge Studio.

  • Modello dati: il modello di dati per AQL è simile al modello relazionale standard utilizzato da un database SQL come DB2®. Tutti i dati in AQL sono memorizzati in tuple, record di dati di una o più colonne o campi. Una raccolta di tuple forma una vista. Tutte le tuple in una vista devono avere lo stesso schema, ossia i nomi e i tipi dei campi in tutte le tuple.
  • Modello di esecuzione: il componente di runtime ha un modello di esecuzione di un documento per volta. Il componente di runtime riceve una raccolta di documenti ed esegue l'estrattore su ciascun documento per estrarre le informazioni da tale documento.
  • Istruzioni AQL: utilizzando le istruzioni AQL, puoi creare e quindi utilizzare moduli, viste, tabelle, dizionari e funzioni.
  • Funzioni integrate: AQL dispone di una raccolta di funzioni integrate per l'utilizzo nelle regole di estrazione.
  • L'istruzione create function: per eseguire operazioni sui valori estratti che non sono supportati da AQL, puoi definire delle funzioni personalizzate da utilizzare nelle regole di estrazione denominate UDF (user-defined functions).

Sintassi di AQL (Annotation Query Language)

Come molti linguaggi di programmazione, AQL è basato su sintassi e grammatica comuni.

La struttura lessicale di un linguaggio di programmazione è l'insieme di regole elementari che definiscono i token o i componenti di base di tale linguaggio come ad esempio le sue parole riservate, i suoi identificativi, le sue costanti e altro ancora.

La sintassi di AQL è simile a quella di SQL ma esistono diverse differenze importanti:

  • AQL è sensibile a maiuscole/minuscole

  • AQL attualmente non supporta le funzioni SQL avanzate quali le sottoquery correlate e le query ricorsive.

  • AQL ha un nuovo tipo di istruzione, extract, che non è presente in SQL.

  • AQL non consente le parole chiave (parole riservate) come nomi di vista, colonna o funzione.

  • AQL consente, ma non richiede, che le espressioni regolari siano espresse in sintassi Perl. Le espressioni regolari iniziano con una barra (/) e terminano con una barra (/), come nella sintassi Perl. AQL consente anche delle espressioni regolari che iniziano con un singolo segno di quotazione (') e terminano con un solo segno di quotazione ('). Ad esempio, è possibile utilizzare /regex/ invece di 'regex' come espressione regolare in AQL.

  • Identificativi: gli identificativi vengono utilizzati per definire i nomi degli oggetti AQL, compresi i nomi di moduli, le viste, le tabelle, i dizionari, le funzioni, gli attributi e i parametri di funzione.

  • Parole riservate: le parole riservate sono parole che hanno un significato fisso nel contesto della struttura AQL e non possono essere ridefinite. Le parole chiave sono parole riservate che hanno significati speciali nella sintassi del linguaggio.

  • Costanti: le costanti sono valori fissi che possono essere uno di questi tipi di dati: String, Integer, Float o Boolean.

  • Commenti" Utilizza i commenti per ampliare il codice AQL con descrizioni di base per aiutare gli altri utenti a comprendere il codice e per generare moduli compilati autodescrittivi.

  • Espressioni: un'espressione AQL è una combinazione di uno o più funzioni e valori scalari che dà come risultato un singolo valore scalare.

Identificativi

Gli identificativi vengono utilizzati per definire i nomi degli oggetti AQL, compresi i nomi di moduli, le viste, le tabelle, i dizionari, le funzioni, gli attributi e i parametri di funzione.

Esistono due tipi di identificativi AQL sensibili a maiuscole/minuscole.

  • Identificativo semplice

    Un identificativo semplice deve iniziare con una lettera minuscola (a-z) o maiuscola (A-Z) o il carattere di sottolineatura (_). I caratteri successivi possono essere minuscoli o lettere maiuscoli, il carattere di sottolineatura o le cifre (0-9). Un identificativo semplice deve essere diverso da qualsiasi parola chiave AQL.

  • Identificativo tra virgolette doppie

    Un identificativo a doppio citato inizia e termina con un doppio carattere di virgolette ("). È possibile utilizzare qualsiasi carattere tra l'inizio e la fine della doppia virgoletta caratteri. Gli identificativi tra virgolette doppie non possono contenere un carattere punto (.). Se all'interno del nome è presente un carattere di virgolette doppie, è necessario eseguirne l'escape antecedendo ad esso un carattere di barra rovesciata (\), ad esempio \”.

Parole riservate

Le parole riservate sono parole che hanno un significato fisso nel contesto della struttura AQL e non possono essere ridefinite. Le parole chiave sono parole riservate che hanno significati speciali nella sintassi del linguaggio.

Le seguenti parole chiave riservate per AQL non possono essere utilizzate come identificativi perché ciascuna di esse ha uno scopo ben definito all'interno del linguaggio:

  • all
  • allow
  • allow_empty
  • always
  • and
  • annotate
  • as
  • ascending
  • ascii
  • attribute
  • between
  • blocks
  • both
  • by
  • called
  • case
  • cast
  • ccsid
  • character
  • characters
  • columns
  • consolidate
  • content\_type
  • count
  • create
  • default
  • descending
  • detag
  • detect
  • deterministic
  • dictionary
  • dictionaries
  • document
  • element
  • else
  • empty\_fileset
  • entries
  • exact
  • export
  • external
  • external_name
  • extract
  • fetch
  • file
  • first
  • flags
  • folding
  • from
  • function
  • group
  • having
  • import
  • in
  • include
  • infinity
  • inline_match
  • input
  • into
  • insensitive
  • java
  • language
  • left
  • lemma_match
  • like
  • limit
  • mapping
  • matching_regex
  • minus
  • module
  • name
  • never
  • not
  • null
  • on
  • only
  • order
  • output
  • part_of_speech
  • parts_of_speech
  • parameter
  • pattern
  • point
  • points
  • priority
  • regex
  • regexes
  • retain
  • required
  • return
  • right
  • rows
  • select
  • separation
  • set
  • specific
  • split
  • table
  • tagger
  • then
  • token
  • Token
  • tokens
  • unicode
  • union
  • up
  • using
  • values
  • view
  • views
  • when
  • where
  • with

Le seguenti parole riservate sono i nomi di tipi scalari integrati:

  • Text
  • Span
  • Integer
  • Float
  • String
  • Boolean
  • ScalarList

I seguenti altri nomi riservati non possono essere utilizzati come identificativi:

  • Dictionary
  • Regex
  • Consolidate
  • Block
  • BlockTok
  • Sentence
  • Tokenize
  • RegexTok
  • PosTag

Costanti

Le costanti sono valori fissi che possono essere uno di questi tipi di dati: String, Integer, Float o Boolean.

Le costanti sono utilizzate nell'elenco di selezione (select) di una clausola select o extract oppure come argomenti in funzioni e predicati integrati o UDF. AQL supporta i seguenti tipi di costanti:

  • Costante stringa

    Una stringa racchiusa tra virgolette singole (‘), ad esempio ‘una stringa’.

  • Costante Integer

    Un valore numerico intero con segno a 32 bit che non è racchiuso tra virgolette, ad esempio 10 o -1.

  • Costante Float

    Un valore a virgola mobile a 32 bit e a singola precisione, non racchiuso tra virgolette, ad esempio 3.14 o -1.2.

  • Costante Boolean

    Il valore true o false non racchiuso tra virgolette.

  • Costante Null

    Il valore null che non è racchiuso tra virgolette.

Commenti

Utilizza i commenti per ampliare il codice AQL con descrizioni di base per aiutare gli altri utenti a comprendere il codice e per generare moduli compilati autodescrittivi.

I commenti consentono agli sviluppatori AQL di ampliare il codice AQL con descrizioni di base per facilitare la comprensione del codice sorgente AQL e di generare moduli AQL compilati autodescrittivi. In AQL sono supportati tre tipi di commenti:

  • Commenti a riga singola

    I commenti a riga singola iniziano con i trattini doppi (--).

  • Commenti a più righe

    I commenti a più righe iniziano con una barra e un asterisco (/*) e terminano con un asterisco e una barra (*). I commenti a più righe non possono essere nidificati. Ad esempio, il seguente commento a più righe nidificato non è consentito:

    /*
    A comment with a /*nested comment*/
    */
    
  • Commenti AQL Doc

    I commenti AQL Doc forniscono un modo per descrivere un modulo oppure un oggetto AQL in testo semplice e in un modo articolato per una comprensione contestuale da parte degli altri utenti. A differenza dei commenti a riga singola e a più righe, che sono ignorati dal compilatore AQL, i commenti AQL Doc sono serializzati nei metadati dei moduli compilati (file .tam) e disponibili per un utilizzo esterno.

    Tutti i commenti in AQL Doc per le istruzioni e i moduli hanno il seguente formato:

    • Il commento è in testo semplice (non è supportata alcuna tag HTML).

    • Il commento inizia con una barra di avanzamento seguita da due asterischi (/**) e termina con una barra di avanzamento asterisco (*/). Facoltativamente, ogni riga può iniziare con un asterisco (*).

    • Prima dell'asterisco può essere utilizzato qualsiasi numero di spazi vuoti.

    • Delle tag speciali precedute da un simbolo chiocciola (@) possono essere utilizzate all'inizio di ogni riga o dopo l'asterisco facoltativo.

    • I commenti AQL Doc non possono essere nidificati. Sono supportati due livelli di granularità all'interno del sistema AQL Doc. Il formato per documentare ogni risorsa utente è spiegato in modo dettagliato nell'argomento che ne descrive l'istruzione e la sintassi.

    • Commenti a livello di modulo

      I commenti a livello di modulo sono contenuti all'interno di un file speciale denominato module.info che si trova direttamente nella cartella del modulo. Si prevede che i commenti descrivano la semantica del modulo e lo schema della vista Document del modulo.

    • Commenti a livello di istruzione

      I commenti a livello di istruzione sono contenute nel file AQL di origine, immediatamente prima dell'istruzione che crea un oggetto AQL. I commenti a riga singola e a più righe sono consentiti tra il commento AQL Doc di un'istruzione e l'istruzione stessa.

      Le seguenti istruzioni AQL di livello superiore possono essere documentate utilizzando i commenti AQL Doc:

      • L'istruzione create external view
      • L'istruzione create external table
      • L'istruzione create external dictionary
      • La funzione create
      • L'istruzione detag
      • L'istruzione select... into I commenti AQL Doc sono serializzati all'interno della rappresentazione compilata di un modulo.

Espressioni

Un'espressione AQL è una combinazione di uno o più funzioni e valori scalari che dà come risultato un singolo valore scalare.

Le espressioni possono essere di uno di questi quattro tipi:

  • una costante
  • un riferimento colonna
  • una chiamata di funzione scalare
  • una chiamata di funzione aggregata

Costante

Un'espressione può essere una costante di tipo Integer, Float o String, come nel seguente esempio:

select 'positive' as polarity

L'espressione è la costante stringa positive.

Riferimento colonna

Un'espressione può essere un riferimento colonna, come nel seguente esempio:

create view Person as
select F.name as firstname, L.name as lastname
from FirstName F, LastName L
where FollowsTok(F.name, L.name, 0, 0);

Questa vista identifica il testo che può essere interpretato come il nome completo di una persona (ad esempio, “Samuel Davis”, “Vicky Rosenberg”). Le espressioni F.name e L.name sono espressioni di riferimento colonna che restituiscono, rispettivamente, la colonna del nome delle viste F e L,. L'istruzione from definisce le viste F e L come nomi locali per le viste FirstName e LastName (che definiscono nomi e cognomi validi e non sono visualizzati in questo esempio).

Chiamata di funzione scalare

Un'espressione può essere composta da una o più chiamate di funzione scalare, ognuna delle quali potrebbe contenere argomenti che sono anche espressioni di tipo chiamata di funzione scalare, riferimento colonna o costante. Una chiamata di funzione scalare può essere una delle funzioni scalari integrate oppure una funzione definita dall'utente scalare. Considera il seguente esempio:

create view FamilyMembers as
    select ToLowerCase(GetText(P.lastname)) as lastname, List( (GetText(P.firstname))) as firstnames
    from Person P
    group by GetText(P.lastname);

Questa vista identifica potenziali membri della famiglia raggruppando le persone con gli stessi cognomi e stampando tutti i nomi, con i cognomi in caratteri minuscoli (ad esempio, lastname keaton, firstnames (Elyse, Alex, Diane)). Gli output delle chiamate di funzione GetText vengono utilizzati come argomenti per la chiamata di funzione ToLowerCase per visualizzare i nomi in minuscolo. Le espressioni di chiamata di funzione scalar in questo esempio sono ToLowerCase, (GetText(P.lastname), ToLowerCase(GetText(P.firstname)) e GetText(P.lastname).

Chiamata di funzione aggregata

Un'espressione può essere una chiamata di funzione aggregata. Questo tipo di espressione può avere come argomenti un'altra espressione di tipo riferimento colonna o di tipo chiamata di funzione scalare. Il seguente esempio mostra una chiamata di funzione aggregata con il tipo di espressione riferimento colonna:

create view CountLastNames as
select Count(Person.lastname)
from Person;

L'espressione è semplicemente Count(Person.lastname) e conta il numero di annotazioni Person.lastname nel documento. Un esempio di una chiamata di funzione aggregata con il tipo di espressione chiamata di funzione scalare esiste nell'esempio precedente come List(GetText(P.firstname)) con la funzione aggregata List che prende una funzione scalare GetText come un argomento per generare un elenco di nomi di battesimo. Le espressioni di chiamata di funzione aggregata sono consentite come espressioni solo nell'elenco select di un'istruzione select. Le espressioni di chiamata di funzione aggregata non sono consentite nell'elenco select di un'istruzione extract o come argomenti per una chiamata di funzione scalare o aggregata.

Modello dati

Il modello di dati per AQL è simile al modello relazionale standard utilizzato da un database SQL come DB2®. Tutti i dati in AQL sono memorizzati in tuple, record di dati di una o più colonne o campi. Una raccolta di tuple forma una vista. Tutte le tuple in una vista devono avere lo stesso schema, ossia i nomi e i tipi dei campi in tutte le tuple.

Il contenuto del documento di input è rappresentato come una vista speciale denominata Document.

I campi di una tupla devono appartenere a uno dei tipi di dati integrati di AQL:

  • Booleano

    Un tipo di dati che ha un valore true o false.

  • Float

    Un numero a virgola mobile e a singola precisione.

  • Numero intero

    Un numero intero con segno a 32 bit.

  • ScalarList

    Una raccolta di valori dello stesso tipo scalare (Integer, Float, Text o Span). Un valore di tipo di dati ScalarList può essere ottenuto come risultato della funzione aggregata integrata AQL List() o come risultato di una UDF.

  • Span

    Una Span è un intervallo, ossia una regione contigua di un oggetto Text, identificata dai suoi offset di inizio e fine nell'oggetto Text. Supponiamo che il tuo testo di input sia:

    Amelia Earhart is a pilot.
    

    Il testo nell'ambito dell'intervallo (Span) [0-6] è Amelia.

    Questo intervallo (Span) può essere visualizzato come:

    0A1m2e3l4i5a6
    

    Analogamente, il testo nell'ambito dell'intervallo (Span) [20-25] è pilot.

    Una Span di [x-x] rappresenta l'intervallo (span) tra la fine di un carattere e l'inizio del carattere successivo. Nell'esempio precedente, [ 0-0 ] è una stringa vuota prima del carattere A. Allo stesso modo, una Span di [ 3-3 ] è una stringa vuota tra i caratteri e e l.

    Un valore di tipo Span può essere ottenuto come risultato di un'istruzione extract, una funzione scalare integrata o una UDF.

  • Testo

    Il tipo di dati AQL per rappresentare una sequenza di caratteri. Un oggetto Text contiene una stringa Unicode, che è indicata come suo valore stringa. Quando una stringa è formata come una concatenazione di sottostringhe disgiunte di un altro oggetto Text, contiene anche un riferimento all'oggetto Text originale e le informazioni di associazione di offset pertinenti. Gli oggetti Text sono considerati uguali tra loro se tutti i loro componenti sono corrispondentemente uguali tra loro.

  • Confronto di valori di tipo Span e Text I fattori di prioritizzazione influenzano i confronti tra i valori di tipo Span e di tipo Text.

Confronto di valori di tipo Span e Text

I fattori di prioritizzazione influenzano i confronti tra i valori di tipo Span e di tipo Text.

I valori di tipo Span e di tipo Text si mettono a confronto tra loro in questi modi:

  • Un valore Span null viene sempre ordinato più in basso rispetto ad altri valori.
  • Un valore Text viene sempre ordinato più in altro di un valore span.
  • I valori di tipo Text sono ordinati prima in base all'ordine lessicale dei loro valori stringa quindi in base ai loro ordini testuali originali e alle loro informazioni di associazione di offset, se applicabili.
  • I valori di tipo Span sono ordinati prima in base ai loro oggetti testuali sottostanti, quindi in base al loro offset di inizio e quindi in base al loro offset di fine. L'intervallo (span) con un offset di inizio più piccolo viene ordinato più in basso. Tra due intervalli (span) che iniziano allo stesso offset, quello con l'offset di fine più piccolo viene ordinato più in basso.

Modello di esecuzione

Il componente di runtime ha un modello di esecuzione di un documento per volta. Il componente di runtime riceve una raccolta di documenti ed esegue l'estrattore su ciascun documento per estrarre le informazioni da tale documento.

Un estrattore consiste in uno o più moduli AQL per creare una raccolta di viste. ciascuna delle quali definisce una relazione. Alcune di queste viste sono designate come viste di output, mentre altre sono viste non di output. Le viste non di output possono includere alcune viste che vengono importate in, o esportate da, un modulo. È importante notare che le viste di output e le viste esportate sono ortogonali. Ad esempio, una vista che viene esportata non si qualifica come una vista che sia di output. Oltre a queste viste, la vista Document univoca rappresenta il documento di input annotato da questo estrattore.

Document Visualizza

A livello di modulo AQL, la vista Document è una vista speciale che rappresenta il documento corrente di cui tale modulo sta eseguendo l'annotazione. Quando due o più moduli vengono combinati per formare un estrattore, l'unione priva di duplicati di schemi Document di tutti i moduli è la vista Document richiesta. Utilizza l'istruzione require document with columns per specificare lo schema della vista Document. Se questa istruzione è assente in un modulo, lo schema predefinito che viene presunto per la vista Document è (text Text, label Text):

  • text

    Il contenuto testuale del documento corrente.

  • label

    L'etichetta del documento corrente di cui è in corso l'annotazione.

La parola chiave Document è riservata come un identificativo per la vista Document, che viene automaticamente popolata durante l'esecuzione. Non puoi pertanto definire un'altra vista o tabella con lo stesso nome. Puoi tuttavia utilizzare la parola Document come un identificativo per alias e nomi di attributo.

Istruzioni AQL

Utilizzando le istruzioni AQL, puoi creare e quindi utilizzare moduli, viste, tabelle, dizionari e funzioni.

Le seguenti istruzioni sono supportate in AQL:

  • Istruzioni per creare moduli e dichiarare l'interazione tra loro

    L'istruzione module

    L'istruzione export

    L'istruzione import

  • Istruzioni per creare funzioni, tabelle, dizionari, viste od oggetti AQL

    Istruzioni create dictionary e create external dictionary

    Istruzione create table

    Istruzione create view

    Istruzione create external view

    Istruzione detag

    Istruzione extract

    Istruzione select

    Istruzione require document with columns

    Istruzione set default dictionary language

    Istruzione create function

Le specifiche di sintassi nelle istruzioni AQL contengono parentesi ([ ]). Queste specifiche indicano che le staffe e i costrutti che detengono sono facoltativi quando la sintassi corrispondente viene utilizzata per scrivere un comunicato. Inoltre, fungono da segnaposti per definire in che modo specificare istruzioni aggiuntive di un costrutto o un argomento.

Istruzione module

Utilizza l'istruzione module per creare un modulo che ha le risorse richieste indipendenti. Puoi esportare e importare queste risorse come oggetti AQL verso e da altri moduli.

Sintassi

module <module-name\>;

Descrizione

  • <module-name\>

    Dichiara che il file corrente fa parte del modulo che si chiama <module-name\>. Il nome del modulo deve essere un identificativo semplice. Gli identificativi tra virgolette doppie non sono consentiti come nomi di modulo.

    Ogni file AQL all'interno del modulo deve avere esattamente una singola dichiarazione di modulo e questa dichiarazione deve essere la prima istruzione in ciascun file. Questa dichiarazione stabilisce uno spazio dei nomi identico al nome del modulo. Tutte le viste (e altri oggetti quali dizionari, tabelle e funzioni) dichiarate nei file AQL all'interno di questo modulo si trovano all'interno di questo singolo spazio dei nomi. Sono accessibili a tutti i file AQL in questo spazio dei nomi.

    Tutti i file dichiarati come parte del modulo <module-name\> devono essere all'interno di una cartella che si chiama <module-name\> per far rispettare questo namespace. Non esiste alcun ordinamento dei file AQL all'interno di questa cartella del modulo. Il compilatore AQL esamina tutti i file AQL del modulo e determina l'ordine corretto di compilazione di tutte le viste, le funzioni, le tabelle e i dizionari dichiarati nel modulo.

Note d'utilizzo

  • Quando il file AQL sottostante non viene individuato come parte di un modulo (AQL modulare) e viene compilato in modalità di compatibilità, questa istruzione non è supportata.
  • Le dipendenze circolari tra le viste non sono consentite.
  • I moduli AQL non supportano i moduli secondari.
  • I file AQL all'Interno delle cartelle secondarie della cartella del modulo di livello superiore vengono ignorati.

Esempi

Esempio 1: Modulo di esempio

Nel seguente esempio, la vista TheMentions appartiene al modulo denominato sample.

module sample;

create dictionary GetTheDict as ('The', 'the');

create view TheMentions as
  extract dictionary 'GetTheDict' on D.text as theMention
  from Document D;

Istruzione export

L'istruzione export in AQL viene utilizzata per esportare un oggetto AQL dal modulo corrente in modo che possa essere importato e utilizzato in altri moduli.

Sintassi

export view|dictionary|table|function <object-name\>;

Descrizione

  • view|dictionary|table|function

    Definisce il tipo di oggetto da esportare. Il tipo di oggetto può essere una vista, un dizionario, una tabella o una funzione.

  • <object-name\>

    Definisce il nome dell'oggetto da esportare. Il <object-name\> può essere un identificativo semplice o un identificativo a doppio quotato.

Note d'utilizzo

  • Non puoi esportare gli oggetti AQL importati. Puoi creare l'effetto di riesportazione della vista o della tabella nel modulo corrente creando una nuova vista:

    select * from <imported_view_name_or_table_name>;
    
  • Le istruzioni export view e output view mostrate negli esempi sono ortogonali tra loro. In altre parole, una vista di output non è automaticamente una vista esportata ma deve essere esportata esplicitamente utilizzando un'istruzione export. Una vista esportata non è automaticamente una vista di output ma ne deve essere eseguito l'output in modo esplicito utilizzando l'istruzione output view. Negli esempi, l'istruzione export tenta di esportare la vista PersonName.FirstName, che è una vista importata. Questo tentativo causa un errore, il che significa che lo sviluppatore deve invece copiare la vista importata in una nuova vista e quindi esportare quest'ultima.

Esempi

Esempio 1. Creazione di viste e dizionari e loro successiva esportazione per l'utilizzo in altri moduli

Questo esempio crea le viste FirstName e NotFirstName. La vista FirstName raccoglie informazioni sui nomi di battesimo rappresentati nel dizionario FirstNamesDictionary. L'altra vista raccoglie i nomi che rimangono quando escludi i nomi di battesimo. Sono necessari due dizionari per semplificare l'estrazione di testo. Un dizionario contiene tutti i nomi di battesimo che vuoi cercare. Il secondo dizionario, LastNamesDictionary, contiene i cognomi da cercare. Il dizionario FirstNamesDictionary è esportato in modo da poter essere utilizzato in altri moduli. Le viste FirstName e NotFirstName vengono anche esportate in modo da poter essere importate e utilizzate in altri moduli, come ad esempio il modulo person nell'Esempio 2.

module personName;

create dictionary FirstNamesDictionary as
('Smith', 'John', 'Mary', 'Sam', 'George');

-- export dictionary statement

export dictionary FirstNamesDictionary;


create view FirstName as
  extract dictionary 'FirstNamesDictionary'
  on D.text as firstName
from Document D;

-- export view statement

export view FirstName;

create dictionary LastNamesDictionary as
('Stewart', 'Johnson', 'Smith', 'Hopkins', 'George');

create view NotFirstName as
  select F.firstName as notFirstName from FirstName F
  where ContainsDict('LastNamesDictionary', F.firstName);

-- export view statement

export view NotFirstName;

Esempio 2: Importazione di viste da utilizzare, ma esportazione eseguita in modo inappropriato, con conseguente condizione di errore

Questo esempio mostra l'importazione delle due viste. Queste viste sono state esportate dal modulo personName nell'Esempio 1. La persona del modulo può ora importare e fare riferimento a quelle viste. Tuttavia, questo modulo prova a esportare la stessa vista che ha importato, FirstName, e ciò causa una condizione di errore.

module person;

-- Form 1

import view FirstName from module personName as PersonFirstName;

-- Form 2

import view NotFirstName from module personName;


-- ERROR
-- Reason: A view that is imported from one module
-- cannot be exported in the current module.
export view personName.FirstName;


output view PersonFirstName;

Il motivo dell'errore in questo codice è che una vista che viene importata da un modulo non può essere esportata nel modulo corrente. Inoltre, le viste esportate non sono automaticamente delle viste di output a meno che tu non abbia definito una vista di output con l'istruzione output view.

Istruzione import

Puoi utilizzare l'istruzione import per fare riferimento a oggetti esportati da altri moduli nel contesto del modulo corrente.

Sintassi

import view|dictionary|table|function <object-name\>
     from module <module-name\> [as <alias\>];

Descrizione

  • view\|dictionary\|table\|function

    Identifica il tipo di oggetto AQL da importare. Il tipo dell'oggetto è obbligatorio.

  • <object-name\>

    Il <object-name\> può essere un identificativo semplice o un identificativo a doppio quotato.

  • <module-name\>

    Il <module-name\> deve essere un identificativo semplice.

  • <alias\>

    Questo modulo dell'istruzione di importazione, noto anche come alias import, importa l'oggetto AQL specificato sotto il nome <alias\> (non il nome originale) nello spazio dei nomi del modulo corrente. Puoi fare riferimento all'elemento importato utilizzando un alias non qualificato oppure un alias qualificato con il nome modulo corrente (il modulo dove era stato importato l'oggetto AQL). Non puoi utilizzare originalModule.elementName perché l'istruzione alias import importa l'elemento solo sotto il nome alias e non sotto il nome originale qualificato.

Note d'utilizzo

  • Un'istruzione di importazione senza una specifica di alias importa l'oggetto AQL specificato nel modulo corrente. Rende l'oggetto AQL accessibile alle istruzioni AQL definite nel modulo corrente con il suo nome qualificato <original\_module\_name\>.<object-name\>.

  • L'istruzione di importazione viene utilizzata solo per importare oggetti AQL dai moduli diversi dal modulo corrente. Un oggetto dichiarato in un file AQL del modulo è visibile a qualsiasi altro file AQL nello stesso modulo. Un'istruzione di importazione mette gli oggetti nel contesto del modulo corrente e non nel contesto del file corrente. Pertanto, una vista importata da 1.aql all'interno del modulo A è resa visibile a 2.aql all'interno dello stesso modulo senza che siano necessarie ulteriori istruzioni di importazione.

  • Tutte le istruzioni di importazione devono seguire immediatamente la dichiarazione del modulo e devono precedere tutti gli altri tipi di istruzioni. Solo gli oggetti AQL esportati esplicitamente da qualsiasi modulo possono essere importati in un altro modulo. Se questo requisito non viene rispettato, si verifica un errore di compilazione.

  • Un errore di compilazione viene introdotto quando un'istruzione import view introduce un conflitto di denominazione con qualsiasi istruzione create view o altre istruzioni di importazione all'interno dello stesso modulo (non solo all'interno del file corrente). Questa limitazione si applica all'importazione (import) di altri oggetti oltre alle viste.

  • Il compilatore AQL rispetta le convenzioni di denominazione utilizzate nelle versioni precedenti di AQL.

    • Un modulo non può contenere una vista e una tabella con lo stesso nome.
    • È consentito un dizionario con lo stesso nome di una tabella o di una vista.
    • È consentita una funzione con lo stesso nome di una tabella, di una vista o di un dizionario.
  • Un errore di compilazione viene introdotto quando diverse istruzioni di importazione in uno o più file AQL nel modulo danno lo stesso nome a oggetti AQL differenti.

  • Un errore di compilazione viene introdotto quando un file AQL all'interno di un modulo prova a fare riferimento a un'altra vista esportata di un modulo senza utilizzare l'istruzione import view. Il nome si applica a dizionari, tabelle o funzioni.

  • Quando due file AQL all'interno di un modulo importano la stessa vista X da un altro modulo sotto due alias differenti, ad esempio A e B, i due alias vengono trattati come se fossero sinonimi. Questa regola si applica a tabelle, dizionari e funzioni.

Esempi

Esempio 1: Creare viste che si esportano per essere importati in altri moduli.

Questo esempio crea due viste, FirstName e NotFirstName. La vista FirstName raccoglie le informazioni relative ai nomi indicati che sono rappresentati nel dizionario FirstNamesDictionary . La seconda vista raccoglie i nomi che rimangono quando escludi i nomi di battesimo. Sono necessari due dizionari per semplificare l'estrazione di testo. Un dizionario contiene tutti i nomi di battesimo che vuoi cercare. Il secondo dizionario, LastNamesDictionary, contiene i cognomi da ricercare. Le viste FirstName e NotFirstName vengono esportate in modo che possano essere importate e utilizzate in altri moduli, quali il modulo person negli esempi 2 e 3.

module personName;

create dictionary FirstNamesDictionary as
('Smith', 'John', 'Mary', 'Sam', 'George');

create view FirstName as
extract dictionary 'FirstNamesDictionary'
on D.text as firstName
from Document D;

export view FirstName;

create dictionary LastNamesDictionary as
('Stewart', 'Johnson', 'Smith', 'Hopkins', 'George');

create view NotFirstName as
select F.firstName as notFirstName from FirstName F
where ContainsDict('LastNamesDictionary', F.firstName);

export view NotFirstName;

Esempio 2. Importazione della vista FirstName utilizzando alias import

Questo esempio importa una delle viste create ed esportate nell'Esempio 1. Poi, la vista PersonFirstName è in uscita in modo che i suoi risultati possano essere visualizzati.

L'istruzione import di esempio è nota come alias import. Importa la vista FirstName, senza alcun qualificatore di modulo, nello spazio dei nomi del modulo corrente, person. La vista importata è accessibile solo mediante il nome alias PersonFirstName e non mediante qualsiasi altro formato. Ad esempio, non puoi fare riferimento alla vista importata come personName.FirstName perché viene importata solo mediante il nome alias.

module person;

`import view FirstName from module personName as PersonFirstName;`

output view PersonFirstName;

Esempio 3. Importazione della vista NotFirstname senza utilizzare alias import

Questa istruzione import di esempio importa il nome qualificato name personName.NotFirstName (non il nome non qualificato della vista) nello spazio dei nomi del modulo corrente, person. Fai sempre riferimento alla vista importata utilizzando solo il nome qualificato. Qualsiasi altra modalità di riferimento viene contrassegnata come un errore del compilatore.

module person;

`import view NotFirstName from module personName;`


output view personName.NotFirstName;

Istruzione import module

Puoi utilizzare l'istruzione import module per importare e riutilizzare moduli AQL esistenti.

Sintassi

 import module <module-name\>;

Descrizione

  • <module-name\>

    Specifica il modulo da importare. Il <module-name\> deve essere un identificativo semplice.

Note d'utilizzo

  • L'istruzione di importazione viene utilizzata solo per importare oggetti AQL da altri moduli, non dal modulo corrente.

  • Tutte le istruzioni di importazione devono seguire immediatamente la dichiarazione del modulo e devono precedere tutti gli altri tipi di istruzioni. Solo gli oggetti AQL esportati esplicitamente da qualsiasi modulo possono essere importati in un altro modulo. Se questo requisito non viene rispettato, si verifica un errore di compilazione.

  • Un errore di compilazione viene introdotto quando un'istruzione import view introduce un conflitto di denominazione con qualsiasi istruzione create view o altre istruzioni di importazione all'interno dello stesso modulo (non solo all'interno del file corrente). Questa limitazione si applica all'importazione (import) di altri oggetti AQL oltre alle viste.

  • Un errore di compilazione viene introdotto quando un file AQL all'interno di un modulo prova a fare riferimento a un'altra vista esportata di un modulo senza utilizzare l'istruzione import view. Il nome si applica a dizionari, tabelle o funzioni.

  • Se due file AQL all'interno di un modulo importano la stessa vista X da un altro modulo sotto due alias differenti, ad esempio A e B, i due alias vengono trattati come se fossero sinonimi. Questa regola si applica a tabelle, dizionari e funzioni.

Esempi

In questo esempio, l'istruzione import importa il nome qualificato di entrambe le viste esportate, personName.FirstName e personName.NotFirstName. Qualsiasi vista che non viene esportata dal modulo personName non viene importata come parte dell'istruzione di importazione

  • Esempio 1. Importa entrambe le viste FirstName e NotFirstName

    Questo esempio mostra tutte le viste esportate dal modulo personName. Le viste FirstName e NotFirstName sono state create nella sezione di esempio dell'istruzione di esportazione.

    module personOther;
    
    -- The following statement would import both views FirstName and NotFirstName.
    import module personName;
    

Istruzione set default dictionary language

L'istruzione set default dictionary language consente a uno sviluppatore dell'estrattore di personalizzare l'insieme predefinito di lingue corrispondenti al dizionario per il modulo di contenimento.

Sintassi

 set default dictionary language as '<language codes\>';

Descrizione

  • <language codes\>

    Specifica la lingua per la compilazione e la corrispondenza per i dizionari del moduli dichiarati senza un'esplicita specifica with language as. Il set <language codes\> deve essere un elenco separato da virgola, senza spazi bianchi intorno ad ogni codice lingua. Il mancato rispetto di questo requisito può causare un errore di compilazione.

    Questa istruzione interessa i seguenti dizionari:

    • I dizionari dichiarati esplicitamente nel modulo corrente utilizzando l'istruzione create dictionary oppure l'istruzione create external dictionary e tale istruzione non ha una clausola with language as.
    • I dizionari da file esterni.
    • In una specifica di modello di un'istruzione extract pattern , gli atomi di tipo 'string' e gli atomi di tipo <'string' [match parameters]> senza una specifica with language as esplicita. Quando questa dichiarazione è assente dall'interno di un modulo, il componente di runtime viene impostato per default su una serie linguistica di tedesco, spagnolo, inglese, francese, italiano e la lingua non specificata x. È definito come un insieme: [de,es,en,fr,it,x_unspecified]. All'interno di un modulo, può esistere solo una singola istanza di questa istruzione.

Note d'utilizzo

  • L'istruzione set default dictionary language può essere aggiornata per migliorare l'estensione di lingue coperte dall'estrattore. Questa capacità di aggiungere lingue favorisce la facilità di personalizzazione e il riutilizzo di estrattori esistenti.

Esempi

Esempio 1. Specifica di lingue da utilizzare per la messa in corrispondenza di voci del dizionario

module Dictionaries;

-- Set the default dictionary matching language
--  for this module to English and French

set default dictionary language as 'en,fr';


/**
* Dictionary of English and French names. Because no language clause
* exists in dictionary definition, module level dictionary matching
* setting will be applied.
*/

create dictionary EnglishFrenchNames
from file 'en_fr_names.dict';

/**
* Dictionary of Italian names. Language clause in the dictionary
* definition will override the module level dictionary matching setting.
*/

create dictionary ItalianNames
with language as 'it'
as
(
'firstEntry','secondEntry'
);


/**
* View to extract pattern: Phone, followed by one to three tokens,
* followed by Email. Language clause at the atom level will override
* the module level dictionary setting.
*/

create view PhoneEmailPattern as
extract pattern <'Phone'[ with language as 'en']>
  <Token> {1,3} 'Email'
as match
from Document D;

output view PhoneEmailPattern;

Istruzione require document with columns

Utilizzando l'istruzione require document with columns, puoi definire lo schema della vista speciale Document in fase di compilazione. Questa definizione di schema specifica l'elenco di campi obbligatori e i loro tipi da trovare in ciascuna tupla della vista Document.

Sintassi

require document with columns  <columnName\> <columnType\>
     [and <columnName\> <columnType\>]*;

Descrizione

  • <columnName\>

    Specifica il nome della colonna da utilizzare nello schema. Il <columnName\> è un identificativo di attributo, che è un identificativo semplice o un identificativo a doppio quotato.

  • <columnType\>

    Specifica il tipo di colonna da utilizzare nello schema della vista Document. Il <columnType\> può essere uno dei seguenti tipi di dati: Integer, Float, Boolean o Text.

  • [ and <columnName\> <columnType\> ]*

    Specifica nomi colonna e tipi aggiuntivi per lo schema della vista Document. Seguono le stesse regole di <columnName\> e <columnType\>.

Nelle versioni precedenti di AQL, lo schema della vista speciale Document è stato predefinito per consistere in un singolo campo (text Text) o due campi (text text, label Text). La scelta tra questi schemi è stata decisa al runtime. Utilizzando l'istruzione require document with columns, puoi sovrascrivere lo schema del documento di input predefinito in fase di compilazione.

Note d'utilizzo

  • Per il codice AQL modulare, l'ambito di qualsiasi istruzione require document with columns è il modulo in cui ne è eseguita la definizione.
  • È consentita solo una singola istruzione require document with columns per ogni file AQL. In un singolo modulo, o un modulo generico, ci possono essere zero, uno o più file AQL che hanno un'istruzione require document with columns. Tutti i file AQL in un modulo uniscono le loro istruzioni require document with columns al livello dell'intero modulo per formare una require document with columns a livello di modulo. Questa istruzione definisce lo schema della vista Document per tale modulo. Se nessuno dei file AQL di un modulo o un modulo generico contiene un'istruzione require, il modulo ha lo schema predefinito per la vista Document. Questo schema consiste di due colonne: (text Text, label Text). Non vengono stabilite colonne predefinite per la vista speciale Document se almeno un file AQL nel modulo ha un'istruzione require document with columns.
  • Quando più moduli vengono combinati per formare un estrattore, lo schema della vista Document dell'intero estrattore è definito dall'unione senza duplicati di schemi Document per ogni modulo. Viene generata un'eccezione quando viene rilevato che una colonna presente nelle molteplici istruzioni require document with columns è in conflitto nei suoi requisiti di tipo nei moduli. Ad esempio, un modulo richiede una colonna X con il tipo Y quando un altro modulo di cui è in corso il caricamento con esso richiede una colonna X con il tipo Z.
  • Viene generata un'eccezione quando esegui un estrattore se la tupla del documento di input fornita non contiene tutte le colonne richieste. Viene generata un'eccezione anche se una colonna non è conforme al suo tipo richiesto corrispondente.
  • Quando l'istruzione require document with columns è presente all'interno di un modulo, ogni colonna della vista speciale Document a cui si fa riferimento deve essere dichiarata in almeno una delle istruzioni require document with columns. L'istruzione può essere trovata in diversi file AQL all'interno dello stesso modulo. Tuttavia, tutte queste istruzioni require document with columns verranno unite al livello del modulo per formare un'istruzione require document with columns a livello di modulo.

Esempi

Esempio 1: Istruzione require document con tipi di colonna simili

Il seguente esempio definisce uno schema di documento che contiene quattro campi dello stesso tipo. Questo esempio AQL prevede che ciascuna tupla di documento della raccolta di dati contenga quattro colonne, come definito nello schema di documento.

Fai riferimento ai formati del documento JSON per i dettagli su come creare un documento conforme a uno schema.

module person;

-- Require document statement with similar field types

require document with columns
  inputDocumentText Text
  and inputDocumentLabel Text
  and documentAuthor Text
  and documentCreationDate Text;

Esempio 2: istruzione require document con tipi di colonna diversi

Il seguente esempio definisce uno schema di documento che contiene colonne di diversi tipi di campo:

module sample;

-- Require document statement with varying field types

require document with columns
  bookText Text
  and purchaseCount Integer
  and bookPrice Float
  and isBookPopular Boolean;

Esempio 3: Unione di schemi di documento

L'esempio descrive come unire gli schemi di documento che utilizzano i file first.aql, last.aql e socialsecurity.aql.

first.aql:
    module person;
    require document with columns firstName Text;


last.aql:
    module person;
    require document with columns lastName Text;


socialsecurity.aql
    module person;
    require document with columns lastName Text
        and socialSecurityNo Integer;

Lo schema unito è (firstName Text, lastName Text, socialSecurityNo Integer).

Istruzione create view

I componenti di livello superiore di un estrattore AQL sono le sue viste. Le viste sono istruzioni logiche che definiscono, ma non necessariamente calcolano, una serie di tuple.

Sintassi

L'istruzione create view può assumere uno di tre possibili formati. Il formato più semplice definisce una vista logica composta dalle tuple di una singola istruzione select o extract. Il secondo è un formato a unione multipla che definisce una vista che comprende le tuple generate dall'unione multi-insieme di diverse istruzioni select o extract. Il terzo formato definisce una nuova vista che contiene la differenza tra set tra le tuple da due istruzioni select o extract.

create view <viewname\> as  <select or extract statement\>;
create view <viewname\> as  (<select or extract statement\>) union all (<select or extract statement\>)...;
create view <viewname\> as  (<select or extract statement\>) minus (<select or extract statement\>);

Descrizione

  • <viewname\>

    Il <viewname\> può essere un identificativo semplice o un identificativo a doppio quotato. Non può contenere il carattere punto.

  • <select or extract statement\>

    L'istruzione select o extract crea l'output utilizzato per calcolare le tuple della vista di contenimento.

Note d'utilizzo

  • I nomi vista sono sensibili a maiuscole/minuscole. Ad esempio, Person, PERSON e person sono nomi vista differenti
  • Due viste all'interno dello stesso modulo AQL non possono condividere un nome poiché ciò li renderebbe duplicati. Tuttavia, due viste con lo stesso nome possono esistere in due moduli differenti poiché i loro nomi completi sono univoci.
  • Per impostazione predefinita, una vista definita dall'istruzione create view è una vista non di output fino a quando non viene specificata come una vista di output.
  • Le istruzioni select o extract dei formati union all e minus devono avere uno schema di output compatibile. Due schemi sono considerati compatibili per un'operazione union o minus se hanno lo stesso numero di colonne, i nomi delle colonne sono nello stesso ordine e hanno tipi di dati compatibili:
    • I campi dello stesso tipo di dati sono compatibili con union o minus.
    • I tipi di dati Span e Text sono compatibili con union o minus. Nel caso di un'unione tra un tipo Span e un tipo Text, il tipo di output è uno Span. Tuttavia, gli oggetti di tipo Text non vengono convertiti automaticamente in un tipo Span – la conversione automatica avviene solo quando richiesta dalle chiamate di funzione.
    • Due ScalarLists sono compatibili con union o minus indipendentemente dal tipo scalare sottostante.

Esempi

Esempio 1: Creazione di una vista con un'istruzione select o extract

Nell'esempio di seguito, la vista Phone utilizza un'istruzione extract per preparare le sue tuple. La vista PhoneNumber utilizza un'istruzione select per scegliere i campi specifici dalla vista Phone.

create view Phone as extract
  regexes /\+?([1-9]\d{2}\)\d{3}-\d{4}/
  and /\+?[Xx]\.?\d{4,5}/
  on D.text as num
from Document D;

create view PhoneNumber as
select P.num as num, LeftContextTok(P.num, 3) as lc
from Phone P;

Esempio 2: Creazione di una vista con l'istruzione union all

La vista AllPhoneNums prepara un insieme riunito dalle tuple delle viste Phone e Extension. Le due viste che vengono riunite hanno lo stesso schema.

create view Phone as
extract
    regex /\+?([1-9]\d{2}\)\d{3}-\d{4}/
    on D.text as match
from Document D;

create view Extension as
  extract
    regex /\+?[Xx]\.?\d{4,5}/
    on D.text as match
from Document D;

create view AllPhoneNums as
  (select P.match from Phone P)
union all
  (select E.match from Extension E);

Esempio 3: Creazione di una vista con l'istruzione minus

Il seguente esempio mostra come puoi utilizzare minus per escludere mediante filtro le tuple indesiderate da una serie di tuple.

create view Organization as
  (select * from OrganizationCandidates)
minus
  (select * from InvalidOrganizations);

Esempio 4: Compatibilità di schema per minus

È importante notare che gli intervalli (span) su testo di destinazione differente non sono dello stesso tipo. Prendiamo in considerazione il seguente esempio AQL che spiega la differenza utilizzando un valore letterale String.

create view OneString as
  select 'a string' as match
  from Document D;

create view TheSameString as
  select 'a string' as match
  from Document D;

create view Subtraction as
  (select R.match from OneString R)
minus
  (select R.match from TheSameString R);

Invece dell'output previsto di un elenco di tuple vuoto, l'output è una serie di record che hanno 'a string' come un valore di campo.

Anche se il contenuto delle viste OneString e TheSameString sembra identico, i valori testuali effettivi hanno degli oggetti AQL sottostanti differenti. Il tipo di OneString.match è 'Span over OneString.match'. Il tipo di TheSameString.match è 'Span over TheSameString.match'. Poiché i tipi di campo sono differenti, non sono compatibili per finalità di messa a confronto.

Per ottenere l'output desiderato di elenco di tuple vuoto, devi mettere a confronto valori dello stesso tipo. Nel seguente esempio, la funzione GetString() converte gli oggetti span in oggetti string per passare tipi compatibili all'operazione minus.

create view Subtraction as
(select GetString(R.match) from OneString R)
minus
(select GetString(R.match) from TheSameString R);

Documentazione dell'istruzione create view con AQL Doc

Il commento AQL Doc per un'istruzione create view contiene le seguenti informazioni:

  • Descrizione generale relativa alla vista.
  • @field per ogni nome colonna nella vista.

Esempio

/**
* Extracts all spans that match a phone number pattern from
* the input documents. It uses a regular expression to match
* phone number patterns.
* @field num phone number
* @field lc 3 tokens to the left of phone number*/

create view PhoneNumber as
select P.num as num, LeftContextTok(P.num, 3) as lc
from
(
extract
    regexes /\+?([1-9]\d{2}\)\d{3}-\d{4}/ and /\+?[Xx]\.?\d{4,5}/
    on D.text as num
from Document D
) P;

Istruzione output view

L'istruzione output view definisce una vista perché sia una vista di output. Il componente di runtime genera in output solo le tuple delle viste contrassegnate come viste di output. Il compilatore AQL compila solo le viste contrassegnate come output o export oppure raggiungibili dalle viste contrassegnate come output o export.

Sintassi

output view <view-name\> [as '<alias\>'];

Descrizione

  • <view-name\>

    Il nome della vista da generare in output, come noto nello spazio dei nomi del modulo corrente. Il <view-name\> è un identificativo semplice o un identificativo doppio citato. La vista integrata Document non può essere generata in output.

  • [as '<alias\>']*

    Definisce un nome <alias\> per la vista di output. Quando l'alias facoltativo non è specificato, la vista viene generata in output sotto i seguenti nomi:

    • In modulare AQL, la vista è in uscita con il nome <module-name\>.<view-name\> dove <module-name\> è il nome del modulo in cui la vista è originariamente definita (che può essere diversa dal modulo in cui la vista è in uscita).
    • In AQL 1,4 o precedente la vista è in uscita con il nome <view-name\> L'istruzione output ... as <alias\> è utile quando si personalizza un estrattore per diversi domini. L'utilizzo del nome <alias\> quando si definisce una vista di output garantisce che i nomi di output siano identici attraverso diverse implementazioni della personalizzazione.

    Il nome <alias\> non può essere utilizzato in un'altra istruzione select o export . È necessario racchiudere il <alias\> con virgolette singole e il nome <alias\> può contenere periodi.

Note d'utilizzo

  • Quando un estrattore AQL viene eseguito, calcola le tuple risultati per ciascuna vista definita come una vista di output. Vengono calcolate anche le tuple di qualsiasi vista non di output ma solo quando sono necessarie per calcolare le tuple risultati di una vista di output.
  • In AQL modulare, l'istruzione output view genera in output le tuple della vista sotto il nome vista completo che è qualificato dal suo nome del modulo. Prendiamo in considerazione il seguente esempio, in cui l'istruzione output view Person; determina la generazione in output della vista personModule.Person:
module personModule;

create view Person as
  extract dictionary 'FamousPeopleDict' on D.text as match
  from Document D;

output view Person;

Questa modalità di funzionamento si applica per qualsiasi output di vista senza un alias, indipendentemente dal fatto che la vista sia generata in output nel modulo in cui è definita o un modulo in cui è importata, anche quando è importata utilizzando un alias import. Ad esempio, nella vista di output MyPerson, questo esempio determina la generazione in output della vista sotto il suo nome qualificato originale personModule.Person e non sotto il suo alias locale MyPerson

module employeeModule;

import view Person from module personModule as MyPerson;

output view MyPerson;
  • L'istruzione alias di output è utile quando crei librerie di estrattori in cui lo stesso tipo di entità può avere molte implementazioni differenti, a seconda del dominio dell'applicazione o della lingua dei documenti di input. Il vantaggio principale derivante dall'utilizzo di un alias quando definisci una vista di output è garantire una nomenclatura congruente nelle viste di output. Una nomenclatura congruente è prevista dalla logica del programma di un utente quando elabori più moduli e ciascuno genera in output una vista semanticamente simile. In AQL modulare, quando viene utilizzato un nome alias in un'istruzione output view, le tuple di una vista sono generate in output sotto il nome alias specificato. Ad esempio, il seguente codice genera in output i risultati sotto il nome alias PersonAlias e il nome alias non è qualificato con il prefisso di modulo.
module personModule;

create view Person as
  extract dictionary 'FamousPeopleDict' on D.text as match
  from Document D;

output view Person as 'PersonAlias';

Esempi

I seguenti esempi contengono due moduli, personModuleFrench e personModuleEnglish. Ogni modulo genera in output una vista, denominate PersonNameFrench e PersonNameEnglish. Supponiamo dei moduli simili e che ognuno di essi generi in output delle viste che sono delle varianti semantiche di un estrattore per i nomi di persona. Questi moduli sono personalizzati per lingue differenti con la varianza nella personalizzazione di questa vista per una specifica lingua di input. Alla fine, un utente potrebbe volere un programma per utilizzare i moduli in cui la vista di output desiderata è denominata PersonName, indipendentemente dai moduli elaborati. Questa aspettativa è normale poiché è previsto che ogni modulo personalizzato per una lingua, un dominio o un altro scopo produca diversi risultati. L'utilizzatore di questi moduli non ha bisogno di modificare l'algoritmo del suo programma in modo da tener conto di nomi di vista di output variabili quando la semantica sottostante è simile.

Nell'esempio, poiché viene utilizzato l'alias PersonName, l'utilizzatore non ha bisogno di modificare il nome della vista desiderato. Tuttavia, i risultati potrebbero variare a seconda dei moduli elaborati. Nell'esempio, a titolo esemplificativo, le corrispondenze risultanti sono basate sul francese (Esempio 1) e basate sull'inglese (Esempio 2).

Esempio 1: Le corrispondenze risultanti sono basate sul francese

Il seguente esempio definisce una vista PersonNameFrench e ne esegue la generazione in output sotto un nome alias indipendente dall'implementazione, 'PersonName'.

module personModuleFrench;

create dictionary FrenchNames as
  ('Jean', 'Pierre', 'Voltaire', 'Francois', 'Marie', 'Juliette');

create view PersonNameFrench as
  extract dictionary 'FrenchNames'
  on D.text as name
  from Document D;

output view PersonNameFrench as 'PersonName';

Esempio 2: Le corrispondenze risultanti sono basate sull'inglese

Il seguente esempio definisce una vista PersonNameEnglish e ne esegue la generazione in output sotto un nome alias indipendente dall'implementazione, 'PersonName'.

module personModuleEnglish;

create dictionary EnglishNames as
  ('John', 'Peter', 'Andrew', 'Francis', 'Mary', 'Juliet');

create view PersonNameEnglish as
  extract dictionary 'EnglishNames'
  on D.text as name
  from Document D;

output view PersonNameEnglish as 'PersonName';

L'utilizzatore dei moduli di esempio può accedere alle tuple di output mediante il nome alias 'PersonName'. L'utilizzatore non avrà bisogno di conoscere il modulo effettivo da cui vengono recuperati i risultati.

Istruzione extract

L'istruzione extract viene utilizzata per estrarre le funzioni di base direttamente dal testo.

Sintassi

extract <select list>,
  <extraction specification>
from <from list>
[having <having clause>]
[consolidate on <column> [using '<policy>']]
[limit <maximum number of output tuples for each document>];

Descrizione

  • <select list\>

    Un elenco delimitato da virgole di espressioni di output. I risultati di queste espressioni di output vengono restituiti come output dell'istruzione extract, insieme alle tuple generate dalla valutazione della specifica di estrazione. Il formato per il <select list\> è lo stesso del <select list\> di un'istruzione select .

  • <extraction specification\>

    Applica la specifica di estrazione su tutti i tupli dalle viste definite nel <from list\>. Rinomina le colonne di tuple in base ai loro corrispondenti alias che sono specificati nell'istruzione extract . Puoi utilizzare una delle seguenti specifiche di estrazione:

    • Espressioni regolari
    • Dizionari
    • Suddivisioni
    • Blocchi
    • Parte del discorso
    • Modelli di sequenza
  • <from list\>

    Un elenco delimitato da virgole che è l'origine delle tuple da cui devono essere selezionate le funzioni. Il formato del <from list\> è simile al formato dell' <from list\> dell'istruzione select . Tuttavia, se l'istruzione extract non ha una specifica di modello, allora il <from list\> può contenere un singolo elemento.

  • [having <having clause\>]

    Specifica un predicato di filtraggio (nel <having clause\>) applicato ad ogni tupla di output estratto. I nomi di campo specificati nel <having clause\> si riferiscono ad eventuali alias specificati nel <select list\>. Questa clausola è facoltativa.

  • [consolidate on <column\>[using '<policy\>' ]]

    Definisce come gestire gli spans sovrapposti come definiti nel consolidamento <policy\>. In questa specifica, <column\> deve essere il nome di un campo di output, che fa parte dell'istruzione extract . Questa clausola è facoltativa.

  • [limit<maximum number of output tuples for each document\>]

    Limita il numero di tuple di output da ciascun documento al massimo specificato. Questa clausola è facoltativa.

Note d'utilizzo

La semantica dell'istruzione extract è la seguente:

  • Valuta la specifica di estrazione su ciascuna tupla della relazione di input. Per ogni risultato che l'estrazione produce, viene prodotta una tupla in uscita che contiene i valori estratti, insieme ad eventuali colonne della tupla originale che sono state specificate nel <select list\>.
  • Rinominare le colonne della tupla in uscita in base agli alias specificati come parte del <select list\> e del <extraction specification\>.
  • Applica gli eventuali predicati nella clausola having facoltativa nella tupla di output risultante.
  • Consolida le tuple che passano i predicati in base alla clausola consolidation facoltativa e aggiungi le tuple risultanti all'output.
  • Se è presente la clausola limit facoltativa, limita l'output al numero specificato di tuple per ciascun documento.

La semantica della clausola from di un'istruzione extract pattern è diversa dagli altri formati delle istruzioni extract che non hanno una specifica di modello. Se almeno una delle viste in <from list\> non contiene tupli su un determinato documento, allora l'output dell'istruzione extract è vuoto. Questo output è vuoto perché l'insieme di tutte le combinazioni di tuple nelle viste di input è vuoto.

Nel caso speciale di istruzioni extract pattern, la clausola from è un segnaposto che dichiara i nomi delle relazioni coinvolte nella specifica di modello. La semantica dell'istruzione è basata solo sulla specifica di modello. In particolare, l'output dell'istruzione può essere non vuoto anche quando qualcuna delle viste di input è vuota.

Esempi

Esempio 1: Estrazione di numeri telefonici da una vista predefinita

Questa istruzione di estrazione di esempio valuta un'espressione regolare per i numeri telefonici degli Stati Uniti nel testo di input rappresentato dalla vista predefinita Document. L'output viene quindi ristretto ai primi tre numeri telefonici identificati per ciascun documento. I nomi campo nella clausola having fanno riferimento agli alias all'inizio dell'istruzione extract.

create view PhoneNumbers as
  extract
    D.text as documentText,
    regex /\d{3}-\d{3}-\d{4}/ on D.text as phoneNumber
from Document D
having MatchesRegex(/\d{3}.*/, phoneNumber)
limit 3;

Esempio 2: Estrazione di blocchi di parole in maiuscolo

In questo esempio, l'istruzione extract identifica i blocchi di due a tre parole in maiuscolo. In AQL, un blocco si riferisce a un intervallo (span) contiguo di token, in questo caso da due a tre token. Questo esempio utilizza anche una politica di consolidamento per escludere i blocchi contenuti all'interno di blocchi più grandi dall'insieme di output delle tuple.

create view CapitalizedWord as
  extract
    regex /[A-Z][a-z]*/
            with flags 'CANON_EQ'
        on 1 token in D.text
        as word
from Document D;

create view TwoToThreeCapitalizedWords as
  extract blocks
  with count between 2 and 3
  and separation 0 tokens
  on CW.word as capswords
from CapitalizedWord CW
consolidate on capswords using 'ContainedWithin';

La clausola consolidate viene applicata al campo capswords dalla specifica extract blocks. La differenza è che il campo di destinazione a cui fa riferimento la clausola consolidation è un campo di output dell'istruzione extract. Il campo di destinazione dell'istruzione select è un campo di input. Questa modalità di funzionamento è simile a quella della clausola having.

Esempio 3: Un'istruzione extract o select nidificata come un nome vista

La vista di input per un'istruzione extract può essere un nome vista, come nell'Esempio 2, oppure un'istruzione extract o select come in questo esempio:

create view SampleExtract as
  extract
  regex /foo/ on E.foobar as foo
  from
    (extract regex /foobar/ on D.text as foobar
  from Document D) E;

Esempio 4: Estrazione di un'istruzione con un elenco di selezione (select)

In questo esempio, estraiamo le corrispondenze per un modello e, al tempo stesso, selezioniamo più attributi dalle viste di input.

create view Person as
  extract.F.first as first, M.initial as middle, L.last as last
          pattern ('Mr.'|'Ms.'|'Miss')? (<F.first> <M.initial>? <L.last>)
                    return group 0 as reference
                    and group 1 as salutation
                    and group 2 as name
  from FirstName F, MiddleInitial M, LastName L;
  • Espressioni regolari Utilizza una specifica di estrazione di espressione regolare per identificare i modelli corrispondenti contenuti dall'espressione regolare nel testo di input.
  • Dizionari Utilizza la specifica di estrazione del dizionario per estrarre le stringhe dal testo di input che sono contenute in un dizionario di stringhe.
  • Suddivisioni Utilizza la specifica di estrazione di suddivisione per suddividere un intervallo (span) di grandi dimensioni in diversi intervalli (span) più piccoli.
  • Blocchi Utilizza la specifica di estrazione di blocchi per identificare i blocchi di intervalli (span) contigui nel testo di input.
  • Parte del discorso Utilizza la specifica di estrazione di parte del discorso per identificare le ubicazioni delle diverse parti del discorso nel testo di input.
  • Modelli di sequenza Utilizza la specifica di estrazione del modello per eseguire la messa in corrispondenza dei modelli in un documento di input e altri intervalli (span) estratti dal documento di input.

Espressioni regolari

Utilizza una specifica di estrazione di espressione regolare per identificare i modelli corrispondenti contenuti dall'espressione regolare nel testo di input.

Sintassi

regex[es] /<regex1>/
         [and /<regex2>/ and ... and /<regex n>/]
       [with flags '<flags string>']
on <token spec>] <name>.<column>
<grouping spec>

Descrizione

  • regex[es] /<regex1\>/

    Specifica le espressioni regolari da utilizzare nell'estrazione. Per impostazione predefinita, AQL utilizza la sintassi Perl per le espressioni regolari, il che significa che i valori letterali di espressione regolare sono racchiusi tra due caratteri barra (//). Le sequenze di escape di espressione regolare hanno la precedenza sugli altri caratteri di escape. AQL consente espressioni regolari nella sintassi di stringa SQL e, pertanto, un'espressione regolare per i numeri telefonici degli Stati Uniti può essere espressa con l'uno o l'altro dei seguenti esempi:

    /\d{3}-\d{5}/
    
    '\\d{3}-\\d{5}'
    
  • [and /<regex2\>/ and ... and /<regex n\>/ ]

    Elenca più espressioni regolari da utilizzare nell'estrazione.

  • [with flags '<flags string\>']

    Specifica una combinazione di indicatori per controllare la messa in corrispondenza di espressioni regolari. Questo parametro è facoltativo. Questi indicatori corrispondono a un sottoinsieme degli indicatori definiti nell'implementazione Java™. Se la stringa di indicatori non viene fornita, AQL utilizza solo l'indicatore DOTALL per impostazione predefinita.

    Per specificare più indicatori, separali con il carattere |. Ad esempio, per specificare una corrispondenza di più righe, una corrispondenza che non sia sensibile a minuscole/minuscole e una uniformazione di tutti i caratteri (case folding) in Unicode, utilizza la stringa di indicatori 'MULTILINE|CASE_INSENSITIVE|UNICODE'.

  • [<token spec\>]

    Indica se mettere in corrispondenza l'espressione regolare solo sui limiti di token.

    ... [[between <number> and] <number> token[s] in] ...
    

    I vincoli di token sono una parte facoltativa della specifica. Se i vincoli di token vengono omessi, AQL restituisce la corrispondenza senza sovrapposizioni più lunga a ciascuna posizione di carattere nel testo di input. Se i vincoli di token sono presenti, l'istruzione extract restituisce la corrispondenza più lunga a ogni limite di token che rientra nell'intervallo specificato di token. Ogni corrispondenza restituita deve iniziare all'inizio di un token e finire alla fine di un token. Se esistono più corrispondenze che si sovrappongono, l'istruzione extract le restituisce tutte.

    Le ubicazioni dei limiti di token dipendono da quale tokenizer il componente di runtime sta utilizzando per tokenizzare il documento. Se il motore sta utilizzando il tokenizer Standard, un token viene definito come una sequenza di caratteri parola o un singolo carattere di punteggiatura.

    Considera, ad esempio, la stringa:

    "The fish are pretty," said the boy.
    

    I limiti di token sono identificati a queste ubicazioni:

    ["][The] [fish] [are] [pretty][,]["] [said] [the] [boy][.]
    
  • <name\>.<column\>

    Il nome vista e il nome colonna su cui viene applicata l'espressione regolare.

  • <grouping spec\>

    Determina come gestire i gruppi di acquisizione nell'espressione regolare. I gruppi di acquisizione sono regioni della corrispondenza dell'espressione regolare identificate da parentesi nell'espressione originale. Ad esempio, l'espressione (fish)(cakes) ha tre gruppi di acquisizione:

    • Il gruppo 0 è l'intera corrispondenza fishcakes.
    • Il gruppo 1 è fish.
    • Il gruppo 2 è cakes. Quando specifichi gli ID gruppo nella clausola di ritorno della sintassi, ciascun ID gruppo deve corrispondere a un gruppo valido all'interno di ciascuna espressione regolare specificata come parte della clausola extract regex nella sintassi.

    Questo è il formato della specifica di raggruppamento:

    return
        group <number> as <name>
        [and group <number> as <name>]*
    

    Per restituire solo il Gruppo 0 (l'intera partita), è possibile utilizzare un formato più breve, alternativo come ad esempio 1. Questo formato equivale a return group 0 as <name>. <name> può essere un identificativo semplice o un identificativo a doppio quotato.

Note d'utilizzo

  • In generale, AQL supporta le stesse funzioni dell'implementazione di espressioni regolari Java 5, come descritto in [Class Pattern: java.util.regex. Il componente di runtime contiene diverse implementazioni di motore di espressioni regolari, compresa l'implementazione integrata di Java. Durante la compilazione, l'ottimizzatore esamina ciascuna espressione regolare e sceglie il motore più rapido che può eseguire l'espressione.

  • I motori di esecuzione alternativi possono avere una semantica leggermente differente per alcuni casi angolari. In particolare, AQL non garantisce l'origine in cui vengono valutate le alternative.

    Supponiamo, ad esempio, che un'istruzione di estrazione corrisponde all'espressione regolare /fish|fisherman/ sul testo 'fisherman'. L'istruzione potrebbe corrispondere a 'fish' o 'fisherman', a seconda di quale motore di espressioni regolari viene utilizzato internamente.

Stringa indicatore AQL Indicatore Java Descrizione
CANON_EQ CANON_EQ Equivalenza canonica: codifiche Unicode differenti dello stesso carattere sono considerate equivalenti.
CASE_INSENSITIVE CASE_INSENSITIVE Esegue una messa in corrispondenza che non è sensibile a maiuscole/minuscole. Per impostazione predefinita, la messa in corrispondenza non sensibile a maiuscole/minuscole presume che solo i caratteri nell'insieme di caratteri US-ASCII siano messi in corrispondenza. La messa in corrispondenza non sensibile a maiuscole/minuscole e che rileva l'Unicode può essere abilitata specificando l'indicatore UNICODE con questo indicatore.
UNICODE UNICODE_CASE Se viene specificata la messa in corrispondenza non sensibile a minuscole/minuscole, utilizza l'uniformazione dei caratteri Unicode per determinare se due caratteri sono equivalenti in una messa a confronto non sensibile a maiuscole/minuscole in un modo che sia congruente con lo standard Unicode. Per impostazione predefinita, la messa in corrispondenza non sensibile a minuscole/minuscole presume che solo i caratteri nell'insieme di caratteri US-ASCII siano messi in corrispondenza. Nota: la modalità di funzionamento di questo indicatore non è definita quando viene utilizzata senza l'indicatore CASE_INSENSITIVE.
DOTALL DOTALL Fare in modo che il carattere dot . corrisponda a tutti i caratteri, incluse le newline.
LITERAL LITERAL Tratta l'espressione come una sequenza di caratteri letterali, ignorando le normali sequenze di escape delle espressioni regolari.
MULTILINE MULTILINE Mette i caratteri ^ e $ in corrispondenza con l'inizio e la fine di qualsiasi riga, a differenza dell'inizio e della fine dell'intero testo di output.
UNIX_LINES UNIX_LINES Tratta solo il carattere di nuova riga di UNIX™ come un'interruzione di riga, ignorando il carattere di ritorno a capo \r.
  • Attieniti alle seguenti linee guida per fare in modo che i tuoi estrattori vengano eseguiti più rapidamente e siano più facili da gestire:
    • Evita espressioni regolari lunghe e complesse e utilizza espressioni regolari più semplici e più piccole che vengono combinate con istruzioni AQL.
    • Evita un uso non necessario di lookahead e lookbehind nelle espressioni regolari. Puoi di norma ottenere lo stesso effetto aggiungendo predicati alla clausola having della tua istruzione di estrazione.
    • Utilizza i vincoli di token nelle tue specifiche di estrazione di espressioni regolari, quando possibile.

Esempi

Esempio 1: Utilizzo dell'equivalente Unicode canonica per determinare le corrispondenze

Questo esempio ti mostra come trovare le parole in maiuscolo che non sono nomi propri. Per determinare le corrispondenze, viene utilizzata l'equivalenza di caratteri Unicode canonica. Nota l'uso dell'indicatore ‘CANON_EQ’ e che regex è eseguito sui token.

create dictionary FirstNamesDict as
  (
  'Aaron', 'Matthew', 'Peter'
  );
create view NotFirstName as
  extract
    regex /[A-Z][a-z]*/
    with flags 'CANON_EQ'
    on 1 token in D.text
    as word
from Document D
  having Not(ContainsDict('FirstNamesDict', word));

Esempio 2: Utilizzo dei gruppi di acquisizione

Il seguente esempio illustra l'utilizzo di gruppi di acquisizione nell'istruzione extract regex. Il codice estrae i campi di un numero telefonico degli Stati Uniti utilizzando i gruppi di acquisizione:

create view Phone as
  extract regex /(\d{3})-(\d{3}-\d{4})/
    on between 4 and 5 tokens in D.text
    return
      group 1 as areaCode
      and group 2 as restOfNumber
      and group 0 as fullNumber
from Document D;

Esempio 3: Applicazione di più regex sul testo di input

Puoi specificare più espressioni regolari nella stessa istruzione extract regex utilizzando la sintassi regexes.

create view PhoneNum as
  extract regexes
    /(\d{3})-(\d{3}-\d{4})/ and /[Xx]\d{3,5}/
        on between 1 and 5 tokens in D.text as num
from Document D;

Esempio 4: Uso non corretto della specifica di raggruppamento

L'espressione regolare in questo esempio di codice non contiene group -1 o group 3000. Ciò causa un errore di compilazione.

create view ErrorExample as
    extract regex /(\d+)/
    on D.text
    return group -1 as wrongGroup and
          group 3000 as nonExistentGroup
from Document D;

Dizionari

Utilizza la specifica di estrazione del dizionario per estrarre le stringhe dal testo di input che sono contenute in un dizionario di stringhe.

Sintassi

    dictionar[y|ies]
        '<dictionary>'
        [and '<dictionary>' and ... and '<dictionary>']
        [with flags '<flags string>']

Descrizione

  • '<dictionary\>'

    Fa riferimento a un dizionario creato utilizzando l'istruzione create dictionary, l'istruzione create external dictionary o un file di dizionario sul file system.

  • [and '<dictionary\>' and ... and '<dictionary\>']

    Fa riferimento a dizionari aggiuntivi da utilizzare per l'estrazione.

  • [with flags'<flags string\>']

    Controlla la messa in corrispondenza dei dizionari. Al momento, sono supportate due opzioni:

    • Esatta

      Fornisce una messa in corrispondenza esatta e sensibile a maiuscole/minuscole.

    • IgnoreCase

      Fornisce una messa in corrispondenza che non è sensibile a maiuscole/minuscole.

Se non è specificato alcun indicatore, il dizionario esegue la messa in corrispondenza in base agli eventuali indicatori specificati durante la sua creazione. Se non viene specificato alcun indicatore durante la creazione, esegue la messa in corrispondenza utilizzando l'indicatore IgnoreCase.

Note d'utilizzo

  • I dizionari sono sempre valutati ai limiti di token. Specificamente, una voce di dizionario corrisponde a una regione di testo se il primo token della voce corrisponde al primo token della regione di testo, il secondo token della voce corrisponde al secondo token della regione di testo e così via. I caratteri tra due token consecutivi vengono ignorati.

    Ad esempio, supponiamo che stiamo utilizzando un semplice modello di tokenizzazione basato sugli spazi vuoti appropriato per una lingua come l'inglese. Supponiamo inoltre che il testo di input sia “Let’s go fishing!” Se un dizionario consiste nel termine go fish, non esiste alcuna corrispondenza nel testo per Let's go fishing!. Tuttavia, se il dizionario consiste nella voce go fishing (nota i due spazi vuoti tra go e fishing), esiste una corrispondenza nel testo Let's go fishing!. Lo spazio vuoto specifica che go e fishing sono due token distinti. Se esistono uno o più caratteri spazio vuoto tra i due token go e fishing nel testo di input, viene effettuata una corrispondenza.

    Per ogni corrispondenza di una voce di dizionario con il testo di input, l'istruzione extract dictionary genera una tupla di output.

Esempi

Esempio 1: Estrazione di termini dai file di dizionario

Trova i nomi di persona utilizzando i file di dizionario di nomi e cognomi comuni con una messa in corrispondenza sensibile a maiuscole/minuscole.

create view Name as
  extract
    dictionaries
        'first.dict'
        and 'last.dict'
    with flags 'Exact'
        on D.text
        as name
from Document D;

Il seguente è del contenuto di esempio di last.dict:

#Dictionary for surnames
Anthony
Aparicio
Cate
Lehmann
Radcliff

Il seguente è del contenuto di esempio di first.dict:

#Dictionary for given names
Aaron
Candra
Freeman
Mathew
Matthew
Zoraida

Nota:

  • Un file system di dizionario a cui si fa direttamente riferimento in un'istruzione extract dictionary non può essere configurato esplicitamente con un insieme di lingue in modo che i dizionari siano compilati e applicati al runtime. l'insieme di lingue viene invece specificato con l'istruzione set default dictionary language se il modulo contiene questa istruzione.

    Pertanto, il riferimento diretto ai file di dizionario in un'istruzione extract dictionary non è consigliato e potrebbe essere abbandonato in futuro. La prassi preferita è quella di definire esplicitamente un oggetto dizionario utilizzando l'istruzione create dictionary from file e utilizzare quindi tale dizionario nell'istruzione di estrazione.

  • Il compilatore e il componente di runtime provano a individuare i file di dizionario a cui si fa riferimento negli AQL nel percorso di ricerca configurato.

Esempio 2: Estrazione di termini da un dizionario inline

Trova le congiunzioni utilizzando un dizionario inline e la messa in corrispondenza predefinita che non è sensibile a maiuscole/minuscole.

create dictionary ConjunctionDict as
  (
    'and', 'or', 'but', 'yet'
  );

create view Conjunction as
  extract
    dictionary 'ConjunctionDict'
        on D.text
        as name
from Document D;

Suddivisioni

Utilizza la specifica di estrazione di suddivisione per suddividere un intervallo (span) di grandi dimensioni in diversi intervalli (span) più piccoli.

Sintassi

split using <name>.<split point column>
    [retain [right|left|both] split point[s]]
    on <name>.<column to split>
    as <output name>

Descrizione

La specifica di estrazione di suddivisione prende due argomenti:

  • Una colonna che contiene intervalli (span) più lunghi di testo.
  • Una colonna che contiene punti di suddivisione.

L'algoritmo di suddivisione funziona in due passaggi sulla vista di input. Il primo passaggio raggruppa tutte le tuple di input in base alla colonna di destinazione. Il secondo passaggio passa attraverso le tuple in ciascun gruppo, suddividendo la colonna di destinazione con ciascun valore della colonna di suddivisione.

  • <name\>.<split point column\>

    Specifica i punti di suddivisione per l'estrazione.

  • [retain [right|left|both] split point[s]]

    Specifica come trattare i punti finali di sinistra e destra di ciascun risultato. Questo argomento è facoltativo.

    • Se viene specificata retain left split point, ogni intervallo (span) di output contiene anche il punto di suddivisione alla sua sinistra, se tale punto di suddivisione esiste.
    • Se viene specificata retain right split point, il sistema fa in modo che ogni intervallo (span) di output contenga il punto di suddivisione alla sua destra.
    • L'estrazione di suddivisione accetta anche i valori null come punti di suddivisione. Per ogni valore di questo tipo, l'estrazione restituisce una tupla che contiene l'intero intervallo (span) di input.
  • <name\>.<column to split\>

    Specifica la colonna di destinazione per l'estrazione.

  • <output name\>

    Definisce il nome dell'output dell'estrazione.

Esempi

Esempio 1: Punti di suddivisione e clausola retain

Se i punti di suddivisione sono tutte le istanze della parola fish nella frase fish are swimming in the fish pond, le diverse versioni della clausola retain hanno i seguenti effetti:

  • retain clause omitted

    " are swimming in the " and " pond"

  • retain right split point

    " are swimming in the fish" and " pond"

  • retain left split point

    "fish are swimming in the " and "fish pond"

  • retain both split points

    "fish are swimming in the fish" and "fish pond"

Esempio 2: Estrazione delle suddivisioni

Questo esempio suddivide il documento in frasi. Utilizza prima un'espressione regolare per identificare i limiti di frase e utilizza quindi la specifica di estrazione di suddivisione per suddividere il testo del documento sui limiti di frase.

create dictionary AbbreviationsDict as
  (
  'Cmdr.',
  'Col.',
  'DR.',
  'Mr.',
  'Miss.');

create view Sentences as
  extract
    split using B.boundary
        retain right split point
        on B.text
        as sentence
  from (
    extract
        D.text as text,
        regex /(([\.\?!]+\s)|(\n\s*\n))/
        on D.text as boundary
        from Document D
    -- Filter the candidate boundaries.
      having Not(ContainsDict('AbbreviationsDict',
            CombineSpans(LeftContextTok(boundary, 1), boundary)))
      ) B;

Blocchi

Utilizza la specifica di estrazione di blocchi per identificare i blocchi di intervalli (span) contigui nel testo di input.

Sintassi

blocks
    with count [between <min\> and] <max\>
    and separation [between 0 and] <max\> (tokens| characters)
    on <name\>.<column containing spans\>
    as <output name\>

Descrizione

  • with count [between<min\> and] <max\>

    Specifica quanti intervalli (span) possono formare un blocco. I valori <min\> e <max\> specificano il numero minimo e massimo di spans che possono effettuare un blocco.

  • [between 0 and] <max\>

    Specifica la distanza di separazione consentita tra gli intervalli (span) prima che non siano più considerati contigui.

  • (tokens| characters)

    Specifica se la distanza di separazione dell'intervallo (span) rappresenta il numero di token o il numero di caratteri.

  • <name\>.<column containing spans\>

    Il nome vista e il nome colonna su cui deve essere applicato l'operatore blocco.

  • <output name\>

    Specifica un nome per l'output dall'operatore blocco.

Note d'utilizzo

  • Se le scansioni di input contengono più blocchi che si sovrappongono negli intervalli (span) di input, un'istruzione di estrazione blocchi restituisce tutti i blocchi possibili. Utilizza il consolidamento per escludere mediante filtro i blocchi ridondanti.
  • Un'istruzione extract con la specifica di estrazione blocchi produce blocchi composti ognuno da un'aggregazione di valori di uno specifico campo da più tuple di input. Pertanto, il suo elenco di selezione (select) non può includere campi dalla sua vista di input.

Esempi

Esempio 1: Estrai blocchi di parole all'interno di un intervallo di caratteri

Nel seguente codice, la vista TwoToThreeCapitalizedWords identifica blocchi di due o tre parole in maiuscolo in 100 caratteri tra loro.

create view CapitalizedWords as
  extract
    regex /[A-Z][a-z]*/
        with flags 'CANON_EQ'
        on 1 token in D.text
        as word
from Document D;

create view TwoToThreeCapitalizedWords as
  extract blocks
    with count between 2 and 3
    and separation between 0 and 100 characters
    on CW.word as capswords
from CapitalizedWords CW;

Esempio 2: Estrai blocchi di parole all'interno di un intervallo di token

Il seguente codice identifica blocchi di esattamente due parole in maiuscolo in cinque token tra loro.

create view TwoCapitalizedWords as
extract blocks
    with count 2
    and separation between 0 and 5 tokens
    on CW.word as capswords
from CapitalizedWords CW;

Parte del discorso

Utilizza la specifica di estrazione di parte del discorso per identificare le ubicazioni delle diverse parti del discorso nel testo di input.

Sintassi

part_of_speech
 '<part of speech spec>'
 [and '<part of speech spec>']*
 [with language '<language code>']
 [and mapping from <mapping table name>]
 on <input column> as <output column\>
 from <input view>

Descrizione

  • '<part of speech spec\>'

    Identifica le parti del discorso da estrarre dal testo di input. Il '<part of speech spec\>' è una delle seguenti stringhe:

    • Una stringa che contiene un elenco delimitato da virgole di tag di parte del discorso generate dal tokenizer multilingue
    • Una combinazione di indicatori e nomi di parte del discorso interni, come definito da una tabella di associazione.
  • [and '<part of speech spec\>']*

    Identifica le parti aggiuntive di tag del discorso per l'estrazione.

  • [with language '<language code\>']

    Specifica la lingua da utilizzare nell'estrazione. Il <language code\> è un codice lingua a due lettere, minuscolo, come 'en' o 'ja'. Se questo argomento viene omesso, si presume che la lingua per l'estrazione di parte del discorso sia l'inglese.

  • [and mapping from <mapping table name\>]

    Specifica il nome di una tabella AQL che associa le tag di parte del discorso non elaborate come ad esempio "NOUN" alle combinazioni di indicatori e parti del discorso di alto livello. Mentre la tabella di associazione può avere dei nomi variabili, una tabella di associazione di parti del discorso deve avere questi nomi colonna:

    • Tag

      La colonna che contiene una tag di parte del discorso del tokenizer multilingue.

    • basetag

      La colonna che contiene la tag interna corrispondente.

    • flagstr

      La colonna che contiene un elenco delimitato da virgole di indicatori associati alla parte del discorso indicata.

    La tabella di associazione deve essere definita utilizzando l'istruzione create table nello stesso modulo dell'istruzione part_of_speech di estrazione che ne fa uso. Non può essere una tabella importata e non può essere una tabella esterna.

    create table POSMapping_EN(tag Text, basetag Text, flagstr Text)
    as values
     ('CCONJ','CONJ','coordinating'),
     ('SCONJ','CONJ','subordinating');
    
  • <input column\>

    Specifica la colonna della vista di input da cui estrarre le informazioni di parte del discorso.

  • <output column\>

    Specifica il nome della colonna dove vengono inviati gli intervalli (span) del token con le parti del discorso indicate.

  • <input view\>

    Specifica la vista di input da cui estrarre le informazioni di parte del discorso.

Note d'utilizzo

  • L'estrazione di parti del discorso funziona solo quando viene utilizzato il tokenizer multilingue. Se il sistema utilizza il tokenizer standard, un'estrazione part_of_speech genera un errore.

Tag di parte del discorso per le lingue

Per tutte le lingue supportate, il tokenizer Multilingue utilizza i tag parte - di - speech elencati nella seguente tabella.

Tag Descrizioni
ADJ aggettivo
ADP apposizione
ADV avverbio
AUX ausiliario
CCONJ congiunzione di coordinamento
DET determinante
INTJ interiezione
NOUN nome
NUM numeri
PART particella
PRON pronome
PROPN nome proprio
PUNCT punteggiatura
SCONJ congiunzione di subordinazione
SYM simbolo
VERB verbo
X altro

Esempi

Esempio 1: Utilizzo di una tag di parte del discorso direttamente in un'istruzione di estrazione

La vista EnglishNoun estrae i nomi inglesi (singolari o di massa) o i nomi propri (singolari).

create view EnglishNoun
as extract parts_of_speech 'NOUN' and 'PROPN'
with language 'en' on D.text
as noun from Document D;

Modelli di sequenza

Utilizza la specifica di estrazione del modello per eseguire la messa in corrispondenza dei modelli in un documento di input e altri intervalli (span) estratti dal documento di input.

Sintassi

La sintassi generale di un modello di sequenza consiste nello specificare prima il modello da mettere in corrispondenza nel testo e poi cosa deve essere restituito dall'estrattore. la parte finale del modello di sequenza specifica qual è l'input per il modello; potrebbe essere una colonna da una vista definita precedentemente oppure potrebbe essere l'intero testo del documento.

pattern <pattern specification> [return clause] [with inline_match on <viewname.colname>]

Descrizione

  • <pattern specification\>

    Un <pattern specification\> è composto da più Atomi. Un singolo Atom può essere una colonna da una vista già definita, una stringa fissa oppure un'espressione regolare. Puoi specificare i tuoi Atom perché siano facoltativi e ripetitivi e specificare le distanze di token tra gli Atom.

    La specifica di modello fa parte di un'istruzione AQL più grande, che include una clausola di estrazione.

    Qui di seguito è riportato un semplice esempio di come creare una vista che contiene tre corrispondenze adiacenti da viste definite in precedenza. In questo esempio, viene restituita l'intera combinazione, che è quello a cui fa riferimento group 0:

    create view Money as
    extract pattern <C.match> <N.match> <Q.match>
    return group 0 as  match
    from Currency C, Number N, Quantifier Q;
    

    Se i tuoi Atom non hanno bisogno di essere esattamente adiacenti l'uno all'altro, puoi utilizzare le distanze di token tra gli Atom per consentire ulteriori corrispondenze. Questo esempio trova le menzioni di persone che seguono in un intervallo compreso tra 0 e 2 token di distanza da un numero telefonico. Notate il costrutto <Token>{0,2} , che indica che è consentito un gap da 0 a 2 token tra la persona e le annotazioni telefoniche.

    create view Phone as
    extract regex /(\d{3})-(\d{3}-\d{4})/
      on between 4 and 5 tokens in D.text
      return
       group 1 as areaCode
       and group 2 as restOfNumber
       and group 0 as fullNumber
    from Document D;
    create view PersonPhone as
    extract
      pattern (<P.name>) <Token>{0,2} (<Ph.fullNumber>)
      return group 0 as match
       and group 1 as person
       and group 2 as phone
    from Person P, Phone Ph;
    

    I costrutti di distanze di token sono limitate a verificarsi all'interno di espressioni di sequenza. Inoltre, ogni distanza di token in una sequenza deve essere preceduta e seguita da un'espressione di "distanza non di token". Di conseguenza, le istruzioni extract pattern producono delle eccezioni:

    -> pattern consisting only of a token gap is an error
    extract pattern <Token> as match from ...
    -> pattern beginning with a token gap is an error
    extract pattern <Token> {0,2} <Ph.phone> as match from ...
    -> pattern ending with a token gap is an error
    extract pattern <P.name> <Token> ?  as match from ...
    -> group consisting only of a token gap is an error
    extract pattern <P.name> (<Token>)  <Ph.phone> as match from ...
    

    Utilizza la sintassi (min,max) per indicare quante volte si ripete ogni Atom. Puoi anche utilizzare la sintassi ? per indicare che un Atom o un Atom ripetuto è facoltativo. Gli Atom, insieme alle loro indicazioni per ripetizione e facoltativo, sono combinati per creare delle sequenze.

    Ecco un esempio più complesso che mostra come ripetere gli elementi. Trova i nomi di hotel candidati identificando le ricorrenze da una a tre parole maiuscole, seguite da un token 'Hotel' o 'hotel'.

    create view CapsWord as
    
    extract
        regex /[A-Z][a-z]*/
           on 1 token in D.text
           as word
    from Document D;
    
    create view HotelCandidate as
    extract
      pattern <CW.word>{1,3} /[Hh]otel/ as hotelname
    from CapsWord CW;
    

    È inoltre possibile utilizzare l'operatore | per indicare una scelta tra Atomi, come in extract pattern <A.match>| <B.match> <C.match> as match from Apple A, Bacon B, Chocolate C;. Questo modello può essere spiegato come “match di un A.match OPPURE una sequenza di un B.match seguito da un C.match. Puoi utilizzare un esempio completo che utilizza l'operatore | nell'Esempio 1.

    Dopo aver creato il tuo pattern, ogni corrispondenza al tuo <pattern specification> costruisce un risultato di output in base alla clausola di ritorno della specifica del pattern, così come l'opzionale <select list> all'inizio dell'istruzione extract . I risultati sono filtrati e consolidati in base alle clausole having, consolidate e limit dell'istruzione extract. Ad esempio, se esistono più corrispondenze che si sovrappongono per la specifica di modello, vengono restituite tutte le possibili corrispondenze e puoi utilizzare una clausola consolidation per escludere mediante filtro gli output ridondanti.

    Considera l'esempio precedente ma ora l'obiettivo è rimuovere le corrispondenze che contengono la parola 'Sheraton' e consolidare le corrispondenze risultanti rimuovendo quelle che sono contenute all'interno di una corrispondenza più grande. Ad esempio, non vogliamo trovare “Best Garden Hotel” e anche “Garden Hotel” nello stesso intervallo (span) di testo.

    create view HotelCandidate as
    extract
      pattern <CW.word>{1,3} /[Hh]otel/ as hotelname
    from CapsWord CW
    having Not(ContainsRegex(/.*Sheraton.*/,hotelname))
    consolidate on hotelname using 'ContainedWithin';
    

Ora che hai dimestichezza con la sintassi e alcuni esempi, questo diagramma delinea la sintassi completa per la specifica di modello. Fai riferimento a questa sintassi completa quando inizi a creare modelli per vedere come strutturare il modello che vuoi creare.

Se hai dimestichezza con le espressioni regolari basate sui caratteri POSIX, riconosci che la sintassi è simile. In questo caso, la sintassi consente spazio vuoto tra gli elementi ed è definito anche cosa può essere un elemento per essere adatto alle finalità di AQL, Nota che il termine Alternation in questo caso significa scelta. L'utilizzo di una barra verticale tra gli elementi indica che esiste una scelta, che può essere raggruppata utilizzando ( ) .

Pattern   -> Alternation
Alternation  -> Sequence | Sequence | ... | Sequence
Sequence   -> Optional Optional ... Optional
Optional   -> Repeat | Repeat ? Repeat     -> Atom | Atom { min, max }
Atom     -> <view_name.column_name>
     'string'
   <'string' [match parameters]>
     /regex/
     <Token>
     Group
Group -> ( Pattern )

Specificamente, un Atom può avere sei formati:

  • <view_name.column_name\>

    Specifica una colonna da uno dei riferimenti funzione tabella, tabella o vista denominati nell'elenco di origine (from) dell'istruzione extract pattern.

  • 'string'

    Specifica una corrispondenza alla stringa specificata utilizzando la semantica di corrispondenza del dizionario predefinita AQL.

  • <'string' [match parameters]\>

    Specifica una corrispondenza alla stringa specificata utilizzando la semantica di corrispondenza del dizionario specificata dai parametri di corrispondenza ([match parameters]). Il formato di [match parameters], per quanto riguarda i caratteri, è (exact | insensitive). Questo formato specifica il tipo di uniformazione dei caratteri che viene utilizzato per determinare le corrispondenze di stringa. Per specificare una corrispondenza esatta sensibile a maiuscole/minuscole, seleziona exact. Per specificare una corrispondenza che non sia sensibile a maiuscole/minuscole, seleziona il valore predefinito insensitive.

  • /regex/

    Specifica una corrispondenza di espressione regolare basata sui caratteri con una corrispondenza vincolata a un singolo token nel testo del documento. Inoltre, la sintassi consente di specificare un costrutto di distanza di token in un'espressione di sequenza per indicare una corrispondenza tra numeri min e max di token.

  • <token\>

    Una corrispondenza per qualsiasi token.

  • [return clause]

    Genera i valori estratti per ciascuna corrispondenza dell'espressione di modello in base alla clausola di ritorno. La clausola return ha la stessa semantica della clausola return in un'istruzione extract regex.

  • [with inline_match on <viewname.colname\>]

    Per gli Atom quali quelli string e regex, la clausola with inline_match determina quale oggetto testuale utilizza il sistema per l'estrazione si stringhe e regex. Ad esempio, se la clausola è with inline_match on Email.subject, tutti i dizionari e tutte le espressioni regolari definite inline nella specifica di modello sono applicate al campo dell'oggetto della vista Email. Se with inline_match è assente, l'estrazione di stringhe ed espressioni regolari viene eseguita per impostazione predefinita sull'intero testo del documento. In questo caso, viewname deve essere il nome di una vista o tabella definita nel modulo corrente oppure importata da un altro modulo; i riferimenti alle funzioni tabella non sono consentite nella clausola with inline_match.

  • [with language as <language code(s)\>]

    Specifica un elenco delimitato da virgole di codici lingua di due lettere, quali en (inglese) o zh (cinese) per le lingue su cui valutare la stringa. Non c'è alcuna corrispondenza sui documenti il cui codice lingua non è contenuto in questa stringa. Se il parametro di lingua viene omesso, la lingua di valutazione viene automaticamente impostata su uno dei seguenti insiemi di lingue:

    • Se è dichiarato, gli insiemi di lingue specificati tramite l'istruzione set default language nel modulo contenitore.
    • Gli insiemi di lingue che contengono tedesco (de), spagnolo (es), inglese (en), francese (fr), italiano (it) e la lingua non specificata (x_unspecified)

Note d'utilizzo

  • La semantica di un'istruzione extract pattern è determinata dalla specifica di modello. Ogni corrispondenza costruisce un risultato di output sulla base della clausola di ritorno della specifica di modello e nonché l'elenco di selezione (select) all'inizio dell'istruzione extract. I risultati sono filtrati e consolidati in base alle clausole having, consolidate e limit dell'istruzione extract. Se esistono più corrispondenze che si sovrappongono per la specifica di modello, un'estrazione di modello genera in output tutte le corrispondenze possibili. Utilizza il consolidamento per filtrare gli output ridondanti.

  • La semantica della clausola from di un'istruzione extract pattern è diversa dagli altri formati delle istruzioni extract che non hanno una specifica di modello. La semantica generale di un'istruzione extract richiede che la specifica di estrazione venga valutata su ogni combinazione delle viste definite nel <from list\>. Se almeno una delle viste presenti nella <from list\> non contiene alcun risultato su un determinato documento, allora l'output dell'estratto estratto è vuoto perché il set di tutte le combinazioni di risultati nelle viste di input è vuoto. Nel caso speciale di istruzioni di modello di estrazione, la clausola from è un segnaposto che dichiara i nomi delle relazioni coinvolte nella specifica di modello. La semantica dell'istruzione è basata solo sulla specifica di modello. In particolare, l'output dell'istruzione può essere non vuoto anche quando qualcuna delle viste di input è vuota.

  • Un'istruzione extract che utilizza l'estrazione di modelli di sequenza può portare in avanti le colonne di qualsiasi vista nell'elenco from ma solo se il nome vista non compare in un elemento ripetuto della specifica di modello. Ad esempio, l'istruzione CapsWordOneToThree determina un errore di compilazione. L'errore si verifica perché la colonna portante CW.type nella parte superiore dell'istruzione extract appartiene al nome della vista CW, che è nell'elemento ripetente <CW.word>{1,3} della specifica del pattern.

    create view CapsWord as
    extract 'UpperCase' as type,
        regex /[A-Z].*/ on 1 token in D.text as word
    from Document D;
    
    ---> This results in and error due to the repeating element CW.word
    create view CapsWordOneToThree as
    extract CW.type as type,
        pattern <CW.word>{1,3} as match
    from CapsWord CW;
    
    output view CapsWordOneToThree;
    

    Per le colonne portate avanti dai nomi vista che appaiono in elementi di alternanza o facoltativi della specifica di modello, il valore della colonna di output è null quando l'alternativa corrispondente o l'elemento facoltativo non è presente nel testo. Un esempio che illustra questo punto è nella vista Person dell'Esempio 1.

  • I gruppi che si verificano in un elemento che si ripete non possono essere generati in output nella clausola return dell'istruzione. Ad esempio, la seguente istruzione causa un'eccezione:

    create view CapsWordOneToThree as
      extract
             pattern (<CW.word>){1,3}
            return group 0 as fullmatch
                   and group 1 as word   -- not allowed due to repeat
      from CapsWord CW;
    

Esempi

Esempio 1: Modello di sequenza con gruppi di acquisizione

L'obiettivo di questo esempio è trovare i nomi persona identificando le ricorrenze del nome proprio, facoltativamente seguito dall'iniziale del secondo nome, seguito da un cognome, e l'intera corrispondenza che è facoltativamente preceduta da un saluto comune. Inoltre, l'estrattore restituisce l'intera corrispondenza come riferimento, il primo gruppo come saluto e il secondo gruppo come denominare e portare avanti i valori del nome di battesimo, iniziale del secondo nome e cognome dalle rispettive viste di input.

create view MiddleInitial as
extract regex /\b([\p{Lu}\p{M}*]\.\s*){1,5}\b/
            on between 1 and 10 tokens in D.text as initial
from Document D;

create view Person as
extract F.first as first,
        M.initial as middle,
        L.last as last,
        pattern ('Mr.'|'Ms.'|'Miss')? (<F.first> <M.initial>? <L.last>)
return group 0 as reference
  and group 1 as salutation
  and group 2 as name
from FirstName F, MiddleInitial M, LastName L;

Poiché l'espressione di modello secondario ('Mr.'|'Ms.'|'Miss')? è facoltativa, il valore della colonna di output salutation è null quando nel testo non è presente un saluto. Analogamente, poiché il modello subexpression <M.initial>? è opzionale, il valore della colonna di output medio è null quando una iniziale di mezzo non è presente.

Esempio 2: Modello di sequenza con corrispondenza stringa e parametri di corrispondenza

L'obiettivo di questo è esempio è trovare ricorrenze delle note di riunione per i progetti noti esaminando le annotazioni di titolo del documento. Nota la clausola with inline_match, che specifica che la corrispondenza di stringa viene eseguita sul campo di corrispondenza della vista Title invece dell'intero testo del documento.

create view Project as
extract
regex /[Pp]roject\s?\w*/ on D.text as name
from Document D;


create view Title as
extract regex /[A-z][a-z]+.*/
on between 1 and 20 tokens in D.text as match
from Document D;


create view MeetingNote as
extract
pattern <'Meeting Notes:'[with case exact]> (<P.name>)
return group 0 as match
  and group 1 as projectname
with inline_match on Title.match
from Project P;

Esempio 3: Modello di sequenza che restituisce risultati non vuoti anche quando una vista di input è vuota

La seguente istruzione genera risultati anche quando la vista di input LastName è vuota. La seconda parte della specifica del modello, <L.name\>? contiene un elemento opzionale. La semantica della specifica di modello è progettata per generare in output tutti gli intervalli (span) composti da un intervallo (span) FirstName.name o un intervallo (span) FirstName.name che è immediatamente seguito da un intervallo (span) LastName.name. Pertanto, sui documenti per cui la vista LastName è vuota, il risultato dell'istruzione è costituito da tutti gli intervalli (span) che comprendono un singolo intervallo (span) FirstName.name che è identificato da tale documento.

create dictionary FirstNamesDict as
(
  'Aaron', 'Matthew', 'Peter'
);
create dictionary LastNamesDict as
(
  'Anthony', 'Lehman', 'Radcliff'
);

create view LastName as
  extract dictionary 'LastNamesDict'
  on D.text as last
from Document D
having MatchesRegex(/((\p{L}\p{M}*)+\s+)?\p{Lu}\p{M}*.{1,20}/, last);

create view FirstName as
  extract dictionary 'FirstNamesDict'
  on D.text as first
from Document D
having MatchesRegex(/\p{Lu}\p{M}*.{1,20}/, first);

create view PersonName as
extract pattern <F.first> <L.last>? as fullName
from FirstName F, LastName L;

Istruzione select

L'istruzione select in AQL fornisce un potente meccanismo per utilizzare diverse specifiche per costruire o combinare insiemi di tuple.

Sintassi

La struttura select è simile in struttura a un'istruzione SQL SELECT:

select `<select list>`
  from `<from list>`
  [where `<where clause>`]
  [consolidate on `<column>`
     [using '`<policy>`' [with priority
         from `<column> ` [priority order]]]]
  [group by `<group by list>`]
  [order by `<order by list>`]
  [limit `<maximum number of output tuples for each document>`];

Descrizione

  • <select list\>

    Un elenco delimitato da virgole di espressioni di output.

  • <from list\>

    Un elenco delimitato da virgole che è l'origine delle tuple da selezionare.

  • [where <where clause\>]

    Definisce un predicato da applicate su ciascuna tupla generata dal prodotto cartesiano di tutte le tuple nelle relazioni nella clausola from. Questa clausola è facoltativa.

  • [consolidate on<column\>[using '<policy\>' [with priority from <column\> priority order]]]

    Definisce una politica di consolidamento per gestire gli intervalli (span) che si sovrappongono. Questa clausola è facoltativa.

  • [group by<group by list\>]

    Raggruppa le tuple prodotte dallo stesso documento in base ai valori comuni di uno specifico campo. Questa clausola è facoltativa.

  • [order by<order by list\>]

    Ordina le tuple di output prodotte dall'istruzione select da ciascun documento. L'ordine è basato sui valori dell'elemento order-by, un elenco delimitato da virgole di espressioni. Questa clausola è facoltativa.

  • [limit <maximum number of output tuples for each document\>]

    Limita il numero di tuple di output per ciascun documento al massimo specificato. Questa clausola è facoltativa.

Note di utilizzo

La semantica dell'istruzione select è la seguente:

  • Determina i dati di input (in tuple) prendendo il prodotto cartesiano di relazioni nell'elenco di origine (from).
  • Per ogni tupla di input generata, filtrata applicando i predicati nella clausola (facoltativa) where.
  • Se la clausola group by facoltativa è presente, raggruppa le tuple prodotte dallo stesso documento in base ai valori specificati nell'elenco group-by e calcola il risultato delle funzioni aggregate all'interno dell'elenco di selezione (select).
  • Consolida le eventuali tuple che si sovrappongono, in base alla politica definita nella clausola (facoltativa) consolidation. Se la clausola order by è presente, ordina queste tuple in base ai valori dell'elenco order-by.
  • Calcola tutte le espressioni all'interno dell'elenco select su ciascuna tupla e rinomina le colonne come specificato dalle clausole as.
  • Se la clausola limit facoltativa è presente, limita il numero di tuple di output al numero specificato di tuple per ciascun documento.

Esempi

Un esempio di come utilizzare l'istruzione select è quello di estrarre i numeri telefonici che corrispondono a un modello. Supponiamo che la vista PhoneNumbers che estrae i numeri telefonici del modello XXX-XXX-XXXX per gli Stati Uniti sia già definita. Questa istruzione select valuta l'espressione regolare per il modello 444-888-XXXX nel testo di input. La vista ha le colonne di output documentText e phoneNumber. Inoltre, l'output è limitato alla prima ricorrenza di questo modello di numero telefonico identificato per ogni documento.

create view PhoneNumbersPattern1 as
select D.documentText, D.phoneNumber
from PhoneNumbers D
where MatchesRegex(/444-888-\d{4}/,D.phoneNumber)
limit 1;

Un altro esempio di come puoi utilizzare l'istruzione select è quello di trovare le associazioni approssimative delle persone e dei loro numeri telefonici corrispondenti. Supponiamo che la vista Person sia già definita e che abbia le colonne person e la vista PhoneNumbers. Questa istruzione select valuta la clausola where per trovare gli intervalli (span) di testo che contengono una menzione di persona seguita da un numero telefonico entro da 1 a 3 parole o token. L'input a questa istruzione è rappresentato da un'unione tra le viste Person e PhoneNumbers nell'elenco di origine (from).

create view PersonPhone as
select P1.documentText, P1.person, P2.phoneNumber, CombineSpans(P1.person,P2.phoneNumber) as personPhoneSpan
from Person P1, PhoneNumbers P2
where FollowsTok(P1.person,P2.phoneNumber,1,3);

La colonna personPhoneSpan conterrà gli intervalli (span) corrispondenti che danno l'associazione approssimativa persona-telefono.

personPhoneSpan
John : 433-999-1000
Martha Mob 433-999-1001
  • L'elenco di selezione (select) L'elenco di selezione (select) è un'istruzione select o extract che consiste in un elenco separato da virgole di espressioni di output.
  • L'elenco di origine (from) La seconda parte di un'istruzione select o extract in AQL è un elenco di origine (from). L'elenco di origine (from) è un elenco separato da virgole che è l'origine delle tuple da selezionare o estrarre.
  • La clausola where La clausola where facoltativa definisce un predicato da applicare su ciascuna tupla generata dal prodotto cartesiano di tutte le tuple nelle relazioni nella clausola from.
  • La clausola consolidate on La clausola consolidate on facoltativa specifica in che modo vengono risolti gli intervalli (span) che si sovrappongono nelle tuple generate in output da un'istruzione select o extract. Le tuple con intervalli (span) che non si sovrappongono non sono interessate quando viene utilizzata questa clausola.
  • La clausola group by La clausola group by facoltativa di un'istruzione select indica al componente di runtime di raggruppare le tuple prodotte dallo stesso documento in base ai valori comuni di uno specifico campo.
  • la clausola order by La clausola order by facoltativa indica al componente di runtime di ordinare le tuple di output prodotte dall'istruzione select da ciascun documento in base ai valori dell'elenco order by, che è un insieme delimitato da virgole di espressioni.
  • La clausola limit La clausola limit facoltativa specifica un limite sul numero di tuple di output prodotte dall'istruzione select per un documento.
  • L'istruzione select... into L'istruzione select ... into è utile per definire una vista e specificare che è una vista di output in una singola istruzione.

Elenco di selezione (select)

L'elenco di selezione (select) in un'istruzione AQL select o extract consiste in un elenco delimitato da virgole di espressioni di output.

Sintassi

Ciascuna espressione di selezione deve essere in uno dei seguenti formati:

select
   <viewname>.<colname> as <alias> |
   <viewname>.* |
   <expr> as <alias> |
     case
     when <predfunction1()> then <expr1>
      when <predfunction2()> then <expr2>...
     when <predfunctionn()>
      then <exprn>
     [else <expr\_default>]
      as <name>

Descrizione

  • <viewname\>.<colname\> as <alias\>

    • <viewname\>

      Specifica la vista da cui selezionare le colonne.

    • <colname\>

      Specifica la colonna in tale vista.

    • <alias\>

      Specifica il nome con cui è noto il campo selezionato. Questo campo è un campo facoltativo. Viene selezionato per essere parte di ciascuna tupla di output. Se <alias\> non viene specificato, il nome della colonna è di default il <colname\>. Può essere un identificativo semplice o un identificativo tra virgolette doppie.

  • <viewname\>.*

    Specifica il nome di una vista. Questa sintassi indica che tutte le colonne della vista specificata devono essere portate avanti dall'istruzione select o extract di inclusione.

    Come SQL, AQL consente l'istruzione select * abbreviata. L'effetto di questa istruzione è di selezionare tutte le colonne da tutti gli input specificati nella clausola from dell'istruzione select. Tuttavia, l'istruzione extract * abbreviata non è supportata.

  • <expr\> as <alias\>

    Rappresenta l'assegnazione di un'espressione a un attributo della vista di inclusione.

    • <expr\>

      Specifica un'espressione composta di chiamate di funzione scalare, chiamate di funzione aggregata o una costante.

    • <name\>

      Rappresenta il nome della colonna che detiene il risultato dell'espressione specificata da <expr\> come <alias\>. Se <alias\> non viene specificato, il nome della colonna è di default il <name\>. Può essere un identificativo semplice o un identificativo tra virgolette doppie.

  • when<function1()\> then <expr1\> when <function2()\> then <expr2\> ... when <functionN()\> then <exprn\> [else ] <expr_default\> as <name\>

    • <function1()\>, <function2()\>, <functionN()\>

      Specifica le funzioni scalari che restituiscono il tipo booleano.

    • <expr1\>, <expr2\>, <exprn\>, <expr_default\>

      Specifica le espressioni composte di chiamate di funzione scalare e devono restituire lo stesso tipo.

    Se il risultato di <function1()\> è vero, allora il risultato dell'espressione case è il risultato di <expr1\>e non vengono valutate nessuna delle successive clausole when . Altrimenti, le clausole when successive (se presenti) vengono valutate nello stesso modo.

    Quando nessuna delle condizioni delle clausole when sono soddisfatte, il risultato di questa espressione di caso è il risultato dell'espressione predefinita <expr\_default\>. Questa espressione è specificata nella clausola else facoltativa. Se la clausola [else] è assente, il risultato di questa espressione case è null.

Note d'utilizzo

  • La seguente istruzione non è supportata:

    select * from Document;
    

    Il contenuto della vista Document potrebbe non essere completamente noto nel contesto o nell'ambito corrente del file .aql dove viene emessa questa istruzione select. La mancanza di informazioni sul contenuto è dovuta al atto che più istruzioni require document with columns fornite esternamente al file .aql corrente potrebbero modificare l'eventuale definizione di schema di questa vista Document speciale quando viene utilizzato a livello di un modulo. L'istruzione Document.* abbreviata non è un costrutto AQL valido.

  • Puoi selezionare esplicitamente i campi dalla vista Document. Il seguente esempio mostra una valida selezione esplicita di campi da una vista Document:

    select D.label as label,
      D.text as text
    from Document D;
    

Esempi

I seguenti esempi illustrano diversi formati dell'elenco di selezione (select).

Esempio 1: Assegnazione di valore esplicita utilizzando una costante

Questo esempio mostra l'assegnazione di un valore costante a un attributo view dall'interno dell'elenco di selezione (select) . Questo campo denominato polarity indica se la polarità di PS.match è positiva o negativa (nota l'assegnazione esplicita di un valore costante a questo attributo).

create view PositiveSentimentsWithPolarity as
select
  'positive' as polarity,
  PS.match as sentiment
from
  PositiveSentiments PS;
create view NegativeSentimentsWithPolarity as
select
  'negative' as polarity,
  NS.match as sentiment
from
  NegativeSentiments NS;

Esempio 2: Assegnazione di valore esplicita utilizzando la chiamata di funzione

Il seguente esempio illustra in che modo il risultato di una chiamata di funzione viene assegnato esplicitamente a un attributo view all'interno dell'elenco di selezione (select).

create view Citizenship as
select
  P.Name as name,
  MatchesDict('USCities.dict', P.birthPlace) as isUSCitizen
from
  Person P;

Esempio 3: Espressione di elenco di selezione (select) da un'estrazione del dizionario

Il seguente esempio illustra il modo in cui l'espressione di selezione elenco può prendere i valori di tipo Span da un risultato di estrazione del dizionario.

create view PersonNames as
select N.match as name
from
  (extract
  dictionary 'firstNames.dict'
  on D.text
  as match
  from Document D
)N;

Esempio 4: Esempio di espressioni case

Questo primo esempio mostra come specificare la gestione null su campi specifici:

create view School as
select
case
when Not(NotNull(P.education)) then 'Unknown'
else GetString(P.education)
as name
from Person P;

Questo esempio spiega come classificare i dati:

create view Company as
select
PM.name as productname,
case
when ContainsRegex (/IBM/,PM.name) then 'IBM'
when ContainsDict ('OpenSourceDict',PM.name) then 'OSS'
else 'Unknown'
as name
from ProductMatches PM;

Elenco di origine (from)

La seconda parte di un'istruzione select o un'istruzione extract in AQL è l'elenco di origine (from). L'elenco di origine (from) è un elenco separato da virgole che è l'origine delle tuple da selezionare o estrarre.

Sintassi

from <from list item> <name>  [, <from list item> <name>]

Descrizione

  • <from list item\>

    Un riferimento funzione tabella, tabella o vista o un'istruzione AQL nidificata. Tutte le istruzioni nidificate in AQL devono essere racchiuse tra parentesi.

  • <name\>

    Nome locale del <from list item\>, che viene scopato all'interno dell'istruzione select o dell'istruzione extract . Un nome locale può essere un identificativo semplice o un identificativo tra virgolette doppie. I nomi locali che contengono spazi, caratteri di punteggiatura o parole chiave AQL devono essere racchiusi tra virgolette doppie.

Esempi

Esempio 1: Un elenco di origine (from) con una vista e un'istruzione nidificata

Questo esempio mostra un elenco di origine (from) che fa riferimento a una vista e a un'istruzione extract nidificata. L'esempio assegna il risultato dell'istruzione al nome locale FN. L'esempio assegna anche gli output della vista LastName al nome locale Last Name.

create dictionary LastNamesDict as
  (
    'Anthony', 'Lehman', 'Radcliff'
  );

create view LastName as
  extract dictionary 'LastNamesDict'
  on D.text as lastname
from Document D;

create view FromList as
  select *
    from
    (extract dictionary 'first.dict' on D.text
      as firstname from Document D) FN,
      LastName "Last Name"
    where Follows(FN.firstname,
      "Last Name".lastname, 0, 1);

I seguenti nomi sono contenuti nel dizionario esterno first.dict:

#Dictionary for given names
Aaron
Candra
Freeman
Mathew
Matthew
Zoraida

Clausola where

La clausola where facoltativa definisce un predicato da applicare su ciascuna tupla generata dal prodotto cartesiano di tutte le tuple nelle relazioni nella clausola from.

Sintassi

select <select list>
  from <from list>
[where <where clause>]

Descrizione

  • <where clause\>

    Specifica uno o più predicati. Un'unione si verifica quando qualsiasi predicato in una clausola where coinvolge i campi da più di una vista che appartiene all'elenco from. Questo predicato deve essere una congiunzione di una serie di funzioni predicato integrate o altre funzioni definite dall'utente che restituiscono il tipo di dati booleano.

    function1() and function2()
    and ... and functionn()
    

    La clausola where è facoltativa e può essere omessa da un'istruzione select se non esistono predicati da applicare.

Esempi

Esempio 1: Filtraggio di tuple unite utilizzando un predicato nella clausola WHERE

Questo esempio mostra una clausola where che trova solo le frasi formate da nomi di battesimo validi seguiti entro 0-1 caratteri da cognomi validi.

-- a view containing words that are valid given names
create view FirstName as
  extract dictionary 'first.dict'
  on D.text as firstname
from Document D;

-- a view containing words that are valid surnames
create view LastName as
  extract dictionary 'last.dict'
  on D.text as lastname
from Document D;

-- a view containing phrases consisting of valid given names
-- followed within 0-1 characters by valid surnames.
create view FullName as
  select *
  from
  FirstName FN,
  LastName LN
  where
  Follows (FN.firstname, LN.lastname, 0, 1);

I seguenti nomi sono contenuti nel dizionario esterno first.dict:

#Dictionary for given names
Aaron
Candra
Freeman
Mathew
Matthew
Zoraida

I seguenti nomi sono contenuti nel dizionario esterno last.dict:

#Dictionary for surnames
Anthony
Lehman
Radcliff

Clausola consolidate on

La clausola consolidate on facoltativa specifica in che modo vengono risolti gli intervalli (span) che si sovrappongono nelle tuple generate in output da un'istruzione select o extract. Le tuple con intervalli (span) che non si sovrappongono non sono interessate quando viene utilizzata questa clausola.

Sintassi

Il seguente codice è un esempio della struttura generale di questa clausola:

consolidate on <target>
  [using '<policy>'[ with priority from <priority_column>
    [ <priority_order> ]]]

Descrizione

  • <target\>

    Specifica una colonna in una vista nella clausola from o un'espressione composta da chiamate di funzione scalare che coinvolgono colonne di viste specificate nella clausola from come argomenti.

  • '<policy\>'

    Specifica una delle seguenti politiche di consolidamento che è supportata da Text Analytics:

    • ContainedWithin

      Questa politica è quella predefinita. Se gli intervalli (span) A e B si sovrappongono, e A contiene completamente B, questa politica rimuove la tupla che contiene l'intervallo (span) B dall'output. Se A e B sono uguali, ne rimuove uno. La scelta di quale tupla rimuovere è arbitraria.

    • NotContainedWithin

      Se gli intervalli (span) A e B si sovrappongono, e A contiene completamente B, questa politica rimuove l'intervallo (span) A dall'output. Se A e B sono uguali, ne rimuove uno. La scelta di quale tupla rimuovere è arbitraria.

    • ContainsButNotEqual

      Questa politica è uguale a ContainedWithin, tranne per il fatto che gli intervalli (span) esattamente uguali vengono conservati.

    • ExactMatch

      Se un insieme di intervalli (span) copre la stessa regione di testo, questa politica restituisce esattamente uno di essi. Tutti gli altri intervalli (span) vengono lasciati invariati.

    • LeftToRight

      Questa politica elabora gli intervalli (span) in ordine da sinistra a destra. Quando si verifica una sovrapposizione, conserva l'intervallo (span) più a sinistra, più lungo e che non si sovrappone. Questa politica emula la politica di gestione delle sovrapposizioni della maggior parte dei motori di espressioni regolari.

  • <priority\_column\>

    Specifica una colonna di tipo Text, String, Integer o Float. Può essere specificato solo con la politica di consolidamento LeftToRight.

  • <priority\_order\>

    Specifica l'ordine crescente (ascending) o decrescente (descending). Può essere specificato solo con la politica di consolidamento LeftToRight. L'ordine crescente assicura che se una tupla T1 abbia la priorità 1 e una tupla T2 abbia la priorità 2, T1 ha una priorità superiore a T2. Al contrario, se l'ordine di priorità è decrescente, T2 ha la priorità più elevata. Il valore predefinito di priority è ascending.

Note d'utilizzo

  • Quando è presente la clausola di priorità, la semantica di consolidamento segue questo ordine:
    • Elabora gli intervalli (span) da sinistra a destra e, quando gli intervalli (span) si sovrappongono, conserva quelli più a sinistra.
    • Se hai più intervalli (span) che si sovrappongono che iniziano allo stesso offset, conserva quelli con la priorità più elevata in base all'ordine di priorità.
    • Interrompi i restanti legami conservando gli intervalli (span) più lunghi tra quelli con la stessa priorità.
  • Il consolidamento tratta i valori null come identici. Tutti gli input con un risultato nullo <consolidate target\> in una singola tupla in uscita, che viene scelto casualmente tra quegli input. La modalità di funzionamento è simile al modo in cui le tuple vengono consolidate con un intervallo (span) identico nella colonna di destinazione. L'eccezione a un risultato di una singola tupla di output è se la politica è ContainsButNotEqual. In quel caso, il null <consolidate target\> outmette tutti gli input con destinazione di consolidamento nullo.

Esempi

Esempio 1: Consolidamento su una singola colonna

Questo esempio indica al sistema di esaminare il campo Person.name di tutte le tuple di output e di utilizzare la politica di consolidamento ContainedWithin per risolvere la sovrapposizione.

consolidate on Person.name
  using 'ContainedWithin'

Esempio 2: Consolidamento sull'espressione, coinvolgendo più colonne

Questo esempio indica al sistema di esaminare il risultato dell'applicazione della funzione scalare CombineSpans ai campi Person.firstname e Person.lastname in ogni tupla di output. Risolve la sovrapposizione utilizzando la politica di consolidamento ContainedWithin.

consolidate on
  CombineSpans(Person.firstname, Person.lastname)
  using 'ContainedWithin'

Esempio 3: Consolidamento utilizzando l'ordine di priorità e la politica LeftToRight

Supponiamo che le seguenti tuple Term vengano estratte dal testo di input John Doe:

match: `John`,
priority: `1`

e

match: `John Doe`,
priority: `2`

Entrambi gli intervalli (span) hanno lo stesso offset di inizio. Quando esegui il consolidamento utilizzando la politica LeftToRight per l'ordine di priorità crescente, la tupla (match: John, priority: 1) viene conservata perché ha la priorità più alta. Quando esegui il consolidamento utilizzando l'ordine di priorità decrescente, la tupla (match: John Doe, priority: 2) viene conservata, come nel seguente esempio:

create view ConsolidatePeopleWithPrioritiesAscending as
  select P.match as match, P.weight as weight
  from People P
  consolidate on P.match
  using 'LeftToRight'
  with priority from P.weight
  ascending;

Clausola group by

La clausola group by facoltativa di un'istruzione select indica al componente di runtime di raggruppare le tuple prodotte dallo stesso documento in base ai valori comuni di uno specifico campo.

Sintassi

select <select list>
from <from list>
[where <where clause>]
...
[group by <group by list>]

Descrizione

  • <group by list\>

    Specifica un elenco delimitato da virgole di espressioni che coinvolge le colonne delle viste nella clausola from e le chiamate di funzione scalare. Quando applichi la clausola group by, ogni gruppo di tuple che condivide valori comuni per tutte le espressioni group by produce una singola tupla di output che è rappresentativa per l'intero gruppo.

    Un campo o un'espressione che non compare nella clausola group by non può comparire nell'elenco di selezione (select), a meno che non se ne faccia uso in una chiamata di funzione aggregata. L'ordine delle espressioni nell'elenco non è importante.

    La clausola group by tratta tutte le nulle come identiche. Group by su una colonna con valori nulli i risultati in un unico gruppo.

Esempi

Esempio 1: Calcolo di valori aggregati

Utilizza la clausola group by per calcolare i valori aggregati. Questo esempio conta il numero di ricorrenze di ciascun nome di battesimo nel documento. In questo esempio, Count è una funzione aggregata.

create view SampleView as
  select
    GetText(P.firstname) as name,
    Count(GetText(P.firstname)) as occurrences
  from
    (extract
    dictionary 'first.dict'
    on D.text as firstname
    from Document D
    ) P
  group by GetText(P.firstname);

In questo caso, first.dict è un dizionario esterno che contiene le seguenti voci:

#Dictionary for given names
Aaron
Candra
Freeman
Matthew
Zoraida

La seguente procedura descrive la semantica di questa istruzione:

  1. Raggruppa le tuple prodotte dalla query secondaria nella clausola from in base al contenuto del testo del loro campo firstname.
  2. Per ogni gruppo, conta il numero di tuple con un valore firstname non null, Produci una singola tupla di output per ogni gruppo del genere, con due valori, il nome e il numero delle tuple in tale gruppo.

Esempio 2: Problemi con il raggruppamenti di campi dissimili

Questo esempio illustra un'istruzione che non è valida.

select GetText(P.firstname) as first,
  GetText(P.lastname) as last,
  Count(P.firstname) as occurrences
from Person P
group by GetText(P.firstname);

L'inclusione GetText(P.lastname) nell'elenco di selezione (select) non è accettata, poiché le tuple con gli stessi valori firstname potrebbero avere dei valori lastname differenti, con una conseguente ambiguità.

Clausola order by

La clausola order by facoltativa indica al componente di runtime di ordinare le tuple di output prodotte dall'istruzione select da ciascun documento in base ai valori dell'elenco order by, che è un insieme delimitato da virgole di espressioni.

Sintassi

select ...
  [order by <order by list>]

Descrizione

  • <order by list\>

    Specifica un elenco delimitato da virgole di espressioni.

    L'ordine è basato sui valori di un elenco delimitato da virgole di espressioni. La clausola order by supporta espressioni che restituiscono tipi di dati numerici (Integer o Float), Text o Span. Se un'espressione nella clausola order by restituisce un tipo Span, le tuple di risultato sono comparate mettendo a confronto i valori di intervallo (span) pertinenti. Nel seguente esempio, sono messi a confronto i valori di intervallo (span) del campo person.

    order by P.person
    
    

    La clausola order by tratta i valori null come non ordinati (tra loro). I valori null sono ordinati più in basso degli altri oggetti.

Esempi

Esempio 1: Ordinamento in base a più espressioni

Supponiamo che person sia un campo di tipo Span. La seguente clausola order by specifica che l'istruzione restituisce le tuple all'interno di ciascun documento. Sono ordinate lessicograficamente in base al testo del campo person e quindi in base all'inizio del campo person.

order by GetText(P.person), GetBegin(P.person)

Clausola limit

La clausola limit facoltativa specifica un limite sul numero di tuple di output prodotte dall'istruzione select per un documento.

Sintassi

select <select list>
  from <from list>
  ...
  [limit <maximum number of output tuples for each document>];

Descrizione

  • <maximum number of output tuples for each document\>

    Specifica il numero massimo di tuple di output per ogni documento. Se il valore di limite è superiore o uguale al numero totale di tuple che può essere restituito, vengono restituite tutte le tuple.

Esempi

Esempio 1: Limitazione del numero di restituzioni

Questo esempio restituisce i primi tre nomi di persona in ciascun documento:

create view SampleView as
  select *
  from Person P
  order by GetBegin(P.name)
  limit 3;

Istruzione select... into

L'istruzione select ... into è utile per definire una vista e specificare che è una vista di output in una singola istruzione.

Sintassi

select <select list>
into <output view name>
from <from list>
[where <where clause>]
[consolidate on <column> [using '<policy>' [with priority from <column> [priority order]]]]
[group by <group by list>]
[order by <order by list>]
[limit <maximum number of output tuples for each document>];

Descrizione

  • <output view name\>

    Specifica il nome della vista di output definita dall'istruzione. L'istruzione select ... into è identica all'istruzione select , tranne la clausola aggiuntiva into <output view name\> .

Esempi

Esempio 1: Definizione di una vista

Questo esempio definisce una vista denominata PersonPhone e specifica anche questa vista come una vista di output.

select P.name as name,
  Ph.number as phoneNumber
into PersonPhone
from Person P, Phone Ph;

Questo esempio è equivalente alle seguenti due istruzioni:

create view PersonPhone as
  select P.name as name,
    Ph.number as phoneNumber
  from Person P, Phone Ph;

output view PersonPhone;

Istruzione detag

L'istruzione detag in AQL fornisce la funzione per rimuovere le tag o rimuovere tutta la markup da documenti HTML o XML prima di eseguire gli estrattori AQL.

L'istruzione detag può anche conservare le ubicazioni originali delle tag e degli eventuali valori in esse memorizzati. Quando un'istruzione detag rimuove le tag da un documento, il componente di runtime ricorda l'associazione tra gli offset dal testo da cui sono state rimosse le tag e l'origine di markup originale. La funzione Remap, una funzione integrata speciale che associa nuovamente gli intervalli (span) dal testo da cui sono state rimosse le tag ai loro intervalli (span) equivalenti dall'origine originale.

Sintassi

detag <input view name>.<text column>
 as <output view name>
[detect content_type (always|never)]
[annotate
 element '<element name>' as <auxiliary view name>
 [with attribute '<attribute name>' as <column name>]
 [and attribute '<attribute name>' as <column name>]
 [, element ...]];

Descrizione

  • <input view name\>.<text column\>

    • <input view name\>

      Specifica il nome della vista di input su cui eseguire il processo di rimozione delle tag. Il <input view name\> può essere un identificativo semplice o un identificativo a doppio quotato.

    • <text column\>

      Specifica il campo di testo della vista di input su cui eseguire il processo di rimozione delle tag. Il <text column\> può essere un identificativo semplice o un identificativo a doppio quotato.

  • <output view name\>

    Specifica il nome della vista di output che contiene il testo da cui sono state rimosse le tag. La vista di output contiene una singola colonna denominata text, che contiene il testo da cui sono state rimosse le tag. Il <output view name\> può essere un identificativo semplice o un identificativo a doppio quotato.

  • always|never

    Specifica se verificare che il contenuto sia HTML o XML prima che l'istruzione detag venga elaborata. Quando si esegue un testo non HTML e non XML tramite un detagger, possono verificarsi problemi se il testo contiene caratteri speciali XML come <, >o &. Se manca la clausola detect content_type il valore predefinito è always e il sistema rileva sempre il contenuto.

    • always

      Specifica che la verifica ha sempre luogo prima che venga tentata l'operazione per evitare problemi con l'analisi di documenti che non siano HTML o XML. Se il valore del <text column\> non sembra contenere un markup, il sistema skips lo stacca per il documento corrente.

    • never

      Specifica che la verifica non ha mai luogo prima che venga tentata l'operazione di rimozione delle tag. Il sistema prova a rimuovere le tag del testo di destinazione, anche se il testo non presenta alcun contenuto HTML o XML.

  • <element name\>

    Specifica il nome dell'elemento HTML o XML da annotare. La clausola annotate facoltativa può indicare al componente di runtime di ricordare le informazioni relative alle tag rimosse creando una o più viste.

  • <auxiliary view name\>

    Specifica il nome della vista creata per contenere le tag originali e i relativi attributi. Può essere un identificativo semplice o un identificativo tra virgolette doppie.

  • <attribute name\>

    Nome di un attributo dell'elemento HTML o XML.

  • <column name\>

    Il nome della colonna nel <auxiliary view name\> che viene utilizzato per memorizzare i valori di <attribute name\>. Può essere un identificativo semplice o un identificativo tra virgolette doppie.

Esempi

Esempio 1: Specifica della vista di output di rimozione delle tag e di una vista ausiliaria

In questo esempio, la vista DetaggedDoc viene creata per contenere la versione con le tag rimosse del testo originale nell'attributo text della vista Document. Oltre a creare una vista DetaggedDoc, la clausola annotate crea una vista ausiliaria denominata Anchor. Questa vista ausiliaria ha due colonne. Una colonna, denominata match, contiene il testo di ancoraggio. L'altra colonna, denominata linkTarget, contiene la destinazione effettiva del collegamento come testo. Gli intervalli (span) nella colonna match sono sul valore di testo della vista DetaggedDoc.

detag Document.text as DetaggedDoc
annotate
  'a' as Anchor
  with attribute 'href' as linkTarget;

Esempio 2: Utilizzo della funzione Remap

Il seguente esempio illustra in che modo la funzione Remap viene utilizzata per associare nuovamente gli intervalli (span) dal testo da cui sono state rimosse le tag ai loro equivalenti nell'origine originale.

-- Strip out tags from each document, provided that the document
-- is in HTML or XML format.
-- Remember the locations and content of all <A> and <META> tags
-- in the original source document.
detag Document.text as DetaggedDoc
detect content_type always
annotate
  element 'a' as Anchor
    with attribute 'href' as target,
  element 'meta' as Meta
    with attribute 'name' as name
    and attribute 'content' as content;

output view DetaggedDoc;

-- Create a view containing all lists of keywords in the
-- document's META tags.
create view MetaKeywordsLists as
select M.content as list
from Meta M
where MatchesRegex(/keywords/, 'CASE_INSENSITIVE', M.name)
  and NotNull(M.content);

-- Create a dictionary of "interesting" web sites
create dictionary InterestingSitesDict as
(
  'ibm.com', 'slashdot.org'
);

-- Create a view containing all anchor tags whose targets contain
-- a match of the "interesting sites" dictionary.
create view InterestingLinks as
select A.match as anchortext, A.target as href
from Anchor A
where ContainsDict('InterestingSitesDict', A.target);

-- Find all capitalized words in the anchor text of links to
-- "interesting" web sites.
create view InterestingWords as
extract I.href as href,
  regex /[A-Z][a-z]+/ on 1 token in I.anchortext as word
from InterestingLinks I;

-- Map spans in the InterestingWords view back to the original
-- HTML or XML source of the document.
create view InterestingWordsHTML as
select I.href as href, Remap(I.word) as word
from InterestingWords I;

Documentazione dell'istruzione detag con AQL Doc

Il commento AQL Doc per un'istruzione detag contiene le seguenti informazioni:

  • Descrizione generale relativa alla funzione dell'istruzione.
  • @field per ogni campo della vista di input su cui eseguire il processo di rimozione delle tag.
  • @auxView specifica il nome della vista.
  • @auxViewField specifica il nome colonna completo della vista.
/**
* Detags the input document
* @field text the detagged text of the document
* @auxView Anchor stores the anchor points from tagged doc
* @auxViewField Anchor.linkTarget stores the href attribute of anchor tag
*/

detag Document.text as DetaggedDoc
  annotate element 'a' as Anchor
  with attribute 'href' as linkTarget;

Istruzioni create dictionary e create external dictionary

Le istruzioni create dictionary e create external dictionary sono utilizzate per definire i dizionari di parole o frasi per identificare i termini corrispondenti nel testo di input mediante le istruzioni di estrazione o le funzioni predicato. L'istruzione create dictionary consente la specifica di contenuto di dizionario nel codice AQL sorgente e il contenuto di dizionario è serializzato all'interno della rappresentazione compilata del modulo (il file .tam). L'istruzione create external dictionary ti consente di specificare il contenuto di dizionario quando viene istanziato l'estrattore, invece che nel codice AQL sorgente, e non devi ricompilare il modulo. Pertanto, i dizionari esterni sono dei potenti costrutti che consentono allo sviluppatore AQL di esporre i punti di personalizzazione in un modulo compilato.

I dizionari possono essere creati da tre origini:

  • File di dizionario
  • Dichiarazioni di dizionario inline
  • Tabelle create con l'istruzione create table e l'istruzione create external table.

Sintassi

L'istruzione create dictionary interna ha tre formati sintattici: from file, from table e un formato inline.

  • Dizionario interno

    Da file:

    create dictionary <dictionary name>
    
     from file '<file name>'
     [with language as '<language code(s)>']
     [and case (exact | insensitive)]
     [and lemma_match];
    

    Da tabella:

    create dictionary <dictionary name>
    
      from table <table name>
      with entries from <column name>
      [and language as '<language code(s)>']
      [and case (exact | insensitive)]
      [and lemma_match];
    

    Formato inline

    create dictionary <dictionary name>
    [with language as '<language code(s)>']
    [and case (exact | insensitive)]
    [and lemma_match]
     as
        (
        '<entry 1>', '<entry 2>', ... , '<entry n>'
        )
    ;
    
  • Dizionario esterno

    create external dictionary <dictionary-name>
    required [true|false]
    [with language as '<language codes\>']
    [and case (exact | insensitive )]
    [and lemma_match];
    

Descrizione

  • <dictionary name\>

    Specifica un nome per il nuovo dizionario interno o esterno. Può essere un identificativo semplice o un identificativo tra virgolette doppie.

  • '<file name\>'

    Specifica il nome del file che contiene le voci di dizionario. I file di dizionario sono file di testo delimitati da ritorno a capo con una singola voce di dizionario per ogni riga. Le voci in un file di dizionario possono consistere in più token.

  • <table name\>

    Specifica il nome della tabella da cui aggiungere le voci di dizionario. I dizionari non possono essere creati da una tabella importata da un altro modulo.

  • <column name\>

    Specifica il nome della colonna nella tabella da cui aggiungere le voci di dizionario.

  • required [true|false]

    Specifica se il contenuto esterno per il dizionario esterno è necessario per eseguire il modulo.

    • true

      Se la clausola è required true, devi fornire un URI all'ubicazione del file che presenta il contenuto esterno. Il file specificato deve presentare del contenuto. Se l'URI non viene fornito, o se il file non presenta contenuto, il componente di runtime genera un'eccezione.

    • false

      Se la clausola è required false, il modulo può essere eseguito con esito positivo anche se non viene fornito un URI al contenuto esterno per questo dizionario. Se non viene fornito un URI, il componente di runtime lo tratta come un dizionario vuoto.

    L'utilizzo di create external dictionary <dictionary-name\> allow_empty è ora obsoleto e determina un avviso di compilatore.

  • '<language code(s)\>'

    Specifica un elenco delimitato da virgole di codici lingua di due lettere, come ad esempio (inglese) o zh (cinese) per le lingue, o per le lingue di documento per i dizionari esterni, su cui valutare il dizionario. Il dizionario non produce alcun risultato sui documenti il cui codice lingua non è contento in questa stringa.

    Se il parametro di lingua viene omesso, la lingua di dizionario viene automaticamente impostata su uno dei seguenti insiemi di lingue:

    • Gli insiemi di lingue specificati tramite l'istruzione set default language, se è dichiarata, nel modulo contenitore.
    • Gli insiemi di lingue che contengono tedesco (de), spagnolo (es), inglese (en), francese (fr), italiano (it) e la lingua non specificata (x_unspecified).
  • lemma_match

    Utilizza la lemmatizzazione per trovare corrispondenze per parole simili a un termine di dizionario nei tuoi documenti.

    La lemmatizzazione è il processo di determinazione del lemma per una specifica parola. Un lemma è una parola che può essere utilizzata come una corrispondenza per un singolo specifico termine. Ad esempio, il termine “go” può essere messo in corrispondenza ai termini “goes”, “going”, “gone” o “went”. Questo processo comporta attività complesse quali la comprensione del contesto e la determinazione della parte del discorso di una parola in una frase. La lemmatizzazione è disponibile per tutte le lingue per cui il tokenizer multilingue di IBM fornisce il supporto di parte del discorso.

    La corrispondenza dei lemmi viene eseguita solo per i dizionari dichiarati con la clausola lemma match.

    La semantica per l'estrazione di dizionario con la clausola lemma_match è la seguente:

    • Viene calcolato il formato lemmatizzato per ogni token del documento di input.
    • Il dizionario viene valutato rispetto al documento lemmatizzato. Non puoi utilizzare l'opzione lemma_match con l'opzione case exact. Se vengono utilizzate entrambe, viene restituito un errore del compilatore.
  • case (exact | insensitive)

    Specifica il tipo di normalizzazione dei caratteri eseguito dal dizionario quando determina se una specifica regione del documento corrisponde.

    • exact

      Specifica una corrispondenza esatta e sensibile a maiuscole/minuscole.

    • insensitive

      Specifica una corrispondenza che non è sensibile a maiuscole/minuscole. Questa opzione rappresenta il valore predefinito.

  • '<entry 1\>', '<entry 2\>', ... , '<entry n\>'

    Specifica le stringhe che vuoi includere nel dizionario inline. Le voci in un dizionario inline possono consistere in uno o più token.

Note d'utilizzo

  • I formati from file e from table sono consigliati, soprattutto quando prevedi di modificare le voci o quando hai molte voci. Utilizzando questi formati, puoi modificare il contenuto del dizionario senza modificare il codice.

  • Quando l'istruzione create dictionary viene elaborata dal compilatore AQL modulare, i riferimenti alle ubicazioni di file di dizionario specificate nella sintassi create dictionary ... from file devono essere relative alla root del modulo in cui viene emessa questa istruzione create dictionary.

  • Puoi specificare commenti in un file di dizionario antecedendo al commento il carattere #. I commenti possono iniziare ovunque in una riga.

  • Se vuoi specificare dei commenti che si estendono su più righe, devi far precedere a ogni riga il carattere di commento. Se il carattere di commento fa parte di una voce di dizionario, devi eseguirne l'escape con il carattere barra rovesciata (\), come in \#. Se il carattere barra rovesciata fa parte della voce di dizionario, devi eseguirne l'escape con se stesso, come in \\.

  • Per i dizionari esterni, quando è in corso il caricamento di modulo, devi specificare un elenco di URI ai dizionari esterni, come richiesto dai moduli in caricamento.

  • Lemmatizzazione dei dizionari: La differenza primaria tra la semantica di corrispondenza del dizionario esistente e la semantica lemmatizzata è che la corrispondenza viene eseguita rispetto al formato lemmatizzato del documento invece del formato originale del documento.

    Le voci di dizionario che appartengono a un dizionario con la corrispondenza dei lemmi abilitata hanno questi prerequisiti.

    • Una voce di dizionario può contenere uno o più token, dove ogni token di voce è un lemma. Per creare un dizionario di lemmi, puoi utilizzare la funzione scalare [GetLemma .
    • I token di una voce di dizionario devono essere separati da uno spazio vuoto. Se il token è composto da spazi vuoti, è necessario eseguirne l'escape utilizzando il carattere barra rovesciata (\).
  • La seguente tabella mostra le differenze tra l'istruzione create external dictionary e l'istruzione create dictionary:

create external dictionary create dictionary
  • Definisce un segnaposto per un dizionario il cui contenuto viene fornito in fase di inizializzazione.
  • Richiede che il contenuto del dizionario sia disponibile in fase di compilazione.
  • Ne viene eseguita la serializzazione nella rappresentazione compilata (.tam) di un modulo.

Esempi

Esempio 1: Creazione di un dizionario esterno

Si prevede che il dizionario esterno, PersonPositiveClues, venga popolato con i valori da un file esterno in fase di caricamento. Si prevede anche che ne venga eseguita la messa in corrispondenza rispetto ad alcune lingue occidentali, come specificato dai suoi indicatori.

module PersonModuleEnglish;

create external dictionary PersonPositiveClues
  allow_empty false
  with case exact;

export dictionary PersonPositiveClues;

Esempio 2: Lemmatizzazione

Considera un dizionario che ha la messa in corrispondenza dei lemmi abilitata e che contiene due voci: go shop e went shopping. Il documento contiene il testo Anna went shopping. Il formato lemmatizzato del documento di input è Anna go shop. La messa in corrispondenza dei lemmi restituisce went shopping come una corrispondenza per la voce go shop. Il testo del documento originale non viene messo a confronto con le voci del dizionario, solo il testo del documento lemmatizzato. Pertanto, non esiste alcuna corrispondenza nel documento per la voce went shopping.

Documentazione delle istruzioni create dictionary e create external dictionary con AQL Doc

Il commento AQL Doc per un'istruzione create dictionary contiene le seguenti informazioni:

Descrizione generale relativa al dizionario

/**
* A dictionary of terms used to greet people.
*
*/

create dictionary GreetingDict as
(
  'regards', 'regds', 'hello', 'hi', 'thanks', 'best', 'subj', 'to', 'from'
);

Il commento AQL Doc per un'istruzione create external dictionary contiene la descrizione generale relativa al dizionario creato. La seguente stringa illustra il formato:

/**
 * Customizable dictionary of given names.
 * Evaluated on English, French, Italian, German, Portuguese, Spanish text.
 */
create external dictionary CustomFirstNames_WesternEurope
  allow_empty true;

Istruzione create table

L'istruzione create table crea una tabella AQL.

L'istruzione create table in AQL viene utilizzata per definire le tabelle di ricerca statiche per ampliare le annotazioni con ulteriori informazioni.

Sintassi

create table <table name> (
    <colname> <type> [,  <colname> <type>]* )
 as values
    ( <value> [, <value>]*),
    ...
    ( <value> [, <value>]*);

Descrizione

  • <table name\>

    Specifica il nome della tabella da creare. Il <table name\> può essere un identificativo semplice o un identificativo a doppio quotato.

  • <colname\>

    Specifica il nome della colonna da creare.

  • <type\>

    Specifica il tipo di dati AQL per la colonna associata. Tutte le colonne devono essere di tipo Text, Integer, Float o Boolean.

  • <value\>

    Specifica le tuple da popolare nella tabella creata.

Esempi

Esempio 1: Creazione di una tabella di nomi azienda

In questo esempio, l'istruzione create table aggiunge ulteriori metadati di ubicazione alle annotazioni di nome azienda.

-- Create a dictionary of company names
create dictionary CompanyNames as
  ('IBM', 'BigCorp', 'Initech');

-- Find all matches of the company names dictionary.
create view Company as
  extract
    dictionary 'CompanyNames' on D.text as company
  from Document D;


-- Create a table that maps company names to locations of
-- corporate headquarters.
create table NameToLocation
  (name Text, location Text) as
  values
  ('IBM', 'USA'),
  ('BigCorp', 'Apex'),
  ('Initech', 'Dallas'),
  ('Acme Fake Company Names', 'Somewhere');

-- Use the table to augment the Company view with location
-- information.
create view CompanyLoc as
  select N2C.location as loc,
          C.company as company
  from Company C, NameToLocation N2C
  where Equals(GetText(C.company), GetText(N2C.name));

output view CompanyLoc;

Documentazione dell'istruzione create table con AQL Doc

Il commento AQL Doc per un'istruzione create table contiene le seguenti informazioni:

  • Descrizione generale relativa alla tabella.
  • @field per ogni nome colonna nello schema di questa tabella.
/** Create a table that maps company names to locations
/** of corporate headquarters.
* @field name name of the company
* @field location location of corporate headquarters
*/

create table NameToLocation
  (name Text, location Text) as
 values
  ('IBM', 'USA'),
  ('Enron', 'UK'),
  ('Initech', 'Dallas'),
  ('Acme Fake Company Names', 'Somewhere');

Istruzione create external table

Puoi utilizzare l'istruzione create external table per specificare una tabella con contenuto stabilito quando un modulo compilato viene eseguito in tutti i documenti di input. Fornisci il contenuto tabella durante la fase di caricamento invece che nel codice AQL sorgente e non devi ricompilare il modulo.

Le tabelle esterne sono dei potenti costrutti che consentono allo sviluppatore AQL di esporre i punti di personalizzazione in un modulo compilato.

Sintassi

create external table <table-name\>
  (<colname\> <type\>
   [,  <colname\> <type\>]* )
   allow_empty <true|false>;

Descrizione

  • <table-name\>

    Specifica il nome della tabella esterna da creare. Il <table-name\> può essere un identificativo semplice o un identificativo a doppio quotato.

  • <colname\>

    Specifica il nome della colonna da creare.

  • <type\>

    Specifica il tipo di dati AQL per la colonna associata. Tutte le colonne devono essere di tipo Text, Integer, Float o Boolean.

  • [, <colname\> <type\>]*

    Specifica ulteriori colonne e oggetti AQL da utilizzare nella tabella esterna.

  • allow_empty [true|false]

    Specifica il valore per la clausola allow_empty .

    • true

      Se la clausola è allow_empty true, il modulo può essere eseguito con esito positivo anche se non viene fornito un URI al contenuto esterno per questa tabella. Se non viene fornito l'URI, il componente di runtime lo tratta come una tabella vuota.

    • false

      Se la clausola è allow_empty false, devi fornire un URI all'ubicazione del file che presenta il contenuto esterno. Il file specificato deve presentare del contenuto. Se l'URI non viene fornito, o se il file non presenta contenuto, il componente di runtime genera un'eccezione.

Note d'utilizzo

  • La rappresentazione compilata del modulo contiene i metadati relativi agli oggetti esterni (viste, dizionari e tabelle) definiti dal modulo.
  • Quando è in corso il caricamento dei moduli, devi specificare un elenco di URI alle tabelle esterne, come richiesto dai moduli in caricamento.
  • Il formato supportato per il contenuto di una tabella esterna è un file CSV (.csv) con intestazione.

La seguente tabella mostra le differenze tra l'istruzione create external table e l'istruzione create table:

create external table create table
  • Definisce un segnaposto per una tabella il cui contenuto viene fornito in fase di inizializzazione.
  • Richiede che il contenuto della tabella sia disponibile in fase di compilazione.
  • Ne viene eseguita la serializzazione nella rappresentazione compilata (.tam) di un modulo.

Esempi

Esempio 1: Creazione di una tabella esterna popolata in fase di caricamento

Si prevede che la tabella esterna, PersonNegativeClues, sia popolata in fase di caricamento a causa dell'indicatore allow_empty false.

module PersonModuleFrench;

create external table PersonNegativeClues (name Text)
  allow_empty false;

export table PersonNegativeClues;

Esempio 2: Creazione di un dizionario con una tabella esterna

I dizionari possono anche essere creati da tabelle esterne, in modo analogo alla creazione da tabelle inline dichiarate con l'istruzione create table.

create external table Product (nickName Text, formalName Text)
allow_empty false;

/**
  * Dictionary of product nicknames, from the nickName field
  * of the customizable external table Product.
  */
create dictionary ProductDict
from table Product
with entries from nickName;

Documentazione dell'istruzione create external table con AQL Doc

Il commento AQL Doc per un'istruzione create external table contiene le seguenti informazioni:

  • Descrizione generale relativa alla tabella.
  • @field per ogni nome colonna nello schema di questa tabella.
/** Create a table that maps company names to locations of corporate headquarters.
* @field name name of the company
* @field location location of corporate headquarters
*/
create external table Company2Location
  (name Text, location Text)
   allow_empty false;

Istruzione create external view

L'istruzione create external view in AQL consente la specifica di ulteriori metadati su un documento come una nuova vista, oltre alla vista Document predefinita che presenta il contenuto testuale e di etichetta.

Sintassi

create external view <view_name> (
        <colname> <type> [, <colname> <type>]*
        )
external_name '<view_external_name>';

Descrizione

  • <view_name\>

    Specifica il nome interno della vista esterna. Alla vista esterna si fa riferimento con questo nome nelle regole AQL. Un <view_name\> può essere un identificativo semplice o un identificativo doppio citato. Una <view_name\> non può contenere il carattere di periodo.

  • <colname\>

    Specifica il nome della colonna da definire nella vista esterna.

  • <type\>

    Specifica il tipo di dati per la colonna associata. I tipi di dati supportati per le colonne di vista esterna sono Text, Span, Integer e Float.

  • '<view_external_name\>'

    Specifica il nome esterno della vista esterna. I sistemi esterni che popolano le tuple nella vista esterna fanno riferimento alla vista esterna mediante il nome esterno. Il '<view_external_name\>' deve essere una costante String che viene accelata in virgolette singole ('ExternalName ').

Esempi

Per illustrare le viste esterne, considera un'applicazione di esempio che richiede che tu identifichi i nomi delle persone nei messaggi email.

Esempio 1: Identificazione dei nomi delle persone nei messaggi email

Supponiamo che il testo di un messaggio email sia "Ena, please send me the document ASAP". Mentre un essere umano potrebbe essere in grado di comprendere che Ena è un nome di una persona in base al testo dell'email, le regole AQL scritte per identificare i nomi di persone con elevata precisione dal testo generale potrebbero essere troppo conservative e non essere in grado di trarre la stessa conclusione con un elevato grado di fiducia, sulla base del fatto che Ena è una parola che inizia con una lettera maiuscola.

Un modo per potenziare la copertura delle regole consiste nell'utilizzare parole dai campi From, To e CC della email come ulteriore evidenza.

Se l'email è indirizzata a "Ena Smith," e l'applicazione rende queste informazioni disponibili all'estrattore, lo sviluppatore dell'estrattore può scrivere ulteriori regole AQL che potenziano la copertura dell'estrattore che è basata sulla conoscenza del settore che le email sono di norma indirizzate a persone.

Ad esempio, puoi scrivere delle regole AQL per identificare i token di persona dai campi di metadati di email. Puoi quindi utilizzare le informazioni come forti indizi quando decidi se un token che inizia per lettera maiuscola nel testo dell'email è un nome di persona. In generale, i metadati di email non fanno parte del messaggio email effettivo ma l'applicazione può rendere questi metadati disponibili all'estrattore utilizzando una vista esterna.

In fase di runtime, per ogni email che deve essere elaborata, l'applicazione può passare il testo di email come testo di documento (per popolare la vista Document). Può anche passare i metadati extra utilizzando una vista esterna definita in modo appropriato.

La seguente istruzione definisce una vista esterna denominata EmailMetadata. La vista esterna ha uno schema che contiene tre campi di tipo Text. In fase di runtime, la vista EmailMetadata viene popolata automaticamente da un tipo esterno denominato EmailMetadataSrc. Puoi quindi fare riferimento alla vista EmailMetadata nelle tue regole AQL, analogamente a come faresti riferimento a qualsiasi altra vista.

create external view EmailMetadata
  (fromAddress Text, toAddress Text, ccAddress Text)
external_name 'EmailMetadataSrc';

Documentazione dell'istruzione create external view con AQL Doc

Il commento AQL Doc per un'istruzione create external view contiene le seguenti informazioni:

  • Descrizione generale relativa alla vista.
  • @field per ogni nome colonna nella vista.
/**
* The external view named EmailMetadata, containing three fields
* of type Text. At run time, the view EmailMetadata is
* automatically populated from an external type named
* EmailMetadataSrc.
*
* @field from the fromAddress field of the email
* @field to the toAddress field of the email
* @field cc the ccAddress field of the email
*/

create external view EmailMetadata(fromAddress Text, toAddress Text, ccAddress Text)
external_name 'EmailMetadataSrc';

Formati file per risorse utente esterne

Sono supportati tre tipi di risorse utente esterne: viste esterne, dizionari esterni e tabelle esterne.

Dizionario esterno

Il formato per il file che contiene le voci per un dizionario esterno è definito qui:

  • File di testo delimitato da ritorni a capo.
  • Una singola voce di dizionario per ogni riga.
  • L'estensione file consigliata è .dict ma possono essere supportate altre estensioni file.
  • Le voci nel dizionari possono consistere in più token.
  • I commenti possono essere specificati antecedendo al contenuto del commento il carattere #.
  • I commenti possono iniziare ovunque in una riga.
  • I commenti su più righe devono contenere il carattere # all'inizio di ciascuna riga.
  • Le voci di dizionario possono contenere caratteri di commenti, se viene eseguito l'escape di ciascun carattere di commento con un carattere barra rovesciata. Ad esempio, \#.

Tabella esterna

Il formato file supportato per il contenuto di una tabella esterna è un file .csv con intestazione.

Il seguente esempio mostra un'istruzione create external table e il file .csv che specifica il contenuto di questa tabella esterna.

create external table Company2Location
  (name Text, location Text)
   allow_empty false;

La prima riga del file .csv contiene l'intestazione. Le righe rimanenti contengono i dati.

name,location
IBM,USA
Infosys,India
LG,Korea
Vodafone,UK

Vista esterna

Il contenuto delle viste esterne può essere specificato nei seguenti modi:

  • Quando esegui un estrattore, puoi specificare il contenuto della vista esterna per una raccolta dati solo quando stai utilizzando il formato di input JSON.

Funzioni integrate

AQL dispone di una raccolta di funzioni integrate per l'utilizzo nelle regole di estrazione.

  • Funzioni aggregate Le funzioni aggregate sono utilizzate per implementare le operazioni (quali il conteggio, le operazioni matematiche e altre operazioni) in un insieme di valori di input. Queste funzioni restituiscono solo un singolo risultato.
  • Funzioni predicato Le funzioni predicato verificano uno specifico predicato sui suoi argomenti di input e restituiscono un valore booleano corrispondente.
  • Funzioni scalari Le funzioni scalari eseguono un'operazione sui valori di un campo su un insieme di tuple di input e restituiscono un valore non booleano, come Span, Text o Integer. Queste funzioni possono essere utilizzate all'interno dell'elenco select di un'istruzione select o di un'istruzione extract . Possono anche essere utilizzate come input per le funzioni predicato.

Funzioni aggregate

Le funzioni aggregate sono utilizzate per implementare le operazioni (quali il conteggio, le operazioni matematiche e altre operazioni) in un insieme di valori di input. Queste funzioni restituiscono solo un singolo risultato.

Queste funzioni possono essere utilizzate all'interno dell'elenco select di un'istruzione select ma non all'interno di un'istruzione extract

Il seguente esempio è il formato generale di una chiamata di funzione aggregata:

Aggregate_Function_Name(argument)

L'argomento (argument) può essere:

  • Un'espressione che consiste in una colonna di una vista nella clausola from o una combinazione di funzioni scalari che coinvolgono colonne delle viste nella clausola from.

    Nella maggior parte dei casi, salvo quanto indicato, i valori null per l'argomento vengono ignorati.

  • Il carattere * nel caso speciale della funzione aggregata Count(*).

    In questo caso, vengono conteggiate tutte le righe dell'output, inclusi i valori null.

Funzione aggregata Tipo di argomento Tipo di ritorno Valore di ritorno
Avg(expression) Integer, Float Float La media di tutti i valori di input o null se non viene selezionata alcuna riga
Conteggio (\ *) Numero intero Il numero di tutte le righe di input
Count(expression) Any Numero intero Il numero di tutti i valori di input non null
List(expression) Integer, Float, Text, Span Elenco dei valori scalari dello stesso tipo dell'argomento di input Un elenco non ordinato di valori di input non null: un contenitore, non un insieme, pertanto potrebbe contenere dei duplicati. Un elenco vuoto se sono selezionati solo valori null
Max(expression) Integer, Float, Text, Span Uguale al tipo argument il numero massimo di elementi in tutti i valori di input oppure null se non è selezionata alcuna riga
Min(expression) Integer, Float, Text, Span Uguale al tipo argument il numero minimo di elementi in tutti i valori di input oppure null se non è selezionata alcuna riga
Sum(expression) Integer, Float Uguale al tipo argument La somma di tutti i valori di input oppure null se non è selezionata alcuna riga

Limitazioni della versione corrente:

La versione corrente di AQL supporta la creazione di valori scalari tramite l'elenco delle funzioni aggregate.

Esempi

Il seguente esempio illustra come le funzioni aggregate possono conteggiare il numero di annotazioni di nome persona o calcolare gli insiemi di nomi di battesimo associati a ciascun distinto cognome identificato in un documento.

-- identify occurrences of given names in the document
create view FirstName as
extract dictionary 'firstNames.dict' on D.text as name
from Document D;

-- identify occurrences of surnames in the document
create view LastName as
extract dictionary 'lastNames.dict' on D.text as name
from Document D;

-- identify complete person names in the document
create view Person as
select F.name as firstname, L.name as lastname
from FirstName F, LastName L
where FollowsTok(F.name, L.name, 0, 0);

-- count the number of person annotations in the document
create view CountPerson as
select Count(*)
from Person;

-- for each distinct surname, output a list of given names associated with it in the document
create view FamilyMembers as
select GetText(P.lastname) as lastname, List(GetText(P.firstname)) as firstnames
from Person P
group by GetText(P.lastname);

Il seguente esempio illustra l'utilizzo delle funzioni Min e Max:

-- Extract stop words from input text
create view StopWords as
extract
regex /\s(the|in|a|an|as|to|from)\s/ on D.text as match
from Document D;


-- Count the number of times each stop word matched above, was used in the text
create view StopWordsCount as
select
GetText(S.match) as stopword,
Count(S.match) as stopwordcount
from StopWords S
group by GetText(S.match);

-- Retrieve the most used and least used stop word count
create view StopWordUsageCount as
        select Min(S.stopwordcount) as least, Max(S.stopwordcount) as most
from StopWordsCount S;

Funzioni predicato

Le funzioni predicato verificano uno specifico predicato sui suoi argomenti di input e restituiscono un valore booleano corrispondente.

Gli argomenti di input per le funzioni predicato includono i valori di ritorno di altre funzioni scalari o aggregate, oltre a dizionari, espressioni regolari e altro ancora. Queste funzioni possono essere utilizzate all'interno della clausola where di un'istruzione select e della clausola having di un'istruzione extract.

E

La funzione And accetta un numero variabile di argomenti booleani e restituisce i risultati di un'operazione AND logica su tutti gli argomenti di input.

L'ottimizzatore AQL non prova a ottimizzare l'ordine di valutazione degli argomenti per questa funzione come parte dell'operazione AND logica. Se qualche input è null, il risultato è null.

Considera questo formato di query:

select ...
from ...
where And(predicate1, predicate2);

Di conseguenza, un formato di query che utilizza l'operazione AND ha spesso un'esecuzione molto più lenta della stessa query nel formato:

select ...
from ...
where predicate1 and predicate2;

Quando possibile, utilizza invece lo stile e la parola chiave SQL invece di questa funzione.

Contiene

La funzione Contains prende due intervalli (span) come argomenti:

Contains(<span1>, <span2>)

Questa funzione restituisce TRUE se span1 contiene completamente span2. Se span2 inizia a span1 o dopo il suo inizio, e termina a span1 o prima della sua fine, span2 è contenuto completamente. Se l'uno o l'altro argomento è null, la funzione restituisce null.

ContainsDict

La funzione ContainsDict controlla se il testo di un intervallo (span) contiene qualsiasi voce da uno specifico dizionario. La funzione accetta come argomenti di input un dizionario, una specifica di indicatore facoltativa e un intervallo (span) da valutare.

ContainsDict('<dictionary>', ['<flags>', ]<span>)

La funzione ContainsDict restituisce TRUE se l'intervallo (span) contiene una o più corrispondenze del dizionario. Gli indicatori possono essere Exact o IgnoreCase.

  • Se viene utilizzato Exact, viene eseguita una messa in corrispondenza sensibile a maiuscole/minuscole rispetto a ciascun termine nel dizionario.
  • Se viene utilizzato IgnoreCase, la messa in corrispondenza eseguita rispetto a ciascun termine nel dizionario non è sensibile a maiuscole/minuscole.
  • Se non è specificato alcun indicatore, il dizionario esegue la messa in corrispondenza in base agli eventuali indicatori specificati durante la sua creazione. Se non è stato specificato alcun indicatore durante la creazione, esegue la messa in corrispondenza utilizzando l'indicatore IgnoreCase.

Se l'intervallo (span) è null, la funzione restituisce null.

Il seguente esempio illustra l'utilizzo della funzione ContainsDict:

create dictionary EmployeePhoneDict as
(
 '121-222-2346', '121-234-1198', '121-235-8891'
);

create view PhoneNum as
extract regex /(\d{3})-(\d{3}-\d{4})/
    on between 4 and 5 tokens in D.text
    return
        group 1 as areaCode
        and group 2 as restOfNumber
        and group 0 as number
from Document D;

create view PhoneNumbers as
select P.number as number
from PhoneNum P
where ContainsDict('EmployeePhoneDict',P.number);

I dizionari sono sempre valutati ai limiti di token. Ad esempio, se un dizionario consiste nel termine fish, non esiste alcuna corrispondenza nel testo Let's go fishing!.

ContainsDicts

La funzione ContainsDicts controlla se il testo di un intervallo (span) contiene qualsiasi voce da qualsiasi specifico dizionario. La funzione accetta come argomenti di input due o più dizionari, una specifica di indicatore facoltativa e un intervallo (span) da valutare.

ContainsDicts('<dictionary>','<dictionary>','<dictionary>', ['<flags>', ]<span>)

La funzione ContainsDicts restituisce TRUE se l'intervallo (span) contiene una o più corrispondenze da almeno uno dei dizionari specificati. Gli indicatori possono essere Exact o IgnoreCase.

  • Se viene utilizzato Exact, viene eseguita una messa in corrispondenza sensibile a maiuscole/minuscole rispetto a ciascuno dei termini nei dizionari.
  • Se viene utilizzato IgnoreCase, la messa in corrispondenza eseguita rispetto a ciascuno dei termini nei dizionari non è sensibile a maiuscole/minuscole.
  • Se non è specificato alcun indicatore, il dizionario esegue la messa in corrispondenza in base agli eventuali indicatori specificati durante la sua creazione. Se non è stato specificato alcun indicatore durante la creazione, esegue la messa in corrispondenza utilizzando l'indicatore IgnoreCase.

Se uno o entrambi gli argomenti sono null, la funzione restituisce null.

Il seguente esempio illustra l'utilizzo della funzione ContainsDicts con l'indicatore Exact:

create view PersonWithFirstName as
select P.reference as reference
from Person P
where ContainsDicts(
'FirstNamesUsedGlobally',
'FirstNamesUsedInGermanyLong',
'NickNamesUsedGlobally',
'FirstNamesUsedInGermanyShort',
'FirstNamesUsedInItaly',
'FirstNamesUsedInFrance',
'Exact',
P.reference);

ContainsRegex

La funzione ContainsRegex verifica se il testo di un intervallo (span) corrisponde a una specifica espressione regolare. Questa funzione accetta un'espressione regolare con cui eseguire la messa in corrispondenza, una specifica di indicatore facoltativa e l'intervallo (span) di input rispetto al quale eseguire la messa in corrispondenza.

ContainsRegex(/<regular expression>/, ['<flags>', ]<span>)

La funzione restituisce TRUE se il testo dell'intervallo (span), che viene preso come una stringa Java™ separata, contiene una o più corrispondenze dell'espressione regolare. La funzione restituisce null se l'intervallo (span) è null. Gli indicatori facoltativi influenzano la modalità di funzionamento della messa a confronto, analogamente agli indicatori utilizzati nelle espressioni regolari Java.

La stringa di indicatori è formata combinando uno o più indicatori servendosi di | come separatore.

  • CANON_EQ
  • CASE_INSENSITIVE
  • DOTALL
  • LITERAL
  • MULTILINE
  • UNICODE (privo di significato senza CASE_INSENSITIVE)
  • UNIX_LINES

Un esempio di una stringa di indicatori è

'UNICODE | CASE_INSENSITIVE'

Considera questo esempio, dove ContainsRegex identifica i nomi prodotto insieme alle loro menzioni de numero versione sull'uno o l'altro lato. A differenza dell'esempio per MatchesRegex, una corrispondenza di numero versione non è identificata in modo stretto utilizzando regex ma dal contesto intorno a una menzione di nome prodotto contenente un token di cui viene eseguita la messa a corrispondenza rispetto al regex.


-- dictionary of product names
create dictionary ProductNamesDict as
(
  'IBM WebSphere Application Server',
  'Microsoft Windows',
  'Apple Mac OS',
  'IBM Rational Application Developer',
  'Apache HTTP Server',
  'Eclipse',
  'Google Android'
);

-- extract product names from input text
create view ProductNames as
extract
  dictionary 'ProductNamesDict'
  on D.text as name
from Document D;

-- gather context around product name mention
create view ProductNamesWithContext as
select
  P.name as name,
  LeftContext(P.name, 5) as leftctxt,
  RightContext(P.name, 5) as rightctxt
from ProductNames P;

-- use a regex to identify products with version number mentions on either sides of the product mention
create view ProductsWithVersionNumbers as
(
  select
    P.name as productname,
    P.leftctxt as productversion
  from ProductNamesWithContext P
  where ContainsRegex (/v\d((\.\d)+)?/, P.leftctxt)
)
union all
(
  select
    P.name as productname,
    P.rightctxt as productversion
  from ProductNamesWithContext P
  where ContainsRegex (/v\d((\.\d)+)?/, P.rightctxt)
);

Equals

La funzione Equals prende tue argomenti di tipo arbitrario:

Equals(<arg1>, <arg2>)

Due intervalli (span) sono considerati uguali se entrambi iniziano e finiscono agli stessi offset e contengono lo stesso testo. Se uno dei due o entrambi gli argomenti sono null, la funzione restituisce null.

Il seguente esempio illustra l'utilizzo della funzione Equals.

-- Select phone number spans whose text is equal to 001-543-2217
create view PhoneNumber as
select P.number as number
from PhoneNum P
where Equals('001-543-2217',GetText(P.number));

Follows

La funzione di predicato Follows prende due argomenti di intervallo (span) e due argomenti integer.

Follows(<span1>, <span2>, <minchar>, <maxchar>)

La funzione restituisce TRUE se il numero di caratteri tra la fine di span1 e l'inizio di span2 è compreso tra minchar e maxchar (inclusi). Se un qualsiasi argomento è null, la funzione restituisce null.

FollowsTok

La funzione di predicato FollowsTok è una versione di Follows; tuttavia, gli argomenti di distanza FollowsTok sono in termini di token invece di caratteri:

FollowsTok(<span1>, <span2>, <mintok>, <maxtok>)

La funzione FollowsTok restituisce TRUE se il numero di token tra la fine di span1 e l'inizio di span2 è compreso tra mintok e maxtok (inclusi). Se un qualsiasi argomento è null, la funzione restituisce null.

GreaterThan

La funzione di predicato GreaterThan prende due argomenti di tipo arbitrario:

GreaterThan(<arg1>, <arg2>)

La funzione restituisce TRUE se <arg1> è maggiore di <arg2>. La funzione restituisce FALSE se l'uno o l'altro argomento è null.

IsNull

La funzione IsNull verifica se i dati sono o meno null. Prende un singolo argomento di qualsiasi tipo e restituisce TRUE se il singolo argomento è null e, altrimenti, FALSE. La modalità di funzionamento di questo predicato e del predicato NotNull già definito è diversa da tutti gli altri predicati che restituiscono null su input null.

MatchesDict

La funzione MatchesDict prende un dizionario (come in un'estrazione di dizionario), una specifica di indicatore facoltativa e un intervallo (span) come argomenti:

MatchesDict('<dictionary>', ['<flags>', ]<span>)

La funzione MatchesDict restituisce TRUE se l'intervallo (span) corrisponde esattamente a uno o più dei termini nel dizionario. Gli indicatori possono essere Exact o IgnoreCase.

  • Se viene utilizzato Exact, viene eseguita una messa in corrispondenza sensibile a maiuscole/minuscole rispetto a ciascun termine nel dizionario.
  • Se viene utilizzato IgnoreCase, la messa in corrispondenza eseguita rispetto a ciascun termine nel dizionario non è sensibile a maiuscole/minuscole.
  • Se non è specificato alcun indicatore, il dizionario esegue la messa in corrispondenza in base agli eventuali indicatori specificati durante la sua creazione. Se non è stato specificato alcun indicatore durante la creazione, esegue la messa in corrispondenza utilizzando l'indicatore IgnoreCase.

Se un qualsiasi argomento è null, la funzione restituisce null.

I dizionari sono sempre valutati ai limiti di token. Ad esempio, se un dizionario consiste nel termine fish, non esiste alcuna corrispondenza nel testo Let's go fishing!.

MatchesRegex

La funzione MatchesRegex ha una sintassi simile a ContainsRegex. A differenza della funzione ContainsRegex, la funzione MatchesRegex restituisce TRUE solo se l'intero testo dell'intervallo (span), preso come una stringa Java separata, corrisponde all'espressione regolare. Se un qualsiasi argomento è null, la funzione restituisce null. Gli indicatori facoltativi influenzano la modalità di funzionamento della messa a confronto, analogamente agli indicatori utilizzati nelle espressioni regolari Java.

MatchesRegex(/<regular expression>/, ['<flags>', ]<span>)

La stringa di indicatori è formata combinando un sottoinsieme di questi indicatori utilizzando | come separatore:

  • CANON_EQ
  • CASE_INSENSITIVE
  • DOTALL
  • LITERAL
  • MULTILINE
  • UNICODE (privo di significato senza CASE_INSENSITIVE)
  • UNIX_LINES

Un esempio di una stringa di indicatori è

'UNICODE | CASE_INSENSITIVE'

Considera questo esempio, dove MatchesRegex viene utilizzato per identificare i nomi prodotto insieme alle loro menzioni del numero versione sulla destra. A differenza dell'esempio nella sezione ContainsRegex, il numero di versione esatto viene identificato come il token immediatamente successivo alla menzione del nome del prodotto.

-- gather right context around product name mention
create view ProductNamesWithContext as
select
  P.name as name,
  RightContext(P.name, 5) as rightctxt
from ProductNames P;

-- use a regex to identify products with version number mentions to the right
create view ProductsWithVersionNumbers as
select
  P.name as productname,
  P.rightctxt as productversion
from ProductNamesWithContext P
where MatchesRegex (/v\d((\.\d)+)?/, P.rightctxt);

Not

La funzione Not prende un singolo argomento booleano e restituisce il suo complemento. Se l'argomento è null, la funzione restituisce null.

NotNull

La funzione NotNull prende un singolo argomento di qualsiasi tipo.

Come suggerisce il suo nome, la funzione NotNull restituisce TRUE se il valore dell'argomento non è null e FALSE se l'argomento è null.

O

La funzione Or prende un numero variabile di argomenti booleani non nulli. Se un qualsiasi argomento è null, la funzione restituisce null.

La funzione Or restituisce TRUE se uno qualsiasi di essi dà come risultato TRUE.

Overlaps

La funzione Overlaps prende due argomenti di intervallo (span):

Overlaps(<span1>, <span2>)

La funzione restituisce TRUE se i due intervalli (span) di input si sovrappongono nel testo del documento. La funzione restituisce null se l'uno o l'altro argomento è null.

Funzioni scalari

Le funzioni scalari eseguono un'operazione sui valori di un campo su un insieme di tuple di input e restituiscono un valore non booleano, come Span, Text o Integer. Queste funzioni possono essere utilizzate all'interno dell'elenco select di un'istruzione select o di un'istruzione extract . Possono anche essere utilizzate come input per le funzioni predicato.

Se viene fornito un oggetto Text in cui è richiesto un oggetto Span, viene generato automaticamente un oggetto Span convertito, che è basato su questo oggetto Text, con offset di inizio e fine che coprono tutta la lunghezza dell'oggetto Text.

Se viene fornito un oggetto Span in cui è richiesto un oggetto Text, un oggetto Text convertito viene generato automaticamente dal valore di testo dell'oggetto Span.

Chomp

La funzione Chomp è simile all'operatore Chomp in Perl, tranne che Chomp opera sugli intervalli (span) anziché sulle stringhe:

Chomp(<span1>)

Il seguente esempio illustra l'utilizzo della funzione Chomp.

detag Document.text as DetaggedDoc
annotate
element 'a' as Anchor
with attribute 'href' as linkTarget;

create view Links as
select Chomp(A.linkTarget) as link
from Anchor A;

Se l'intervallo (span) di input contiene uno spazio vuoto all'inizio o alla fine, la funzione Chomp restringe l'intervallo (span) abbastanza da rimuovere lo spazio vuoto. La funzione restituisce quindi un nuovo intervallo (span) senza lo spazio vuoto iniziale o finale. Se l'intervallo (span) di input non ha uno spazio vuoto iniziale o finale, la funzione Chomp restituisce lo stesso intervallo (span). Se l'intervallo (span) di input è null, Chomp restituisce null.

CombineSpans

La funzione CombineSpans prende due intervalli (span) come input e restituisce quello più corto che copre completamente entrambi gli intervalli (span) di input se essi sono basati sullo stesso oggetto di testo.

CombineSpans(['IgnoreOrder',] <span1>, <span2>)

La funzione CombineSpans è sensibile all'ordine dei suoi intervalli (span) di input, a meno che non utilizzi il parametro IgnoreOrder. Quando viene utilizzato il parametro IgnoreOrder facoltativo, l'ordine dei due intervalli (span) viene ignorato.

Il seguente esempio illustra l'utilizzo della funzione CombineSpans.

create view FullName as
     select
             CombineSpans('IgnoreOrder',F.name, L.name) as fullName
     from
             FirstName F,
             LastName L
     where
             FollowsTok(F.name, L.name, 0,0);

La semantica della funzione è la seguente:

  • Se span1 o span2 è null o i due intervalli (span) sono su oggetti di testo diversi, la funzione restituisce null.
  • Altrimenti, se span1 è più piccolo di span2 o viene utilizzato il parametro IgnoreOrder, la funzione restituisce l'intervallo (span) più breve che copre sia span1 che span2.
  • Altrimenti (span1 è più grande di span2 e IgnoreOrder non viene utilizzato), la funzione restituisce un errore di runtime.

In base alla definizione di Span, i diversi scenari di argomenti per la funzione CombineSpans sono i seguenti:

  • Span 2 è sempre dopo l'arco 1. In altre parole, l'ordine da sinistra a destra è mantenuto:

    CombineSpans([0,7], [3,7]) returns the span [0,7]
    CombineSpans([0,7], [8,10]) returns the span [0,10]
    CombineSpans([0,7], [3,6]) returns the span [0,7]
    CombineSpans([0,7], [0,7]) returns the span [0,7]
    
  • Span 2 non è dopo span 1. In altre parole, l'ordine da sinistra a destra è non mantenuto:

    CombineSpans(‘IgnoreOrder’, [0,10], [0,7]) returns the span [0,10]
    CombineSpans(‘IgnoreOrder’, [3,6], [0,7]) returns the span [0,7]
    CombineSpans(‘IgnoreOrder’, [3,7], [0,7]) returns the span [0,7]
    CombineSpans(‘IgnoreOrder’, [8,10], [0,7]) returns the span [0,10]
    CombineSpans([3,6], [0,7]) will result in Runtime error as the IgnoreOrder flag has not been specified.
    

GetBegin e GetEnd

La funzione GetBegin prende un singolo argomento di intervallo (span) e restituisce l'offset di inizio dell'intervallo (span) di input.

Ad esempio,

GetBegin([5, 10])

restituisce il valore 5.

Analogamente, la funzione GetEnd restituisce l'offset di fine del suo intervallo (span) di input.

Il seguente esempio illustra l'utilizzo delle funzioni GetBegin e GetEnd.

create view PersonOffsets as
select GetBegin(P.name) as offsetBegin, GetEnd(P.name) as offsetEnd
from Person P;

Per entrambe queste funzioni, se l'argomento è null, la funzione restituisce null.

GetLanguage

La funzione GetLanguage prende un singolo argomento di intervallo (span) e restituisce il codice lingua di due lettere del testo di origine dell'intervallo (span). Se l'argomento è null, la funzione restituisce null.

Questa istruzione produce dei risultati significativi solo se l'origine dati sta aggiungendo tag ai campi di testo con le lingue appropriate.

GetLemma

La funzione GetLemma prende un singolo oggetto Span o Text come argomento e restituisce una stringa che contiene il formato lemmatizzato dell'intervallo (span) di input. Se l'argomento è null, la funzione restituisce null. Con le voci di dizionario per la corrispondenza dei lemmi, questa funzione può determinare il formato lemmatizzato dei diversi token come da restituzione del tokenizer. Ad esempio, per l'intervallo (span) went shopping GetLemma restituisce la stringa di lemma go shop.

I risultati di questa funzione rispettano le seguenti regole:

  • Se l'apertura di ingresso inizia all'inizio di un token e termina alla fine di un token, il risultato contiene la sequenza di lemmi che inizia con il lemma del primo token, seguito da uno spazio bianco, seguito dal lemma del secondo token, seguito da uno spazio bianco, e così via (per esempio, uccello di pesce gatto ...). Se il lemma per un token è costituito da spazi vuoti, esegui l'escape dello spazio vuoto utilizzando il carattere di barra rovesciata ( \ ).
  • Se l'intervallo (span) di input inizia o termina con uno spazio vuoto (ad esempio, se inizia tra due token e termina tra due token), la funzione ignora gli spazi vuoti iniziale e finale.
  • Se l'intervallo (span) di input inizia in mezzo a un token o termina in mezzo a un token, l'output consiste nel seguente contenuto, in questo ordine, e separato da uno spazio vuoto:
    • Il formato di superficie del primo token parziale, se esiste.
    • La sequenza di lemmi che corrispondono ai token completi dal primo all'ultimo. Se il lemma per uno qualsiasi dei token completi consiste di spazi vuoti, esegui l'escape degli spazi vuoti utilizzando il carattere di barra rovesciata (\).
    • Il formato di superficie dell'ultimo token parziale, se esiste.

Questa funzione restituisce un errore se il tokenizer utilizzato non è in grado di produrre lemmi.

Puoi utilizzare la funzione GetLemma() per creare dizionari di formati lemmizzati. Richiama GetLemma() su un input che contiene i termini di cui desideri includere il formato lemmizzato nel dizionario.

GetLength

La funzione GetLength prende un singolo argomento di intervallo (span) e restituisce la lunghezza dell'intervallo (span) di input. Se l'argomento è null, la funzione restituisce null.

Ad esempio,

GetLength([5, 12])

restituisce un valore di 7.

GetLengthTok

La funzione GetLengthTok prende un singolo argomento di intervallo (span) e restituisce la lunghezza dell'intervallo (span) di input nei token. Se l'argomento di input è null, la funzione restituisce null.

GetString

La funzione GetString prende un singolo oggetto AQL come suo argomento e restituisce un oggetto Text che è formato dalla rappresentazione di stringa dell'oggetto.

Per gli argomenti di intervallo (span) e di testo, il valore restituito è diverso da quelli restituiti da GetText(). Per gli oggetti Text, il valore restituito include le virgolette singole che racchiudono la stringa di testo. Per gli oggetti di intervallo (span), il valore restituito include inoltre gli offset nelle parentesi.

Per gli elenchi scalari, questa funzione restituisce i valori GetString() degli elementi dell'elenco, concatenati con caratteri punto e virgola. Per gli argomenti Integer, Float, Boolean e String, questa funzione restituisce il valore dell'argomento come una stringa. Per gli argomenti null, questa funzione restituisce null.

GetText

La funzione GetText prende un singolo intervallo (span) o testo come argomento. Per l'input di intervallo (span), restituisce l'oggetto di testo in base alla stringa di testo effettiva contrassegnata dall'intervallo (span). Per l'input di testo, restituisce l'oggetto di testo di input. Se l'input è null, questa funzione restituisce null. Ad esempio:

GetText([5, 12])

L'intervallo (span) restituisce la stringa secondaria del documento dalla posizione di carattere 5 - 12.

La funzione GetText ha due utilizzi primari.

Verifica dell'uguaglianza di stringa tra il testo contrassegnato da due intervalli (span).

-- Create a dictionary of company names
create dictionary CompanyNames as
('IBM', 'BigCorp', 'Initech');

-- Find all matches of the company names dictionary.
create view Company as
extract
    dictionary 'CompanyNames' on D.text as company
from Document D;


-- Create a table that maps company names to locations of
-- corporate headquarters.
create table NameToLocation (name Text, location Text) as
values
    ('IBM', 'USA'),
    ('BigCorp', 'Apex'),
    ('Initech', 'Dallas'),
    ('Acme Fake Company Names', 'Somewhere');

-- Use the table to augment the Company view with location
-- information.
create view CompanyLoc as
select N2C.location as loc, C.company as company
from Company C, NameToLocation N2C
where Equals(GetText(C.company), GetText(N2C.name));

output view CompanyLoc;

Suddivisione di un documento in documenti secondari più piccoli.

Ad esempio, se il documento principale è un blog formato da più voci di blog, puoi utilizzare GetText per creare un documento secondario per ogni voce di blog.

detag Document.text as DetaggedBlog
annotate
    element 'blog' as Blog
    with attribute 'name' as title;


create view BlogEntry as
select B.match as entry, B.title as title
from Blog B;

-- Turn each tuple in the BlogEntry view into a sub-document
create view BlogEntryDoc as
select GetText(B.title) as title, GetText(B.entry) as body
from BlogEntry B;

output view BlogEntryDoc;

--Dictionary for Companies
create dictionary CompanyNameDict as
(
    'A Corporation', 'B Corporation'
);

-- Run an extraction over the sub-documents.
-- The spans that this "extract" statement creates will have
-- offsets relative to the blog entries themselves, as opposed
-- to the original multi-entry document.
create view CompanyName as
extract dictionary 'CompanyNameDict' on B.body as name
from BlogEntryDoc B;

output view CompanyName;

LeftContext e RightContext

La funzione LeftContext prende un intervallo (Span) e un Integer come input.

LeftContext(<input span>, <nchars>)

La funzione LeftContext(<input span\>, <nchars\>) restituisce un nuovo span che contiene i caratteri nchars del documento immediatamente a sinistra di <input span\>. Se l'apertura di ingresso inizia meno di <nchars\> caratteri dall'inizio del documento, quindi LeftContext() restituisce un span che inizia all'inizio del documento e continua fino all'inizio dell'apertura di input.

Ad esempio, LeftContext([20, 30], 10) restituisce l'intervallo (span) [10, 20]. L'intervallo (span) LeftContext([5, 10], 10) restituisce [0, 5].

Se l'input inizia al primo carattere del documento, LeftContext() restituisce un intervallo (span) di lunghezza zero. Analogamente, la funzione RightContext restituisce il testo a destra del suo intervallo (span) di input. Per entrambe le funzioni, se l'uno o l'altro argomento è null, la funzione restituisce null.

LeftContextTok e RightContextTok

Le funzioni LeftContextTok e RightContextTok sono versioni di LeftContext e RightContext che prendono le distanze in termini di token.

LeftContextTok(<input span>, <num tokens>)
RightContextTok(<input span>, <num tokens>)

Il seguente esempio illustra l'utilizzo della funzione RightContextTok.

create view Salutation as
extract
 regex /Mr\.|Ms\.|Miss/
  on D.text as salutation
  from Document D;

--Select the token immediately following a Salutation span
create view NameCandidate as
select RightContextTok(S.salutation, 1) as name
from Salutation S;

Per entrambe le funzioni, se l'uno o l'altro argomento è null, la funzione restituisce null.

Remap

La funzione Remap prende un singolo argomento di intervallo (span):

Remap(<span>)

Se l'intervallo (span) di input è su un oggetto di testo che è stato prodotto trasformando un altro oggetto di testo, la funzione Remap converte l'intervallo (span) in un intervallo (span) sul testo di "origine" originale.

Ad esempio, se l'intervallo (span) N.name è su un documento da cui sono state rimosse le tag che viene prodotto eseguendo HTML tramite l'istruzione AQL detag, allora

Remap(<N.name>)

restituisce un intervallo (span) equivalente sull'HTML originale.

Se l'argomento di intervallo (span) è stato prodotto eseguendo l'istruzione detag su un documento vuoto, la funzione riesegue l'associazione degli intervalli (span) all'inizio del documento (in altre parole, Document.text[0-0]). Inoltre, se l'istruzione detag produce una stringa vuota, la funzione riesegue l'associazione degli intervalli (span) all'inizio del documento. La sola parte di AQL che produce tale oggetto di testo derivato è l'istruzione detag.

Il seguente esempio illustra l'utilizzo della funzione Remap:

-- Detag the HTML document and annotate the anchor tags
detag Document.text as DetagedDoc
    annotate
    element 'a' as Anchor;

-- Remap the Anchor Tags
create view AnchorTag as
select Remap(A.match) as anchor
from Anchor A;

Se l'argomento per Remap non è un oggetto di testo derivato o un intervallo (span) su un oggetto di testo derivato, la funzione genera un errore. Se l'argomento è null, la funzione restituisce null.

SpanBetween

La funzione SpanBetween prende due intervalli (span) come input e restituisce l'intervallo che copre esattamente il testo tra i due intervalli (span) se gli intervalli (span) sono basati sullo stesso oggetto di testo e restituisce null se sono basati su oggetti di testo differenti.

SpanBetween(['IgnoreOrder',] <span1>, <span2>)

Quando viene utilizzato il parametro IgnoreOrder facoltativo, l'ordine dei due intervalli viene ignorato dal compilatore AQL.

Se nessun testo esiste tra i due spans, allora SpanBetween restituisce un span vuoto che inizia alla fine di <span1>.

Come CombineSpans, SpanBetween è sensibile all'ordine dei suoi input, a meno che non si utilizzi il parametro IgnoreOrder . Quindi

SpanBetween([5, 10], [50, 60])

restituisce l'intervallo (span) [10, 50], mentre

SpanBetween([50, 60], [5, 10])

restituisce l'intervallo (span) [60, 60].

Se l'argomento per SpanBetween è null, la funzione restituisce null.

SpanIntersection

La funzione SpanIntersection prende due intervalli (span) come input e restituisce un intervallo (span) che copre il testo che entrambi gli input coprono se gli intervalli (span) sono basati sullo stesso oggetto di testo e restituisce null se sono basati su oggetti di testo differenti:

SpanIntersection(<span1>, <span2>)

Ad esempio,

SpanIntersection([5, 20], [10, 60])

restituisce l'intervallo (span) [10, 20], mentre

SpanIntersection([5, 20], [7, 10])

restituisce l'intervallo (span) [7, 10].

Se i due intervalli (span) non si sovrappongono, SpanIntersection restituisce null. Se l'uno o l'altro input di intervallo (span) è null, la funzione restituisce null.

SubSpanTok

La funzione SubSpanTok prende come input un intervallo (span) e una coppia di offset nell'intervallo (span);

SubSpanTok(<span>, <first_tok>, <last_tok>)

Come suggerisce il nome della funzione, gli argomenti <first_tok> e <last_tok> sono distanze in token, secondo qualunque tokenizer il sistema sia configurato per l'utilizzo.

La funzione SubSpanTok restituisce un nuovo intervallo (span) che copre l'intervallo indicato di token (inclusi il primo e ultimo valore indicati) all'interno dell'intervallo (span) di input. Se il range specificato inizia all'interno dell'intervallo (span) va oltre la fine dell'intervallo (span), viene restituita la parte del range contenuta. Se <first_tok> rappresenta una distanza oltre l'arco di riferimento, allora SubSpanTok restituisce un arco di lunghezza zero che inizia all'inizio dell'apertura di ingresso.

Se qualsiasi input è null, la funzione restituisce null.

ToLowerCase

La funzione ToLowerCase prende un singolo oggetto come suo argomento e restituisce una rappresentazione stringa in minuscolo dell'oggetto. La conversione in una stringa si verifica nello stesso modo in cui la funzione GetString() esegue la conversione.

L'uso primario di questa funzione è eseguire delle unioni di uguaglianza che non sono sensibili a maiuscole/minuscole.

where Equals(ToLowerCase(C.company), ToLowerCase(N2C.name))

Se l'oggetto di input è null, la funzione restituisce null.

Istruzione create function

Per eseguire operazioni sui valori estratti che non sono supportati da AQL, puoi definire delle funzioni personalizzate da utilizzare nelle regole di estrazione denominate UDF (user-defined functions).

AQL supporta le funzioni scalari definite dall'utente e le funzioni tabella definite dall'utente. Java™ e PMML sono i soli linguaggi di implementazione supportati per le UDF. Una funzione scalare restituisce un singolo valore scalare e una funzione tabella restituisce una o più tuple, in altre parole, una tabella.

Implementi le UDF (user-defined functions) eseguendo quattro passi:

  1. Implementazione della funzione

    AQL supporta le UDF (user-defined functions) implementate in Java o PMML .

  2. Sua dichiarazione in AQL.

    Puoi rendere le funzioni scalari definite dall'utente e i modelli di machine learning dai file PMML disponibili per AQL utilizzando l'istruzione create function.

  3. Suo utilizzo in AQL.

    Le UDF (user-defined functions) funzionano con le istruzioni e le clausole AQL.

  4. Esecuzione del debug della UDF.

    Poiché le UDF (user-defined functions) basata su Java sono implementate come metodi pubblici nelle classi Java, esegui il debug delle tue UDF nello stesso modo in cui esegui il debug dei tuoi programmi Java.

Implementazione di UDF (user-defined functions)

AQL supporta le UDF (user-defined functions) implementate in Java™ o PMML.

Questa sezione si concentra specificamente sulle UDF implementate in Java. Per le UDF implementate in PMML, il modello di machine learning è memorizzato all'interno del file XML PMML. Fare riferimento alla documentazione di PMML per come creare questi modelli: [http://dmg.org/pmml/v4-1/GeneralStructure.html]

Puoi implementare una UDF scalare come un metodo pubblico in una classe Java. Puoi implementare una UDF tabella come metodo pubblico in una classe Java che estende l'API com.ibm.avatar.api.udf.TableUDFBase. Inoltre, una UDF tabella può, facoltativamente, sovrascrivere il metodo initState() della superclasse com.ibm.avatar.api.udf.TableUDFBase.

Se la UDF ha un parametro di input di tipo Span, Text o ScalarList, o il tipo di ritorno della UDF è Span, Text o ScalarList, la classe Java deve importare le classi com.ibm.avatar.algebra.datamodel.Span, com.ibm.avatar.algebra.datamodel.Text o com.ibm.avatar.algebra.datamodel.ScalarList per la compilazione.

Le funzioni tabella richiedono delle API supplementari per fornire le informazioni sullo schema di output. Queste API appartengono alla classe di base com.ibm.systemt.api.udf.TableUDFbase. Se una classe secondaria contiene più di una funzione tabella, viene creato un oggetto Java separato per ciascuna istanza.

Perché il codice UDF richiami le risorse non di classe dal suo file JAR, il solo metodo supportato è getResourceAsStream(). Altri metodi per accedere alle risorse (come getResource(), getResources(), getSystemResource()) non sono supportati. Ad esempio, un file JAR UDF che contiene il file delle proprietà my.properties nel pacchetto com.ibm.myproject.udfs può accedervi con la seguente istruzione Java:

InputStream in = this.getClass().getClassLoader().
  getResourceAsStream(“com/ibm/myproject/udfs/my.properties”);

Ciclo di vita delle UDF implementate in Java

Le seguenti operazioni vengono eseguite quando l'estrattore viene compilato (l'API CompileAQL.compile(), istanziato (API OperatorGraph.createOG()) e convalidato (API OperatorGraph.validateOG()), esattamente una volta per ogni istruzione create function in AQL.

  1. Carica la classe Java che contiene il metodo UDF utilizzando un nuovo caricatore di classe. La classe viene ricercata all'interno del JAR UDF specificato nella corrispondente istruzione create function. Anche le eventuali altre classi richieste quando si carica questa classe vengono ricercate all'interno dello stesso JAR UDF e, se non vengono trovate, la ricerca viene delegata al caricatore di classe che ha istanziato il runtime.
  2. Crea un'istanza di tale classe.
  3. Per le UDF tabella, richiama il metodo initState().

Poiché questi passi vengono eseguiti per ogni istruzione create function, se una classe Java contiene più metodi UDF (e tutti i metodi vengono utilizzati in AQL in istruzioni create function differenti), la classe viene caricata più volte, ogni volta in un caricatore di classe separato (Passo 1). Inoltre, vengono create più istanze della classe (Passo 2) e il metodo initState() viene richiamato un volta per ogni istanza (Passo 3). Il motivo per cui ogni UDF risulta in un caricatore di classe separato è quello di consentire alle differenti UDF di utilizzare versioni differenti della stessa classe (o libreria).

Al runtime (API OperatorGraph.execute()), la classe UDF non viene caricata nuovamente perché viene caricata durante l'istanziazione dell'estrattore. Il metodo Java che implementa la UDF è richiamato quando necessario per calcolare i componenti dell'output. Quando l'estrattore viene utilizzato all'interno di un singolo thread, significa che esistono da zero a possibilmente molti richiami per ogni documenti di input (e molto probabilmente molteplici richiami nel corso della durata dell'oggetto Operator Graph). Quando l'estrattore è condiviso tra più thread, thread differenti possono accedere al metodo all'incirca allo stesso tempo (con input differenti).

Se hai bisogno che una parte specifica del codice UDF venga valutata esattamente una sola volta, ad esempio per inizializzare le strutture di dati di cui ha bisogno il metodo UDF nei richiami, il codice non deve essere inserito nel metodo di valutazione UDF poiché tale metodo viene molto probabilmente eseguito più volte nel corso della durata dell'estrattore (come l'oggetto OperatorGraph),ed è possibile che si acceda ad esso quasi simultaneamente quando l'estrattore è condiviso tra più thread. Invece:

  1. Per le UDF scalari, attieniti ai principi di programmazione Java standard. Ad esempio, inserisci il codice in un blocco statico.
  2. Per le UDF tabella, inserisci il codice nel metodo initState() oppure attieniti ai principi di programmazione Java standard. Ad esempio, inserisci il codice in un blocco statico.

Quando esegui tale operazione, ricordati che la classe potrebbe essere caricata più volte durante la compilazione, l'istanziazione e la convalida dell'estrattore, come spiegato nei passi da 1 a 3 in alto. Se il codice che istanzia l'UDF è inserito in un blocco statico, tale codice viene eseguito ogni volta che la classe viene caricata (potenzialmente più volte), introducendo quindi un sovraccarico durante la compilazione e l'istanziazione di Operator Graph. Se il sovraccarico è notevole, attieniti a queste prassi ottimali:

  • Per ridurre al minimo il sovraccarico durante la fase di compilazione, la prassi ottimale consiste nell'inserire le risorse pesanti della fase di compilazione come i dizionari di grandi dimensioni o le UDF con un lungo tempo di inizializzazione in un modulo AQL separato ed eseguine l'esportazione. Prova a compilare solo i moduli AQL che hanno subito modifiche e gli altri moduli che dipendono da essi.
  • Per ridurre al minimo il sovraccarico durante l'inizializzazione e la convalida dell'Operator Graph:
    1. Se il codice di inizializzazione è richiesto da un singolo metodo UDF, inserisci tale metodo UDF in una classe Java separata (e inserisci il codice di istanziazione pesante in un inizializzatore statico come in precedenza oppure utilizza qualche altro meccanismo per assicurarti che il codice venga eseguito una sola volta).
    2. Se il codice di inizializzazione è condiviso da più metodi UDF, runtime e AQL non forniscono un metodo esplicito per garantire che il codice di inizializzazione venga eseguito esattamente una sola volta. In una situazione del genere, se il tempo di inizializzazione è proibitivo, la sola soluzione consiste nell'inserire le risorse condivise e il codice di inizializzazione nel percorso classe di sistema. In altre parole, inserisci il codice di inizializzazione in una nuova classe MySeparateClass.java e memorizza il risultato dell'inizializzazione in una variabile statica di questa classe, come MySeparateClass.myVar. Assembla MySeparateClass.java insieme alle risorse necessarie durante l'inizializzazione in un file JAR e inserisci tale JAR nel percorso classe di sistema. I metodi UDF possono fare riferimento al modello inizializzato utilizzando la variabile statica MySeparateClass.myVar. Il codice di inizializzazione viene ora eseguito esattamente una sola volta, quando la classe MySeparateClass.java viene caricata dal caricatore di classe del sistema.

Suggerimento:

La rappresentazione compilata di un modulo (il file .tam) contiene il codice binario serializzato dell'UDF. Pertanto, se le istruzioni create function fanno riferimento allo stesso codice UDF in due moduli differenti, il codice UDF viene serializzato nella rappresentazione compilata di entrambi i moduli. In altre parole, il codice UDF viene serializzato due volte. In tali casi, puoi evitare la ridondanza creando un modulo separato che funge da libreria di UDF e riutilizzare tale libreria in altri moduli. Per creare una libreria di UDF, attieniti alla seguente procedura:

  1. Crea un modulo.
  2. Inserisci tutti i file JAR UDF all'interno di tale modulo.
  3. Definisci tutte le funzioni necessarie con le istruzioni create function.
  4. Esportale tutte con le istruzioni export function in modo che possano essere importate e utilizzate in altri moduli.

Esempi

Esempio 1: Esecuzione di una UDF scalare

Questo esempio mostra l'implementazione della UDF scalare denominata toUpperCase. Questa UDF prende come input un valore di tipo Span e genera in output un valore di stringa che consiste nel contenuto di testo dell'intervallo (Span) di input, convertito in maiuscole.

package com.ibm.biginsights.textanalytics.udf;
import com.ibm.avatar.algebra.datamodel.Span;

/**
  * @param s input Span
  * @return all upper-case version of the text of the input Span
  */
public String toUpperCase(Span s) {
  return s.getText().toUpperCase();
}

Esempio 2: Esecuzione di una UDF scalare che utilizza una tabella come input

Questo esempio mostra l'implementazione di una UDF scalare denominata TableConsumingScalarFunc. Questa UDF prende come input due elenchi di tuple e genera in output un valore stringa che concatena il contenuto dei due elenchi di tuple di input.

import com.ibm.avatar.algebra.datamodel.TupleList;

/**
  * Example implementation of a user-defined scalar function using a table as input
*/
public class TableConsumingScalarFunc
{

  /**
    * Main entry point to the `scalar` function. This function takes two lists of tuples and concatenates them into a single string.
    *
    * @param arg1 first set of tuples to merge
    * @param arg2 second set of tuples to merge
    * @return the two sets of tuples, concatenated
    */
  public String eval (TupleList arg1, TupleList arg2)
  {
    StringBuilder sb = new StringBuilder ();

    sb.append("Input1: ");
    sb.append(arg1.toPrettyString ());
    sb.append("\nInput2: ");
    sb.append(arg2.toPrettyString ());

    return sb.toString ();
  }
}

Esempio 3: Implementazione di una UDF tabella che utilizza una tabella come input

Questo esempio mostra l'implementazione di una UDF tabella denominata TableConsumingTableFunc. Questa UDF prende come input due elenchi di tuple e genera in output un singolo elenco di tuple che contiene le tuple dal primo input frammiste alle tuple dal secondo input. Nota che l'implementazione si estende dalla classe di base com.ibm.avatar.api.udf.TableUDFBase, che fornisce le API per ottenere gli schemi di input e output.

package com.ibm.test.udfs;

import java.lang.reflect.Method;

import com.ibm.avatar.algebra.datamodel.AbstractTupleSchema;
import com.ibm.avatar.algebra.datamodel.FieldCopier;
import com.ibm.avatar.algebra.datamodel.Tuple;
import com.ibm.avatar.algebra.datamodel.TupleList;
import com.ibm.avatar.algebra.datamodel.TupleSchema;
import com.ibm.avatar.api.exceptions.TableUDFException;
import com.ibm.avatar.api.udf.TableUDFBase;

/**
  * Example implementation of a user-defined table function
*/
public class TableConsumingTableFunc extends TableUDFBase
{

  /** Accessors for copying fields from input tuples to output tuples. */
  private FieldCopier arg1Copier, arg2Copier;

  /**
    * Main entry point to the `table` function. This function takes two lists of tuples and generates a new list of wide
    * tuples, where element i of the returned list is created by joining element i of the first input with element i of
    * the second input.
    *
    * @param arg1 first set of tuples to merge
    * @param arg2 second set of tuples to merge
    * @return the two sets of tuples, interleaved
    */
  public TupleList eval (TupleList arg1, TupleList arg2)
  {

    TupleSchema retSchema = getReturnTupleSchema ();
    TupleList ret = new TupleList (retSchema);

    // We skip any records that go off the end
    int numRecs = Math.min (arg1.size (), arg2.size ());

    for (int i = 0; i < numRecs; i++) {
      Tuple retTuple = retSchema.createTup ();

      Tuple inTup1 = arg1.getElemAtIndex (i);
      Tuple inTup2 = arg2.getElemAtIndex (i);

      arg1Copier.copyVals (inTup1, retTuple);
      arg2Copier.copyVals (inTup2, retTuple);

      // System.err.printf ("%s + %s = %s\n", inTup1, inTup2, retTuple);

      ret.add (retTuple);
    }

    return ret;
  }

  /**
    * Initialize the internal state of the `table` function. In this case, we create accessors to copy fields from input
    * tuples to output tuples.
    *
    * @see com.ibm.avatar.api.udf.TableUDFBase#initState() for detailed description
    */
  @Override
  public void initState () throws TableUDFException
  {
    // Create accessors to do the work of copying fields from input tuples to output tuples
    AbstractTupleSchema arg1Schema = getRuntimeArgSchema ().getFieldTypeByIx (0).getRecordSchema ();
    AbstractTupleSchema arg2Schema = getRuntimeArgSchema ().getFieldTypeByIx (1).getRecordSchema ();
    TupleSchema retSchema = getReturnTupleSchema ();

    // Create offsets tables for a straightforward copy.
    String[] srcs1 = new String[arg1Schema.size ()];
    String[] dests1 = new String[arg1Schema.size ()];
    String[] srcs2 = new String[arg2Schema.size ()];
    String[] dests2 = new String[arg2Schema.size ()];

    for (int i = 0; i < srcs1.length; i++) {
      srcs1[i] = arg1Schema.getFieldNameByIx (i);
      dests1[i] = retSchema.getFieldNameByIx (i);
    }
    for (int i = 0; i < srcs2.length; i++) {
      srcs2[i] = arg2Schema.getFieldNameByIx (i);
      dests2[i] = retSchema.getFieldNameByIx (i + srcs1.length);
    }

    arg1Copier = retSchema.fieldCopier (arg1Schema, srcs1, dests1);
    arg2Copier = retSchema.fieldCopier (arg2Schema, srcs2, dests2);
  }

  /**
    * Check the validity of tuple schemas given in the AQL “create function”.
    *
    * @see com.ibm.avatar.api.udf.TableUDFBase#validateSchema(TupleSchema, TupleSchema, TupleSchema, Method, Boolean) for
    *      description of arguments
    */
  @Override
  public void validateSchema (TupleSchema declaredInputSchema, TupleSchema runtimeInputSchema,
    TupleSchema returnSchema, Method methodInfo, boolean compileTime) throws TableUDFException
  {
    // The output schema should contain the columns of the two input schemas in order.
    AbstractTupleSchema arg1Schema = declaredInputSchema.getFieldTypeByIx (0).getRecordSchema ();
    AbstractTupleSchema arg2Schema = declaredInputSchema.getFieldTypeByIx (1).getRecordSchema ();

    System.err.printf ("TableConsumingTableFunc: Input schemas are %s and %s\n", arg1Schema, arg2Schema);

    // First check sizes
    if (returnSchema.size () != arg1Schema.size () + arg2Schema.size ()) { throw new TableUDFException (
      "Schema sizes don't match (%d + %d != %d)", arg1Schema.size (), arg2Schema.size (), returnSchema.size ()); }

    // Then check types
    for (int i = 0; i < arg1Schema.size (); i++) {
      if (false == (arg1Schema.getFieldTypeByIx (i).equals (returnSchema.getFieldTypeByIx (i)))) { throw new TableUDFException (
        "Field type %d of output doesn't match corresponding field of first input arg (%s != %s)", i,
        returnSchema.getFieldTypeByIx (i), arg1Schema.getFieldTypeByIx (i)); }
    }

    for (int i = 0; i < arg2Schema.size (); i++) {
      if (false == (arg2Schema.getFieldTypeByIx (i).equals (returnSchema.getFieldTypeByIx (i + arg1Schema.size ())))) { throw new TableUDFException (
        "Field type %d of output doesn't match corresponding field of first input arg (%s != %s)", i
          + arg1Schema.size (), returnSchema.getFieldTypeByIx (i + arg1Schema.size ()), arg2Schema.getFieldTypeByIx (i)); }
    }
  }

}

Dichiarazione di UDF (user-defined functions)

Puoi rendere le funzioni scalari definite dall'utente e i modelli di machine learning dai file PMML disponibili per AQL utilizzando l'istruzione create function.

Sintassi

La sintassi generale della istruzione create function è la seguente:

create function <function-name>(<input-schema-definition>)
return <return-type> [like <column-name>] | table ( <output-schema-definition)
external_name <ext-name>
language [java | pmml]
[deterministic | not deterministic]
[return null on null input | called on null input];
<input-schema-definition>
<column-name> <data-type> | table (<output-schema-definition>) as locator [,<column-name> <data-type> | table (<output-schema-definition>) as locator ]*
<output-schema-definition>
<column-name> <data-type> [,<column-name> <data-type>]*

Descrizione

  • <function-name\>

    Il <function-name\> dichiara il nome AQL dell'UDF. All'UDF si fa riferimento nel codice AQL con questo nome

  • <input-schema-definition\>

    Specifica i parametri di input dell'UDF. Un parametro di input ha un nome, che viene specificato come <column-name\>, e può essere un tipo scalare o un localizzatore di tabella. Quando il linguaggio è PMML, la funzione deve prendere una singola tabella denominata params come argomento.

  • <column-name\>

    Specifica il nome di una colonna nell'input o nell'output dell'UDF.

  • <data-type\>

    Il tipo di un parametro scalare di input all'UDF, il tipo di una colonna nello schema di una tabella di input all'UDF oppure nello schema della tabella di output dell'UDF. I valori possibili per <data-type\> sono Interi, Float, String, Text, Span, Boolean o ScalarList.

  • table (<output-schema-definition\>) as locator

    Il tipo di input consente a una funzione di prendere come input l'intero contenuto di una specifica vista AQL come da suo calcolo sul documento corrente. Il parametro locator fa riferimento alle viste o alle tabelle come argomenti.

  • <return-type\>

    Per le UDF scalari, il <return-type\> specifica il tipo di valore scalare restituito dall'UDF. I valori possibili per il tipo di ritorno sono: Integer, Float, String, Text, Span, Boolean o ScalarList. Se il tipo di ritorno è Integer, la funzione Java™ che implementa l'UDF restituisce gli oggetti di tipo Integer. L'implementazione UDF non può restituire il tipo primitivo int. Se il tipo di ritorno è Text o Span, specifica il parametro di input da cui viene derivato il tipo di ritorno. Puoi specificare il parametro di input utilizzando la specifica like facoltativa, poiché gli intervalli (span) sono sempre da una colonna sottostante. Se il tipo di ritorno è ScalarList, specifica il parametro di input da cui deve essere dedotto il tipo scalare all'interno della ScalarList. Quando il linguaggio è PMML, la funzione deve restituire una tabella.

  • <output-schema-definition\>

    Per le UDF di tabella, la <output-schema-definition\> specifica lo schema di output della tabella restituita dall'UDF, compresi i nomi delle colonne e i relativi tipi.

  • <ext-name\>

    L'external_name specifica dove trovare l'implementazione dell'UDF. Quando la lingua è Java, si tratta di una stringa del modulo '<jar-file-name\>:<fully-qualified-class-name\>!<method-name\>', che consiste in tre parti:

    • Nome file JAR: quando compili l'AQL modulare, i riferimenti di ubicazione dei file JAR UDF devono essere relativi alla root del modulo in cui viene effettuato il riferimento.
    • Nome classe: nome classe completo che contiene l'implementazione UDF.
    • Nome metodo: il metodo deve essere un metodo pubblico della classe. La firma del metodo deve corrispondere ai tipi di parametro specificati nell'istruzione create function. La conversione di tipo automatica non viene eseguita dal componente di runtime. Quando il linguaggio è PMML, la clausola external_name specifica una stringa che è l'ubicazione del file PMML relativa alla directory root del modulo. L'attuale implementazione supporta i modelli espressi utilizzando lo standard PMML versione 4.1 e ne esegue la valutazione utilizzando la libreria org.jpmml versione 1.0.22.
  • language

    La specifica language punta al linguaggio di implementazione dell'UDF. Il componente di runtime supporta solo le UDF implementate in Java™.

  • deterministic/not deterministic

    Il valore deterministic/not deterministic facoltativo specifica se la funzione è senza stato. Una funzione deterministica restituisce sempre lo stesso valore per lo stesso insieme di valori di input.

  • return null on null input

    Il valore return null on null input facoltativo specifica la modalità di funzionamento della funzione quando uno o più dei valori di input sono null. Se viene specificato return null on null input, il sistema restituisce null su input null senza richiamare la UDF. Se viene specificato, l'UDF viene richiamata anche per i valori di input null.

Note di utilizzo per le UDF implementate in PMML

Le funzioni create dai file PMML prendono una singola tabella denominata params come loro argomento e genera in output una tabella. L'implementazione della funzione associa i campi di input tra lo schema di input e quello di output dichiarati nell'istruzione create function e lo schema specificato nel file PMML. In altre parole, la sezione DataDictionary che descrive i nomi e i tipi dei campi può comparire nei record di input e output che il modello produce e utilizza, la sezione MiningSchema che indica quali file denominati definiti nella sezione DataDictionary sono in ciascuna tupla che rappresenta un vettore di funzione e la sezione Output che indica quali campi denominati definiti nella sezione DataDictionary sono presenti in ciascuna tupla della rappresentazione esterna dell'output del modello. Queste funzioni devono essere funzioni tabella; ogni riga nella tabella viene passata al modello PMML e produce una riga di output.

Queste informazioni sullo schema sono necessarie perché i sistemi di tipo PMML e AQL non corrispondono perfettamente. Ad esempio, PMML ha diversi tipi per rappresentare le date/ore mentre AQL attualmente richiede che gli utenti codifichino le date/ore come valori stringa. Le informazioni sullo schema consentono anche agli sviluppatori che conoscono AQL ma non PMML di comprendere il set di regole AQL.

Il compilatore AQL controlla lo schema di input rispetto allo schema di input del file PMML per garantire che i due schemi siano compatibili. Se i due schemi contengono campi con lo stesso nome ma tipi incompatibili, la compilazione non riesce con un messaggio di errore appropriato. Se gli schemi di input od output della funzione contengono colonne supplementari o mancanti, la funzione resulting ignora queste colonne e non genera un errore. L'ordine di nomi colonna può essere diverso tra la definizione AQL e il file PMML. Se un nome colonna compare in entrambi gli schemi di input e output ma non nello schema PMML, i valori di tale colonna sono passati all'output della funzione.

Esempi

Esempio 1: Dichiarazione di UDF scalari con valori scalari come input utilizzando Java

Il seguente esempio mostra un'istruzione create function che dichiara una funzione denominata udfCombineSpans. La UDF (user-defined functions) prende due intervalli (span) come input e restituisce un intervallo (span) unito simile al primo intervallo (span) di input. La funzione Java™ UDF effettiva è assemblata in un file JAR denominato udfs.jar, nella directory udfjars. Il metodo che implementa la funzione è combineSpans nella classe com.ibm.test.udfs.MiscScalarFunc. Il metodo dichiara anche una funzione udfSpanGreaterThan che restituisce true se l'intervallo (span) è maggiore della dimensione specificata.

/**
* A function to combine two spans and return the resultant span from beginOffset of first span, to endOffset of second span
* @param p1 first input span
* @param p2 second input span
* @return a span from beginOffset of p1 till endOffset of p2
*/

create function udfCombineSpans(p1 Span, p2 Span)
return Span like p1
external_name 'udfjars/udfs.jar:com.ibm.test.udfs.MiscScalarFunc!combineSpans'
language java
deterministic
return null on null input;

/**
* A function to compare an input Span's size against an input size
* @param span input span
* @param size input size to be compared against
* @return Boolean true if input span's size is greater than input argument size, else false
*/

create function udfSpanGreaterThan(span Span, size Integer)
return Boolean
external_name 'udfjars/udfs.jar:com.ibm.test.udfs.MiscScalarFunc!spanGreaterThan'
language java
deterministic;

Il prossimo esempio mostra come dichiarare una funzione denominata udfCompareNames a cui viene dato un elenco di nomi nameList e un singolo nome myName. L'output è un elenco simile all'elenco di input, che contiene solo le voci da nameList simili a myName.

/**
* A function to compare an input string against a list of names
* and returns a list of entries from nameList similar to myName.
* @param nameList a list of names
* @param myName a name to compare against the list
* @return a list of entries from nameList similar to myName
*/

create function udfCompareNames(nameList ScalarList, myName String)
return ScalarList like nameList
external_name 'udfjars/udfs.jar:com.ibm.test.udfs.MiscScalarFunc!compareNames'
language java
deterministic;

Esempio 2: Dichiarazione di UDF scalari con tabelle come input utilizzando Java

Il seguente esempio illustra l'utilizzo del tipo di input table as locator. Mostra un'istruzione create function che dichiara una funzione denominata MyScalarFunc. L'implementazione Java™ della UDF viene assemblata all'interno della classe com.ibm.test.udfs.TableConsumingScalarFunc.

Questa UDF prende come input due elenchi di tuple e genera in output un valore stringa che concatena il contenuto dei due elenchi di tuple di input. L'implementazione Java™ dell'UDF è inclusa in Implementazione di UDF (user-defined functions).

-- Declare a simple scalar function that turns two tables into a big string
create function MyScalarFunc(
    firstArg table( spanVal Span ) as locator,
    secondArg table( spanVal Span, strVal Text ) as locator
)
return String
external_name
  'udfjars/udfs.jar:com.ibm.test.udfs.TableConsumingScalarFunc!eval'
language java
deterministic
called on null input;

Esempio 3: Dichiarazione di UDF tabella utilizzando Java

Il seguente esempio illustra l'utilizzo della clausola return table. L'esempio mostra un'istruzione create function che dichiara una funzione tabella denominata MyScalarFunc. L'implementazione Java™ della UDF viene assemblata all'interno della classe com.ibm.test.udfs.TableConsumingTableFunc. Questa UDF prende come input due elenchi di tuple e genera in output un elenco di tuple che unisce insieme gli elenchi di input. L'implementazione Java™ dell'UDF è inclusa in Implementazione di UDF (user-defined functions).

-- Declare a simple table function that "zips together" two input tables
create function MyTableFunc(
    firstArg table( spanVal Span ) as locator,
    secondArg table( spanVal Span, strVal Text ) as locator
)
return table( outSpan1 Span, outSpan2 Span, outStr Text)
external_name
  'udfjars/udfs.jar:com.ibm.test.udfs.TableConsumingTableFunc!eval'
language java
deterministic
called on null input;

Esempio 4: Dichiarazione di una UDF tabella implementata in PMML

Il seguente esempio mostra un'istruzione create function che dichiara una funzione tabella denominata IrisDecisionTree utilizzando il linguaggio PMML. L'implementazione PMML dell'UDF è specificata nel file IrisTree.xml, che è visualizzato nel seguente esempio. Il modello memorizzato in IrisTree.xml è un modello di struttura ad albero delle decisioni.

-- Scoring function based on a decision tree model stored in IrisTree.xml
create function IrisDecisionTree(
    params table(
        sepal_length Float,
        sepal_width Float,
        petal_length Float,
        petal_width Float
    ) as locator
)
return table( class Text, actual_class Text,
    -- This PMML file also defines additional output fields
    "Probability_Iris-setosa" Float,
    "Probability_Iris-versicolor" Float,
    "Probability_Iris-virginica" Float)
external_name 'IrisTree.xml'
language pmml;

IrisTree.xml

<?xml version="1.0"?>
<PMML version="3.2" xmlns="http://www.dmg.org/PMML-3_2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.dmg.org/PMML-3_2 http://www.dmg.org/v3-2/pmml-3-2.xsd">
  <Header copyright="Copyright (c) 2012 DMG" description="RPart Decision Tree Model">
  <Extension name="user" value="DMG" extender="Rattle/PMML"/>
  <Application name="Rattle/PMML" version="1.2.29"/>
  <Timestamp>2012-09-27 12:46:08</Timestamp>
  </Header>
  <DataDictionary numberOfFields="5">
  <DataField name="class" optype="categorical" dataType="string">
    <Value value="Iris-setosa"/>
    <Value value="Iris-versicolor"/>
    <Value value="Iris-virginica"/>
  </DataField>
  <DataField name="sepal_length" optype="continuous" dataType="double">
    <Interval closure="closedClosed" leftMargin="4.3" rightMargin="7.9"/>
  </DataField>
  <DataField name="sepal_width" optype="continuous" dataType="double">
    <Interval closure="closedClosed" leftMargin="2" rightMargin="4.4"/>
  </DataField>
  <DataField name="petal_length" optype="continuous" dataType="double">
    <Interval closure="closedClosed" leftMargin="1" rightMargin="6.91"/>
  </DataField>
  <DataField name="petal_width" optype="continuous" dataType="double">
    <Interval closure="closedClosed" leftMargin="0.1" rightMargin="2.5"/>
  </DataField>
  </DataDictionary>
  <TreeModel modelName="RPart_Model" functionName="classification" algorithmName="rpart" splitCharacteristic="binarySplit" missingValueStrategy="defaultChild">
  <MiningSchema>
    <MiningField name="class" usageType="predicted"/>
    <MiningField name="sepal_length" usageType="supplementary"/>
    <MiningField name="sepal_width" usageType="supplementary"/>
    <MiningField name="petal_length" usageType="active"/>
    <MiningField name="petal_width" usageType="supplementary"/>
  </MiningSchema>
  <Output>
    <OutputField name="class" optype="categorical" dataType="string" feature="predictedValue"/>
    <OutputField name="Probability_Iris-setosa" optype="continuous" dataType="double" feature="probability" value="Iris-setosa"/>
    <OutputField name="Probability_Iris-versicolor" optype="continuous" dataType="double" feature="probability" value="Iris-versicolor"/>
    <OutputField name="Probability_Iris-virginica" optype="continuous" dataType="double" feature="probability" value="Iris-virginica"/>
  </Output>
  <Node id="1" score="Iris-virginica" recordCount="105" defaultChild="3">
    <True/>
    <ScoreDistribution value="Iris-setosa" recordCount="33" confidence="0.314285714285714"/>
    <ScoreDistribution value="Iris-versicolor" recordCount="35" confidence="0.333333333333333"/>
    <ScoreDistribution value="Iris-virginica" recordCount="37" confidence="0.352380952380952"/>
    <Node id="2" score="Iris-setosa" recordCount="33">
    <SimplePredicate field="petal_length" operator="lessThan" value="2.6"/>
    <ScoreDistribution value="Iris-setosa" recordCount="33" confidence="1"/>
    <ScoreDistribution value="Iris-versicolor" recordCount="0" confidence="0"/>
    <ScoreDistribution value="Iris-virginica" recordCount="0" confidence="0"/>
    </Node>
    <Node id="3" score="Iris-virginica" recordCount="72" defaultChild="7">
    <SimplePredicate field="petal_length" operator="greaterOrEqual" value="2.6"/>
    <ScoreDistribution value="Iris-setosa" recordCount="0" confidence="0"/>
    <ScoreDistribution value="Iris-versicolor" recordCount="35" confidence="0.486111111111111"/>
    <ScoreDistribution value="Iris-virginica" recordCount="37" confidence="0.513888888888889"/>
    <Node id="6" score="Iris-versicolor" recordCount="37">
      <SimplePredicate field="petal_length" operator="lessThan" value="4.85"/>
      <ScoreDistribution value="Iris-setosa" recordCount="0" confidence="0"/>
      <ScoreDistribution value="Iris-versicolor" recordCount="34" confidence="0.918918918918919"/>
      <ScoreDistribution value="Iris-virginica" recordCount="3" confidence="0.0810810810810811"/>
    </Node>
    <Node id="7" score="Iris-virginica" recordCount="35">
      <SimplePredicate field="petal_length" operator="greaterOrEqual" value="4.85"/>
      <ScoreDistribution value="Iris-setosa" recordCount="0" confidence="0"/>
      <ScoreDistribution value="Iris-versicolor" recordCount="1" confidence="0.0285714285714286"/>
      <ScoreDistribution value="Iris-virginica" recordCount="34" confidence="0.971428571428571"/>
    </Node>
    </Node>
  </Node>
  </TreeModel>
</PMML>

Documentazione dell'istruzione create function con i commenti

Il commento AQL Doc per un'istruzione create function contiene le seguenti informazioni:

  • Una descrizione generale relativa alla funzione.
  • La descrizione @param che specifica ciascun nome di parametro utilizzato nella funzione. Indica il tipo del parametro, se è un tipo scalare o una tabella. Se il parametro è una tabella, descrivi lo schema della tabella, compresi i nomi e i tipi colonna nell'ordine in cui compaiono nello schema della tabella prevista come input.
  • La descrizione @return che specifica le informazioni restituite dalla funzione. Se la funzione restituisce una tabella, specifica lo schema di output della tabella, compresi i nomi e i tipi colonna nell'ordine in cui compaiono nello schema della tabella di output.
/**
* A function to compare an input string against a list of names
* and returns a list of entries from nameList similar to myName.
* @param nameList a list of names
* @param myName a name to compare against the list
* @return a list of entries from nameList similar to myName
*/

create function udfCompareNames(nameList ScalarList, myName String)
  return ScalarList like nameList
  external_name 'udfjars/udfs.jar:com.ibm.test.udfs.MiscScalarFunc!compareNames'
  language java
  deterministic;

Utilizzo di UDF (user-defined functions)

Le UDF (user-defined functions) funzionano con le istruzioni e le clausole AQL.

Le funzioni scalari definite dall'utente funzionano con le istruzioni e le clausole AQL, in modo analogo alle funzioni integrate. In modo specifico, le UDF scalari possono essere utilizzate nelle clausole select, where, having, group by e order by nello stesso modo delle funzioni scalari integrate, come GetBegin e LeftContext. Le funzioni scalari definite dall'utente che restituiscono un tipo booleano possono essere utilizzate come predicati nelle clausole where e having.

Le funzioni tabella definite dall'utente (UDF tabella) possono essere utilizzate nella clausola from di un'istruzione select o un'istruzione extract.

Esempi

Esempio 1. Utilizzo di UDF scalari implementate in Java con valori scalari come input

Questo esempio illustra come utilizzare le funzioni udfCombineSpans e udfSpanGreaterThan dichiarate in Dichiarazione di UDF (user-defined functions).

create function udfCombineSpans(p1 Span, p2 Span)
return Span like p1
external_name 'udfjars/udfs.jar:com.ibm.test.udfs.MiscScalarFunc!combineSpans'
language java
deterministic
return null on null input;

create function udfSpanGreaterThan(span Span, size Integer)
return Boolean
external_name 'udfjars/udfs.jar:com.ibm.test.udfs.MiscScalarFunc!spanGreaterThan'
language java
deterministic;

-- identify occurrences of given names in the document
create dictionary FirstNamesDict from file 'firstNames.dict';

create view FirstName as
extract dictionary 'FirstNamesDict' on D.text as name
from Document D;

-- Use a UDF to merge the name that is longer than 7 characters with the text to its right in a
-- way that is appropriate to the application.
create view NameAndContext as
select udfCombineSpans(F.name, RightContext(F.name, 50)) as name
from FirstName F
where udfSpanGreaterThan(F.name, 7);

Esempio 2: Utilizzo di UDF scalari implementate in Java con tabelle come input

Il seguente esempio mostra come utilizzare una funzione scalare che utilizza tabelle come input. Questo esempio illustra l'utilizzo della funzione UDF tabella MyScalarFunc, la cui implementazione Java™ è inclusa in Implementazione di UDF (user-defined functions). Sono gli stessi tipi colonna ma hanno nomi colonna differenti.

-- Declare a simple scalar function that turns two tables into a big string
create function MyScalarFunc(
    firstArg table( spanVal Span ) as locator,
    secondArg table( spanVal Span, strVal Text ) as locator
)
return String
external_name
  'udfjars/udfs.jar:com.ibm.test.udfs.TableConsumingScalarFunc!eval'
language java
deterministic
called on null input;

-- Create two views to serve as inputs to the `table` function.
-- Note that column names don't match, but types do.
create view FirstInputView as
extract regex /\d+/ on 1 token in D.text as match
from Document D;

create view SecondInputView as
select S.match as spanCol, 'Dummy string' as textCol
from
    (extract regex /[A-Z][a-z]+/ on 1 token in D.text as match
    from Document D) S;

-- Call the `scalar` function defined above from the select list.
create view ScalarFuncOutput as
select MyScalarFunc(FirstInputView, SecondInputView) as func
from Document D;

Esempio 3: Utilizzo di UDF tabella implementate in Java

Questo esempio illustra l'utilizzo della funzione UDF tabella MyTableFunc, la cui implementazione Java™ è inclusa in Implementazione di UDF (user-defined functions).

-- Declare a simple table function that "zips together" two input tables
create function MyTableFunc(
    firstArg table( spanVal Span ) as locator,
    secondArg table( spanVal Span, strVal Text ) as locator
)
return table( outSpan1 Span, outSpan2 Span, outStr Text)
external_name
  'udfjars/udfs.jar:com.ibm.test.udfs.TableConsumingTableFunc!eval'
language java
deterministic
called on null input;

-- Create two views to serve as inputs to the `table` function.
-- Note that column names don't match, but types do.
create view FirstInputView as
extract regex /\d+/ on 1 token in D.text as match
from Document D;


create view SecondInputView as
select S.match as spanCol, 'Dummy string' as textCol
from
    (extract regex /[A-Z][a-z]+/ on 1 token in D.text as match
    from Document D) S;

-- Use the `table` function
create view TabFuncOutput as
select T.outSpan1 as span1, T.outSpan2 as span2
from MyTableFunc(FirstInputView, SecondInputView) T;

Come nell'Esempio 2, l'esempio definisce due viste: FirstInputView con lo schema (match Span) e SecondInputView con lo schema (spanCol Span, textCol Text). L'ultima vista nell'esempio, TabFuncOutput richiama la funzione table MyTableFunc nella clausola from, con due viste di input. Come spiegato nell'Esempio 2, una vista è compatibile con un argomento di localizzatore tabella di una funzione, a condizione che il numero di colonne e i tipi colonna nello schema della vista di input e il localizzatore tabella corrispondano. Non è tuttavia necessario che i nomi colonna corrispondano.

Infine, la clausola select scarta la colonna outStr dalla tabella di output di MyTableFunc, conservando solo le prime due colonne outSpan1 e outSpan2.

Esempio 4: Utilizzo di una UDF tabella implementata in PMML

Questo esempio illustra l'utilizzo della funzione UDF tabella IrisDecisionTree che è dichiarata nell'esempio 4 di Dichiarazione di UDF (user-defined functions).

-- External view to hold the input records
create external view IrisData(
    sepal_length Float,
    sepal_width Float,
    petal_length Float,
    petal_width Float
)
external_name 'IrisData';
--Invoke the function on the input data records
create view IrisDecisionTreeOutput as
select * from IrisDecisionTree(IrisData);

output view IrisDecisionTreeOutput;