Referência de Annotation Query Language
A Anotation Query Language (AQL) é a linguagem principal usada para criar extratores de regras avançadas do IBM Watson® Knowledge Studio.
- Modelo de dados: o modelo de dados para AQL é semelhante ao modelo relacional padrão usado por um banco de dados SQL, como o DB2®. Todos os dados em AQL são armazenados em tuplas, registros de dados de uma ou mais colunas, ou campos. Uma coleção de tuplas forma uma visualização. Todas as tuplas em uma visualização devem ter o mesmo esquema que são os nomes e os tipos dos campos em todas as tuplas.
- Modelo de execução: o componente de tempo de execução tem um modelo de execução de um documento por vez. O componente de tempo de execução recebe uma coleção de documentos e executa o extrator em cada documento para extrair informações desse documento.
- Instruções AQL: ao usar instruções AQL, é possível criar e, em seguida, usar módulos, visualizações, tabelas, dicionários e funções.
- Funções integradas: a AQL tem uma coleção de funções integradas para uso em regras de extração.
- A instrução create function: para executar operações em valores extraídos não suportados pela AQL, é possível definir funções customizadas para usar em regras de extração chamadas funções definidas pelo usuário (UDFs).
Sintaxe da Annotation Query Language (AQL)
Como muitas linguagens de programação, a AQL é baseada em sintaxe comum e gramática.
A estrutura lexical de uma linguagem de programação é o conjunto de regras elementares que definem os tokens ou componentes básicos dessa linguagem, como suas palavras reservadas, identificadores, constantes e muito mais.
A sintaxe da AQL é semelhante à da SQL, mas existem várias diferenças importantes:
-
A AQL faz distinção entre maiúsculas e minúsculas.
-
A AQL não suporta atualmente recursos avançados de SQL, como subconsultas correlacionadas e consultas recursivas.
-
A AQL tem um novo tipo de instrução,
extract, que não está presente em SQL. -
A AQL não permite palavras-chave (palavras reservadas), como nomes de visualização, de coluna ou de função.
-
A AQL permite, mas não requer, que as expressões regulares sejam expressas na sintaxe Perl. As expressões regulares começam com uma barra (
/) e terminam com uma barra (/), como na sintaxe de Perl. A AQL também permite expressões regulares que começam com aspas simples (') e terminam com aspas simples ('). Por exemplo, é possível usar/regex/em vez de'regex'como a expressão regular em AQL. -
Identificadores: são usados para definir os nomes de objetos AQL, incluindo nomes de módulos, visualizações, tabelas, dicionários, funções, atributos e parâmetros de função.
-
Palavras reservadas: são palavras que têm um significado fixo no contexto da estrutura AQL e não podem ser redefinidas. Palavras-chave são palavras reservadas que têm significados especiais dentro da sintaxe do idioma.
-
Constantes: são valores fixos que podem ser um destes tipos de dados: sequência, número inteiro, valor flutuante ou booleano.
-
Comentários: use comentários para aumentar o código AQL com descrições básicas para ajudar que outros entendam o código e para gerar módulos compilados autoexplicativos.
-
Expressões: uma expressão AQL é uma combinação de um ou mais valores e funções escalares que são avaliados para um único valor escalar.
Identificadores
Identificadores são usados para definir os nomes de objetos da AQL, incluindo nomes de módulos, visualizações, tabelas, dicionários, funções, atributos e parâmetros de função.
Existem dois tipos de identificadores AQL que fazem distinção entre maiúsculas e minúsculas:
-
Identificador simples
Um identificador simples deve começar com uma letra minúscula (
a-z) ou maiúscula (A-Z) ou com o caractere sublinhado (_). Os caracteres seguintes podem ser letras minúsculas ou maiúsculas, o caractere sublinhado ou dígitos (0-9). Um identificador simples deve ser diferente de qualquer palavra chave em AQL. -
Identificador com aspas duplas
Um identificador entre aspas duplas começa e termina com um caractere de aspas duplas (
"). É possível usar qualquer caractere entre os caracteres de aspas duplas iniciais e finais. Os identificadores com aspas duplas não podem conter um caractere de ponto (.). Se um caractere de aspas duplas ocorrer dentro do nome, ele deverá ser escapado, prefixando-o com o caractere de barra invertida (\), por exemplo,\”.
Palavras reservadas
Palavras reservadas são palavras que têm um significado fixo dentro do contexto da estrutura AQL e não podem ser redefinidas. Palavras-chave são palavras reservadas que têm significados especiais dentro da sintaxe do idioma.
As palavras-chave reservadas de AQL a seguir não podem ser usadas como identificadores porque cada uma tem um propósito bem definido dentro da linguagem:
allallowallow_emptyalwaysandannotateasascendingasciiattributebetweenblocksbothbycalledcasecastccsidcharactercharacterscolumnsconsolidatecontent\_typecountcreatedefaultdescendingdetagdetectdeterministicdictionarydictionariesdocumentelementelseempty\_filesetentriesexactexportexternalexternal_nameextractfetchfilefirstflagsfoldingfromfunctiongrouphavingimportinincludeinfinityinline_matchinputintoinsensitivejavalanguageleftlemma_matchlikelimitmappingmatching_regexminusmodulenamenevernotnullononlyorderoutputpart_of_speechparts_of_speechparameterpatternpointpointspriorityregexregexesretainrequiredreturnrightrowsselectseparationsetspecificsplittabletaggerthentokenTokentokensunicodeunionupusingvaluesviewviewswhenwherewith
As seguintes palavras reservadas são os nomes de tipos escalares embutidos:
TextSpanIntegerFloatStringBooleanScalarList
Os outros nomes reservados a seguir não podem ser usados como identificadores:
DictionaryRegexConsolidateBlockBlockTokSentenceTokenizeRegexTokPosTag
Constantes
Constantes são valores fixos que podem ser um destes tipos de dados: String, Integer, Floatou Boolean.
As constantes são usadas na lista de seleção de uma cláusula select ou extract ou como argumentos em funções UDF ou integradas e predicados. A AQL suporta os tipos de constantes a seguir:
-
Constante de sequência
Uma sequência colocada entre aspas simples ('), por exemplo, 'uma sequência'.
-
Constante inteira
Um valor de número inteiro assinado de 32 bits que não é delimitado por aspas, por exemplo, 10 ou -1.
-
Constante flutuante
Um valor de vírgula flutuante de 32 bits de precisão única, não delimitado por aspas, por exemplo 3,14 ou -1,2.
-
Constante booleana
O valor true ou false não delimitado por aspas.
-
Constante nula
O valor nulo que não é delimitado por aspas.
Comentários
Use comentários para aumentar o código AQL com descrições básicas para ajudar os outros a entenderem o código e a gerar módulos compilados autoexplicativos.
Os comentários permitem que os desenvolvedores de AQL aumentem o código AQL com descrições básicas, para facilitar o entendimento do código-fonte AQL, e eles geram os módulos AQL compilados autoexplicativos. Três tipos de comentários são suportados na AQL:
-
Comentários de linha única
Os comentários de linha única começam com hifens duplos (
--). -
Comentários de múltiplas linhas
Os comentários de várias linhas começam com uma barra e um asterisco (
/*) e terminam com um asterisco e uma barra (*). Os comentários de várias linhas não podem ser aninhados. Por exemplo, o comentário de múltiplas linhas aninhadas a seguir não é permitido:/* A comment with a /*nested comment*/ */ -
Comentários de AQL Doc
Os comentários de AQL Doc fornecem uma maneira de descrever um módulo ou um objeto AQL em linguagem simples e de uma maneira rica em aspecto para compreensão contextual por outros usuários. Ao contrário dos comentários de linha única e dos comentários com diversas linhas, que são ignorados pelo Compilador AQL, os comentários de AQL Doc são serializados nos metadados de módulos compilados (arquivos .tam) e disponibilizados para consumo externo.
Todos os comentários em AQL Doc para instruções e módulos têm o formato a seguir:
-
O comentário está em texto sem formatação (nenhuma tag HTML é suportada).
-
O comentário começa com uma barra seguida de dois asteriscos (
/**) e termina com uma barra e um asterisco (*/). Opcionalmente, cada linha pode começar com um asterisco (*). -
Qualquer número de espaços em branco pode ser usado antes do asterisco.
-
As tags especiais prefixadas por um símbolo de arroba (
@) podem ser usadas no início de cada linha ou depois do asterisco opcional. -
Os comentários de AQL Doc não podem ser aninhados. Dois níveis de granularidade são suportados no sistema AQL Doc. O formato para documentar cada artefato é explicado em detalhes no tópico que descreve sua instrução e sintaxe.
-
Comentários de nível de módulo
Os comentários de nível de módulo estão contidos em um arquivo especial denominado module.info e localizado diretamente na pasta do módulo. Espera-se que os comentários descrevam a semântica do módulo e o esquema da visualização
Documentdo módulo. -
Comentários de nível de instrução
Os comentários de nível de instrução estão contidos no arquivo AQL de origem, precedendo imediatamente a instrução que cria um objeto AQL. Os comentários de linha única e comentários de múltiplas linhas são permitidos entre o comentário de AQL Doc de uma instrução e a instrução em si.
As instruções AQL de nível superior a seguir podem ser documentadas usando comentários de AQL Doc:
- A instrução create external view
- A instrução create external table
- A instrução create external dictionary
- A função create
- A instrução detag
- A instrução select... into Os comentários de AQL Doc são serializados dentro da representação compilada de um módulo.
-
Expressões
Uma expressão AQL é uma combinação de um ou mais valores e funções escalares que são avaliados para um único valor escalar.
As expressões podem ser de um dos quatro tipos:
- uma constante
- uma referência de coluna
- uma chamada de função escalar
- uma chamada de função agregada
Constante
Uma expressão pode ser uma constante do tipo Integer, Float ou String, como no exemplo a seguir:
select 'positive' as polarity
A expressão é a constante de sequência positive.
Referência de coluna
Uma expressão pode ser uma referência de coluna, como no exemplo a seguir:
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);
Essa visualização identifica texto que pode ser interpretado como o nome completo de uma pessoa (por exemplo, "Samuel Davis", "Vicky Rosenberg"). As expressões F.name e L.name são expressões de
referência de coluna que retornam a coluna de nome das visualizações F e L, respectivamente. A instrução from define as visualizações F e L como os nomes locais para as visualizações
FirstName e LastName (que definem nomes e sobrenomes válidos e não são mostrados nesse exemplo).
Chamada de função escalar
Uma expressão pode ser composta por uma ou mais chamadas de função escalar, cada uma podendo conter argumentos que também são expressões do tipo constante, referência de coluna ou chamada de função escalar. Uma chamada de função escalar pode ser uma das funções escalares integradas ou uma função escalar definida pelo usuário. Considere o exemplo a seguir:
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);
Essa visualização identifica os potenciais membros da família agrupando pessoas com os mesmos sobrenomes, imprimindo todos os nomes, com os sobrenomes em caracteres minúsculos (por exemplo, sobrenome keaton, nomes (Elyse, Alex, Diane)). As
saídas das chamadas de função GetText são usadas como argumentos para a chamada de função ToLowerCase para exibir os nomes em minúsculas. As expressões de chamada de função scalar neste exemplo são:
ToLowerCase, (GetText(P.lastname), ToLowerCase(GetText(P.firstname)) e GetText(P.lastname).
Chamada de função agregada
Uma expressão pode ser uma chamada de função agregada. Esse tipo de expressão pode ter como argumentos outra expressão do tipo referência de coluna ou do tipo chamada de função escalar. O exemplo a seguir mostra uma chamada de função agregada com a expressão do tipo referência de coluna:
create view CountLastNames as
select Count(Person.lastname)
from Person;
A expressão é simplesmente Count(Person.lastname) e conta o número de anotações Person.lastname no documento. Um exemplo de chamada de função agregada com expressão do tipo chamada de função escalar existe no exemplo
anterior como List(GetText(P.firstname)) com a função agregada List usando uma função escalar GetText como um argumento para gerar uma lista de nomes. As expressões de chamada de função agregada são
permitidas somente como expressões na lista select de uma instrução select. As expressões de chamada de função agregada não são permitidas na lista select de uma instrução extract ou como
argumentos para uma chamada de função escalar ou agregada.
Modelo de dados
O modelo de dados para AQL é semelhante ao modelo relacional padrão que é usado por um banco de dados SQL, como o DB2®. Todos os dados em AQL são armazenados em tuplas, registros de dados de uma ou mais colunas, ou campos. Uma coleção de tuplas forma uma visualização. Todas as tuplas em uma visualização devem ter o mesmo esquema que são os nomes e os tipos dos campos em todas as tuplas.
O conteúdo do documento de entrada é representado como uma visualização especial chamada Documento.
Os campos de uma tupla devem pertencer a um dos tipos de dados embutidos da AQL:
-
Booleano
Um tipo de dados que tem um valor true ou false.
-
Valor flutuante
Um número de vírgula flutuante de precisão única.
-
Número inteiro
Um número inteiro assinado de 32 bits.
-
ScalarList
Uma coleção de valores do mesmo tipo escalar (Número inteiro, Valor flutuante, Texto ou Período). Um valor de tipo de dados ScalarList pode ser obtido como resultado da função agregada integrada AQL
List()ou como o resultado de uma UDF. -
Intervalo
Um Período é uma região contígua de um objeto de Texto, identificado por seus deslocamentos de início e de término no objeto de Texto. Suponha que seu texto de entrada seja:
Amelia Earhart is a pilot.O texto no Span [0-6] é
Amelia.Esse Span pode ser visualizado como:
0A1m2e3l4i5a6Da mesma forma, o texto no Span[20-25] é
pilot.Um Período de [x-x] representa o período entre o término de um caractere e o início do caractere seguinte. No exemplo anterior, [0-0] é uma sequência vazia antes do caractere
A. Da mesma forma, um intervalo de [3-3] é uma sequência de caracteres vazia entre os caractereseel.Um valor do tipo Período pode ser obtido como resultado de uma instrução
extract, de uma função escalar integrada ou de uma UDF. -
Texto
O tipo de dados AQL para representar uma sequência de caracteres. Um objeto de texto contém uma string Unicode, chamada de seu valor string. Quando uma sequência é formada como a concatenação de subsequências desconectadas de outro objeto de Texto, ela também contém referência ao objeto de Texto original e informações relevantes de mapeamento de deslocamento. Dois objetos Text serão considerados iguais entre si se todos os seus componentes forem correspondentemente iguais entre si.
-
Comparando valores do tipo Período e Texto Os fatores de priorização afetam as comparações entre valores dos tipos Período e Texto.
Comparando valores de tipo Span e Texto
Os fatores de priorização afetam as comparações entre os valores do tipo Span e o tipo Text.
Os valores do tipo Span e do tipo Text se comparam uns com os outros nestas maneiras:
- Um valor de span nulo é sempre classificado mais baixo do que outros valores.
- Um valor de texto é sempre classificado mais alto que um valor de span.
- Os valores do tipo Text serão classificados primeiro pela ordem lexical de seus valores de sequência, em seguida, por suas ordens originais de Text e pelas informações de mapeamento de deslocamento, se aplicáveis.
- Os valores do tipo Span são classificados primeiro por seus objetos de texto subjacentes, em seguida, por seu deslocamento inicial e, em seguida, por seu deslocamento final. O span com um deslocamento inicial menor é classificado mais baixo. Entre dois spans que iniciam no mesmo deslocamento, aquele com o menor deslocamento de extremidade inferior.
Modelo de execução
O componente de tempo de execução tem um modelo de execução de um documento por vez. O componente de tempo de execução recebe uma coleção de documentos e executa o extrator em cada documento para extrair informações desse documento.
Um extrator consiste em um ou mais módulos AQL para criar uma coleção de visualizações em que cada uma delas define uma relação. Algumas dessas visualizações são designadas como visualizações de saída, enquanto outras são visualizações não de
saída. As visualizações não de saída podem incluir algumas visualizações que são importadas para um módulo ou exportadas dele. É importante notar que visualizações de saída e visualizações exportadas são ortogonais. Por exemplo, uma visualização
que é exportada não se qualifica como uma visualização que é gerada. Além dessas visualizações, a visualização Document exclusiva representa o documento de entrada que é anotado por esse extrator.
Document view
No nível do módulo AQL, a visualização Document é uma visualização especial que representa o documento atual que está sendo anotado por esse módulo. Quando dois ou mais módulos são combinados para formar um extrator, a união sem
duplicata de esquemas de Document de todos os módulos é a visualização Document necessária. Use a instrução require document with columns para especificar o esquema da visualização Document. Se essa
instrução estiver ausente em um módulo, o esquema padrão assumido para a visualização Document será (text Text, label Text):
-
texto
O conteúdo textual do documento atual.
-
rótulo
O rótulo do documento atual que está sendo anotado.
A palavra-chave Document é reservada como um identificador para a visualização Document, que é preenchida automaticamente durante a execução. Portanto, não é possível definir outra visualização ou tabela com o mesmo nome. No entanto,
é possível usar a palavra Document como um identificador para nomes de atributos e aliases.
Instruções de AQL
Ao usar instruções AQL, é possível criar e, em seguida, usar módulos, visualizações, tabelas, dicionários e funções.
As instruções a seguir são suportadas em AQL:
-
Instruções para criar módulos e declarar a interação entre eles
A instrução module
A instrução export
A instrução import
-
Instruções para criação de objetos AQL: visualizações, dicionários, tabelas ou funções
As instruções create dictionary e create external dictionary
A instrução create table
A instrução create view
A instrução create external view
A instrução detag
A instrução extract
A instrução select
A instrução require document with columns
A instrução set default dictionary language
A instrução de criação de função
As especificações de sintaxe nas instruções AQL contêm colchetes ([ ]). Essas especificações indicam que os colchetes e as construções que eles contêm são opcionais quando a sintaxe correspondente é usada para escrever uma instrução.
Além disso, elas representam itens temporários para definir como especificar instâncias adicionais de uma construção ou um argumento.
A instrução module
Use a instrução module para criar um módulo que tenha os recursos necessários autocontidos. É possível exportar e importar esses recursos como objetos AQL para/de outros módulos.
Sintaxe
module <module-name\>;
Descrição
-
<module-name\>Declara que o arquivo atual faz parte do módulo denominado
<module-name\>. O nome do módulo deve ser um identificador simples. Os identificadores entre aspas dupla não são permitidos como nomes de módulo.Cada arquivo AQL dentro do módulo deve ter exatamente uma declaração de módulo, e esta declaração deve ser a primeira instrução em cada arquivo. Essa declaração estabelece um namespace idêntico ao module-name. Todas as visualizações (e outros objetos, como dicionários, tabelas e funções) declaradas em arquivos AQL dentro desse módulo estão localizadas nesse único namespace. Eles são acessíveis a todos os arquivos AQL neste espaço de nomes.
Todos os arquivos declarados como parte do módulo
<module-name\>devem estar em uma pasta chamada<module-name\>para fazer a aplicação deste namespace. Não existe nenhuma ordenação dos arquivos AQL dentro dessa pasta do módulo. O compilador de AQL examina todos os arquivos AQL do módulo e determina a ordem correta para compilar todas as visualizações, dicionários, tabelas e funções declaradas no módulo.
Observações de uso
- Quando o arquivo AQL subjacente não é localizado como parte de um módulo (AQL modular) e é compilado no modo de compatibilidade, essa instrução não é suportada.
- As dependências circulares entre as visualizações não são permitidas.
- Os módulos AQL não suportam submódulos.
- Os arquivos AQL dentro de subpastas da pasta do módulo de nível superior são ignorados.
Exemplos
Exemplo 1: módulo de amostra
No exemplo a seguir, a visualização TheMentions pertence ao módulo que é denominado sample.
module sample;
create dictionary GetTheDict as ('The', 'the');
create view TheMentions as
extract dictionary 'GetTheDict' on D.text as theMention
from Document D;
A instrução export
A instrução export em AQL é usada para exportar um objeto AQL do módulo atual para que ele possa ser importado e usado em outros módulos.
Sintaxe
export view|dictionary|table|function <object-name\>;
Descrição
-
view|dictionary|table|functionDefine o tipo de objeto a ser exportado. O tipo de objeto pode ser uma visualização, um dicionário, uma tabela ou uma função.
-
<object-name\>Define o nome do objeto a ser exportado. O
<object-name\>pode ser um identificador simples ou um identificador entre aspas duplas.
Observações de uso
-
Não é possível exportar nenhum dos objetos AQL importados. É possível criar o efeito de reexportar a visualização ou tabela no módulo atual criando uma nova visualização:
select * from <imported_view_name_or_table_name>; -
As instruções
export vieweoutput viewque são mostradas nos exemplos são ortogonais entre si. Ou seja, uma visualização de saída não é automaticamente uma visualização exportada, mas ela deve ser exportada explicitamente usando uma instruçãoexport. Uma visualização exportada não é automaticamente uma visualização de saída, mas ela deve ser explicitamente saída usando a instruçãooutput view. Nos exemplos, a instruçãoexporttenta exportar a visualização PersonName.FirstName, que é uma visualização importada. Essa tentativa causa um erro, o que significa que o desenvolvedor deve copiar a visualização importada para uma nova visualização e, em seguida, exportá-la.
Exemplos
Exemplo 1: criando visualizações e dicionários e, em seguida, exportando-os para uso em outros módulos
Este exemplo cria as visualizações FirstName e NotFirstName. A visualização FirstName coleta informações sobre os nomes representados no dicionário FirstNamesDictionary. A outra visualização coleta os nomes que permanecem ao excluir os nomes. Dois dicionários são necessários para tornar a extração de texto mais fácil. Um dicionário contém todos os nomes que você deseja procurar. O segundo dicionário, LastNamesDictionary, contém os sobrenomes a serem procurados. O dicionário FirstNamesDictionary é exportado para que possa ser usado em outros módulos. As visualizações FirstName e NotFirstName também são exportadas para que possam ser importadas e usadas em outros módulos, como a pessoa do módulo no Exemplo 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;
Exemplo 2: importando visualizações a serem usadas, mas exportando de forma inadequada, causando um erro
Este exemplo mostra a importação de duas visualizações. Essas visualizações foram exportadas do módulo personName no Exemplo 1. A pessoa do módulo agora pode importar e fazer referência a essas visualizações. No entanto, esse módulo tenta exportar a mesma visualização que ele importou, FirstName, o que causa um erro.
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;
A razão para o erro neste código é que uma visualização que é importada de um módulo não pode ser exportada no módulo atual. Além disso, as visualizações exportadas não são automaticamente visualizações de saída, a menos que você tenha definido
uma visualização de saída com a instrução output view.
A instrução import
É possível usar a instrução import para referenciar objetos que são exportados de outros módulos no contexto do módulo atual.
Sintaxe
import view|dictionary|table|function <object-name\>
from module <module-name\> [as <alias\>];
Descrição
-
view\|dictionary\|table\|functionIdentifica o tipo de objeto AQL a ser importado. O tipo do objeto é obrigatório.
-
<object-name\>O
<object-name\>pode ser um identificador simples ou um identificador entre aspas duplas. -
<module-name\>O
<module-name\>deve ser um identificador simples. -
<alias\>Esta forma da instrução de importação, também conhecida como
alias import, importa o objeto AQL especificado com o nome<alias\>(não o nome original) no namespace do módulo atual. É possível referenciar o elemento importado usando um alias não qualificado ou um alias qualificado com o nome do módulo atual (o módulo no qual o objeto AQL foi importado). Não é possível usar originalModule.elementName porque a instruçãoalias importimporta o elemento somente sob o nome de alias e não sob o nome original qualificado.
Observações de uso
-
Uma instrução de importação sem uma especificação de alias importa o objeto AQL especificado para o módulo atual. Ela torna o objeto AQL acessível às instruções AQL definidas no módulo atual com o nome qualificado
<original\_module\_name\>.<object-name\>. -
A instrução de importação é usada somente para importar objetos AQL de módulos diferentes do módulo atual. Um objeto que é declarado em um arquivo AQL do módulo é visível para qualquer outro arquivo AQL nesse mesmo módulo. Uma instrução de importação coloca objetos no contexto do módulo atual, e não no contexto do arquivo atual. Portanto, uma visualização que é importada por 1.aql dentro do módulo A torna-se visível para 2.aql dentro do mesmo módulo sem a necessidade de quaisquer instruções adicionais de importação.
-
Todas as instruções de importação devem seguir imediatamente após a declaração do módulo e devem preceder todos os outros tipos de instruções. Somente os objetos AQL que são exportados explicitamente de qualquer módulo podem ser importados em outro módulo. Se este requisito não for observado, resultará um erro de compilação.
-
Um erro de compilação é introduzido quando uma instrução
import viewintroduz um conflito de nomenclatura com qualquer instruçãocreate viewou outras instruções de importação do mesmo módulo (não apenas do arquivo atual). Essa restrição se aplica aoimportde outros objetos além de visualizações. -
O compilador de AQL adere às convenções de nomenclatura que são usadas em versões anteriores da AQL:
- Um módulo não pode conter uma visualização e uma tabela com o mesmo nome.
- Um dicionário com o mesmo nome de uma tabela ou visualização é permitido.
- Uma função com o mesmo nome de uma tabela, visualização ou dicionário é permitida.
-
Um erro de compilação é introduzido quando diferentes instruções de importação dentro de um ou múltiplos arquivos AQL no módulo dão o mesmo nome a diferentes objetos AQL.
-
Um erro de compilação é introduzido quando um arquivo AQL dentro de um módulo tenta fazer referência a outra visualização exportada de um módulo sem usar a instrução
import view. O mesmo se aplica a dicionários, tabelas ou funções. -
Quando dois arquivos AQL dentro de um módulo importam a mesma visualização X de outro módulo sob dois aliases diferentes, por exemplo, A e B, os dois aliases são tratados de forma sinônima. Essa regra se aplica também a tabelas, dicionários e funções.
Exemplos
Exemplo 1: criar visualizações que você exporta para serem importadas para outros módulos.
Este exemplo cria duas visualizações, FirstName e NotFirstName. A visualização FirstName coleta informações sobre os nomes representados no dicionário FirstNamesDictionary. A segunda visualização
coleta os nomes que ficam quando os nomes são excluídos. Dois dicionários são necessários para tornar a extração de texto mais fácil. Um dicionário contém todos os nomes que você deseja procurar. O segundo dicionário, LastNamesDictionary,
contém os sobrenomes a serem procurados. As visualizações FirstName e NotFirstName são exportadas para que possam ser importadas e usadas em outros módulos, como o módulo person nos Exemplos 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;
Exemplo 2: importando a visualização FirstName usando a importação de alias
Este exemplo importa uma das visualizações criadas e exportadas no Exemplo 1. Em seguida, a visualização PersonFirstName é gerada para que seus resultados possam ser exibidos.
A instrução de importação de amostra é conhecida como uma importação de alias. Ela importa a visualização FirstName, sem qualificador de módulo, para o namespace do módulo atual, person. A visualização importada pode
ser acessada somente por meio do nome de alias PersonFirstName e não por meio de qualquer outro formulário. Por exemplo, não é possível consultar a visualização importada como personName.FirstName porque ela é importada
somente por meio do nome de alias.
module person;
`import view FirstName from module personName as PersonFirstName;`
output view PersonFirstName;
Exemplo 3: importando a visualização NotFirstname sem usar a importação de alias
Esta instrução de importação de amostra importa o nome qualificado personName.NotFirstName (não o nome não qualificado da visualização) para o namespace do módulo atual, person. Consulte sempre a visualização importada usando
somente o nome qualificado. Qualquer outro modo de referência é sinalizado como erro do compilador.
module person;
`import view NotFirstName from module personName;`
output view personName.NotFirstName;
A instrução import module
É possível usar a instrução import module para importar e reutilizar os módulos AQL existentes.
Sintaxe
import module <module-name\>;
Descrição
-
<module-name\>Especifica o módulo a ser importado. O
<module-name\>deve ser um identificador simples.
Observações de uso
-
A instrução de importação é usada somente para importar objetos AQL de outros módulos, não do módulo atual.
-
Todas as instruções de importação devem seguir imediatamente após a declaração do módulo e devem preceder todos os outros tipos de instruções. Somente os objetos AQL que são exportados explicitamente de qualquer módulo podem ser importados em outro módulo. Se este requisito não for observado, resultará um erro de compilação.
-
Um erro de compilação é introduzido quando uma instrução
import viewintroduz um conflito de nomenclatura com qualquer instruçãocreate viewou outra instrução de importação do mesmo módulo (não apenas do arquivo atual). Esta restrição se aplica àimportde outros objetos AQL, além de visualizações. -
Um erro de compilação é introduzido quando um arquivo AQL dentro de um módulo tenta fazer referência a outra visualização exportada de um módulo sem usar a instrução
import view. O mesmo se aplica a dicionários, tabelas ou funções. -
Se dois arquivos AQL dentro de um módulo importarem a mesma visualização X de outro módulo sob dois aliases diferentes, por exemplo, A e B, os dois aliases serão tratados de forma sinônima. Essa regra se aplica também a tabelas, dicionários e funções.
Exemplos
Neste exemplo, a instrução import importa o nome qualificado de ambas as visualizações exportadas, personName.FirstName e personName.NotFirstName. Qualquer visualização que não seja exportada pelo módulo
personName não será importada como parte da instrução de importação
-
Exemplo 1: importar ambas as visualizações FirstName e NotFirstName
Este exemplo mostra todas as visualizações exportadas do módulo personName. As visualizações
FirstNameeNotFirstNameforam criadas na seção de exemplo da instrução de exportação.module personOther; -- The following statement would import both views FirstName and NotFirstName. import module personName;
A instrução set default dictionary language
A instrução set default dictionary language permite que um desenvolvedor de extractor customize o conjunto padrão de idiomas de correspondência de dicionário para o módulo de contenção.
Sintaxe
set default dictionary language as '<language codes\>';
Descrição
-
<language codes\>Especifica o idioma para compilação e a correspondência para dicionários do módulo que são declaradas sem uma especificação
with language asexplícita. O conjunto<language codes\>deve ser uma lista separada por vírgulas, sem espaços em branco, ao redor de cada código de idioma. A falha na observação desse requisito pode resultar em um erro de compilação.Essa instrução afeta os dicionários a seguir:
- Os dicionários que são explicitamente declarados no módulo atual usando a instrução
create dictionaryoucreate external dictionarye essa instrução não tem uma cláusulawith language as. - Os dicionários de arquivos externos.
- Em uma especificação de padrão de uma instrução
extract pattern, átomos do tipo'string'e do tipo<'string' [match parameters]>sem uma especificação explícitawith language as. Quando esta instrução está ausente de um módulo, o componente de tempo de execução assume como padrão um conjunto de idiomas de alemão, espanhol, inglês, francês, italiano e o idioma não especificado x. Ele é definido como um conjunto:[de,es,en,fr,it,x_unspecified]. Em um módulo, apenas uma instância dessa instrução pode existir.
- Os dicionários que são explicitamente declarados no módulo atual usando a instrução
Observações de uso
- A instrução
set default dictionary languagepode ser atualizada para melhorar a extensão de idiomas que são cobertos pelo extrator. Essa capacidade de incluir idiomas promove a facilidade de customização e a reutilização de extratores existentes.
Exemplos
Exemplo 1: especificando idiomas a serem usados para corresponder entradas de dicionário
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;
A instrução require document with columns
Usando a instrução require document with columns, é possível definir o esquema da visualização especial Document no tempo de compilação. Essa definição de esquema especifica a lista de campos obrigatórios e seus tipos
a serem localizados em cada tupla da visualização Document.
Sintaxe
require document with columns <columnName\> <columnType\>
[and <columnName\> <columnType\>]*;
Descrição
-
<columnName\>Especifica o nome da coluna a ser usada no esquema. O
<columnName\>é um identificador de atributo, que é um identificador simples ou um identificador entre aspas duplas. -
<columnType\>Especifica o tipo de coluna a ser usado no esquema da visualização
Document. O<columnType\>pode ser um dos tipos de dados a seguir: Número inteiro, Valor flutuante, Booleano ou Texto. -
[ and <columnName\> <columnType\> ]*Especifica nomes e tipos de colunas adicionais para o esquema da visualização
Document. São seguidas as mesmas regras de<columnName\>e<columnType\>.
Em versões anteriores da AQL, o esquema da visualização especial Document era predefinido para consistir em um único campo (text Text) ou em dois campos (text text, label Text). A escolha entre esses esquemas foi decidida em tempo
de execução. Usando a instrução require document with columns, é possível substituir o esquema de documento de entrada padrão no tempo de compilação.
Observações de uso
- Para o código AQL modular, o escopo de qualquer instrução
require document with columnsé o módulo no qual ela está definida. - Somente uma instrução
require document with columnsé permitida por arquivo AQL. Dentro de um único módulo ou um módulo genérico, pode haver zero, um ou múltiplos arquivos AQL que tenham uma instruçãorequire document with columns. Todos os arquivos AQL dentro de um módulo mesclam suas instruçõesrequire document with columnsno nível do módulo inteiro para formar umrequire document with columnsem todo o módulo. Essa instrução define o esquema da visualizaçãoDocumentpara esse módulo. Se nenhum dos arquivos AQL de um módulo ou um módulo genérico conter uma instrução necessária, o módulo possui um esquema padrão para a visualizaçãoDocument. Esse esquema consiste em duas colunas: (text Text, label Text). Nenhuma coluna padrão será estabelecida para a visualização especialDocumentse pelo menos um arquivo AQL no módulo tiver uma instruçãorequire document with columns. - Quando múltiplos módulos são combinados para formar um extrator, o esquema da visualização
Documentdo extrator inteiro é definido pela união sem duplicata de esquemas de Document para cada módulo. Uma exceção é emitida quando qualquer coluna localizada entre as diversas instruçõesrequire document with columnsé localizada como conflitante em seus requisitos de tipo entre os módulos. Por exemplo, um módulo requer uma coluna X com o tipo Y quando outro módulo que está sendo carregado com ele requer uma coluna X com o tipo Z. - Uma exceção será emitida ao executar um extrator se a tupla de documento de entrada fornecida não contiver todas as colunas necessárias. Uma exceção também será emitida se uma coluna não se adequar ao seu tipo necessário correspondente.
- Quando a instrução
require document with columnsestá presente dentro de um módulo, cada coluna da visualização especialDocumentque é referenciada deve ser declarada em pelo menos uma das instruçõesrequire document with columns. A instrução pode ser localizada em diferentes arquivos AQL dentro do mesmo módulo. No entanto, todas as instruçõesrequire document with columnsseriam mescladas no nível do módulo para formar uma instruçãorequire document with columnsem todo o módulo.
Exemplos
Exemplo 1: instrução require document com tipos de colunas semelhantes
O exemplo a seguir define um esquema de documento que contém quatro campos do mesmo tipo. Essa amostra AQL espera que cada tupla de documento da coleção de dados contenha quatro colunas, conforme definido no esquema do documento.
Consulte os formatos de documentos JSON para obter detalhes sobre como criar um documento que se adequa a um esquema.
module person;
-- Require document statement with similar field types
require document with columns
inputDocumentText Text
and inputDocumentLabel Text
and documentAuthor Text
and documentCreationDate Text;
Exemplo 2: instrução require document com tipos de colunas variados
A amostra a seguir define um esquema de documento que contém colunas de tipos de campo variados.
module sample;
-- Require document statement with varying field types
require document with columns
bookText Text
and purchaseCount Integer
and bookPrice Float
and isBookPopular Boolean;
Exemplo 3: mesclando esquemas de documento
O exemplo descreve como mesclar esquemas de documento que usam os arquivos 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;
O esquema mesclado é (firstName Text, lastName Text, socialSecurityNo Integer).
A instrução create view
Os componentes de nível superior de um extrator AQL são suas visualizações. As visualizações são instruções lógicas que definem, mas não necessariamente computam, um conjunto de tuplas.
Sintaxe
A instrução create view pode tomar uma das três formas. A forma mais simples define uma visualização lógica que é composta pelas tuplas de uma única instrução select ou extract. A segunda é um formato
de várias junções que define uma visualização que abrange as tuplas que surgem da união de multiconjuntos de várias instruções select ou extract. A terceira forma define uma nova visualização que contém a diferença
de conjunto entre as tuplas de duas instruções select ou 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\>);
Descrição
-
<viewname\>O
<viewname\>pode ser um identificador simples ou um identificador entre aspas duplas. Ele não pode conter o caractere de ponto. -
<select or extract statement\>A instrução
selectouextractcria saída que é usada para computar as tuplas da visualização contendo.
Observações de uso
- Os nomes da visualização fazem distinção entre maiúsculas e minúsculas. Por exemplo, Person, PERSON e person são nomes de visualização diferentes
- Duas visualizações dentro do mesmo módulo AQL não podem compartilhar um nome, o que as tornaria duplicadas. No entanto, duas visualizações com o mesmo nome podem existir em dois módulos diferentes, uma vez que seus nomes completos são exclusivos.
- Por padrão, uma visualização que é definida pela instrução
create viewé uma visualização não de saída até que ela seja especificada como uma visualização de saída. - As instruções
selectouextractdas formasunion alleminusdevem ter um esquema de saída compatível. Dois esquemas serão considerados compatíveis para uma operaçãounionouminusse tiverem o mesmo número de colunas, os nomes de colunas estiverem na mesma ordem e eles tiverem tipos de dados compatíveis:- Os campos do mesmo tipo de dados são compatíveis com
unionouminus. - Os Tipos de Dados de span e Texto são
unionouminuscompatíveis. No caso de uma união entre um tipo Span e um Text, o tipo de saída é um Span. No entanto, os objetos do tipo Text não são convertidos automaticamente em um tipo Span; a conversão automática acontece somente quando necessário por chamadas de função. - Dois
ScalarListssão compatíveis comunionouminus, independentemente do tipo escalar subjacente.
- Os campos do mesmo tipo de dados são compatíveis com
Exemplos
Exemplo 1: criando uma visualização com uma instrução select ou extract
No exemplo abaixo, a visualização Phone usa uma instrução extract para preparar suas tuplas. A visualização PhoneNumber usa uma instrução select para escolher campos específicos por meio
da visualização 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;
Exemplo 2: criando uma visualização com a instrução Union All
A visualização AllPhoneNums prepara um conjunto sindicalizado das tuplas das visualizações Phone e Extension. As duas visualizações que estão sendo sindicalizadas têm o mesmo esquema.
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);
Exemplo 3: criando uma visualização com a instrução Minus
O exemplo a seguir mostra como é possível usar minus para filtrar tuplas indesejadas de um conjunto de tuplas.
create view Organization as
(select * from OrganizationCandidates)
minus
(select * from InvalidOrganizations);
Exemplo 4: compatibilidade de esquema para minus
É importante observar que os spans sobre um texto de destino diferente não são do mesmo tipo. Considere o exemplo de AQL a seguir que explica essa diferença usando uma literal de 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);
Em vez da saída esperada de uma lista de tuplas vazia, a saída é um conjunto de registros que têm 'uma sequência' como um valor de campo.
Embora os conteúdos das visualizações OneString e TheSameString pareçam idênticos, os valores de texto reais têm diferentes objetos AQL subjacentes. O tipo de OneString.match é 'Span sobre OneString.match'.
O tipo de TheSameString.match é 'Span sobre TheSameString.match'. Uma vez que os tipos de campo são diferentes, eles não são compatíveis para propósitos de comparação.
Para obter a saída desejada da lista de tuplas vazias, deve-se comparar valores do mesmo tipo. No exemplo a seguir, a função GetString() converte objetos de período em objetos de sequência de caracteres para transmitir tipos compatíveis
para a operação minus.
create view Subtraction as
(select GetString(R.match) from OneString R)
minus
(select GetString(R.match) from TheSameString R);
Documentando a instrução create view com o AQL Doc
O comentário do AQL Doc para uma instrução create view contém as seguintes informações:
- Descrição geral sobre a visualização.
- @field para cada nome de coluna na visualização.
Exemplo
/**
* 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;
A instrução output view
A instrução output view define uma visualização para ser uma visualização de saída. O componente de tempo de execução gera somente as tuplas de visualizações que são marcadas como visualizações de saída. O compilador de AQL compila
somente visualizações que são marcadas como saída ou exportação ou atingíveis por meio de visualizações que são marcadas como saída ou exportação.
Sintaxe
output view <view-name\> [as '<alias\>'];
Descrição
-
<view-name\>O nome da visualização a ser gerada, como conhecido no namespace do módulo atual. O
<view-name\>é um identificador simples ou um identificador entre aspas duplas. A visualização integradaDocumentnão pode ser gerada. -
[as '<alias\>']*Define um nome
<alias\>para a visualização de saída. Quando o alias opcional não é especificado, a visualização é gerada sob os nomes a seguir:- Na AQL modular, a visualização é emitida com o nome
<module-name\>.<view-name\>, em que<module-name\>é o nome do módulo no qual a visualização é originalmente definida (que pode ser diferente do módulo no qual ela é gerada). - Na AQL 1.4 ou anterior, a visualização é gerada com o nome
<view-name\>A instruçãooutput ... as <alias\>é útil quando você personaliza um extrator para diferentes domínios. O uso do nome<alias\>ao definir uma visualização de saída garante que os nomes de saída sejam idênticos em diferentes implementações da customização.
O nome
<alias\>não pode ser usado em outra instruçãoselectouexport. É necessário que<alias\>esteja entre aspas simples e o nome<alias\>pode conter períodos. - Na AQL modular, a visualização é emitida com o nome
Observações de uso
- Quando um extrator AQL é executado, ele computa tuplas resultantes para cada visualização que é definida como uma visualização de saída. As tuplas de qualquer visualização não de saída também são computadas, mas somente quando elas são necessárias para computar as tuplas resultantes de uma visualização de saída.
- Em AQL modular, a instrução
output viewgera as tuplas da visualização sob o nome completo da visualização que é qualificado por seu nome do módulo. Considere o exemplo a seguir em que a instruçãooutput view Person;resulta na saída da visualizaçãopersonModule.Person:
module personModule;
create view Person as
extract dictionary 'FamousPeopleDict' on D.text as match
from Document D;
output view Person;
Esse comportamento se aplica para qualquer saída de visualização sem um alias, independentemente de a visualização ser gerada no módulo no qual ela é definida ou em um módulo no qual ela é importada, mesmo quando a importação é de alias. Por
exemplo, na visualização de saída MyPerson, esse exemplo resulta na visualização sendo gerada com seu nome qualificado original personModule.Person e não com seu alias local MyPerson
module employeeModule;
import view Person from module personModule as MyPerson;
output view MyPerson;
- A instrução de alias de saída é útil quando se constrói bibliotecas de extratores nas quais o mesmo tipo de entidade pode ter muitas implementações diferentes, dependendo do domínio de aplicativo ou do idioma dos documentos de entrada. O
principal benefício do uso de um alias quando você define uma visualização de saída é assegurar uma nomenclatura consistente entre as visualizações de saída. Uma nomenclatura consistente é esperada pela lógica do programa de um usuário
quando você processa múltiplos módulos em que cada um deles gera uma visualização semanticamente semelhante. No AQL modular, quando um nome de alias é usado em uma instrução
output view, as tuplas de uma visualização são saída sob o nome de alias especificado. Por exemplo, o código a seguir geraria os resultados sob o nome de alias PersonAlias e o nome de alias não é qualificado com o prefixo do módulo.
module personModule;
create view Person as
extract dictionary 'FamousPeopleDict' on D.text as match
from Document D;
output view Person as 'PersonAlias';
Exemplos
Os exemplos a seguir contêm dois módulos, personModuleFrench e personModuleEnglish. Cada módulo gera uma visualização, nomeadas PersonNameFrench e PersonNameEnglish. Suponha que módulos semelhantes, cada um dos quais gere visualizações que sejam variantes semânticas de um extrator para nomes de pessoa. Esses módulos são customizados para idiomas diferentes com a variação na customização dessa visualização para um idioma de entrada especificado. Portanto, um usuário pode querer que um programa use módulos nos quais a visualização de saída buscada seja denominada PersonName, independentemente dos módulos processados. Essa expectativa é normal, uma vez que se espera que cada módulo customizado para um idioma, domínio ou outro propósito produza vários resultados. O consumidor desses módulos não precisa alterar o algoritmo de seu programa para acomodar nomes de visualização de saída variados quando a semântica subjacente é semelhante.
No exemplo, como o alias PersonName é usado, o consumidor não precisa alterar o nome da visualização que é buscado. No entanto, os resultados podem variar dependendo dos módulos que são processados. No exemplo, as correspondências resultantes baseiam-se no francês (Exemplo 1) e no inglês (Exemplo 2).
Exemplo 1: as correspondências de resultado são baseadas em francês
O exemplo a seguir define uma visualização PersonNameFrench e gera-a sob um nome de alias neutro de implementação, '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';
Exemplo 2: as correspondências de resultado são baseadas em inglês
O exemplo a seguir define uma visualização PersonNameEnglish e gera-a sob um nome de alias neutro de implementação, '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';
O consumidor dos módulos de exemplo pode acessar as tuplas de saída por meio do nome de alias 'PersonName'. O consumidor não precisaria saber o módulo real por meio do qual os resultados são buscados.
A instrução extract
A instrução extract é usada para extrair recursos básicos diretamente do texto.
Sintaxe
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>];
Descrição
-
<select list\>Uma lista delimitada por vírgula de expressões de saída. Os resultados dessas expressões de saída são retornados como a saída da instrução
extract, com as tuplas geradas pela avaliação da especificação de extração. O formato de<select list\>é o mesmo que do<select list\>de uma instruçãoselect. -
<extraction specification\>Aplica a especificação de extração em todas as tuplas das visualizações definidas no
<from list\>. Renomeia as colunas de tuplas de acordo com seus aliases correspondentes que são especificados na instruçãoextract. Você pode utilizar uma das seguintes especificações de extração:- Expressões regulares
- Dicionários
- Divisões
- Bloqueios
- Parte do discurso
- Padrões de sequência
-
<from list\>Uma lista delimitada por vírgula que é a origem das tuplas por meio das quais os recursos devem ser selecionados. O formato de
<from list\>é semelhante ao formato do<from list\>da instruçãoselect. No entanto, se a instruçãoextractnão tiver uma especificação padrão,<from list\>poderá conter um único item. -
[having <having clause\>]Especifica um predicado de filtragem (no
<having clause\>) que é aplicado a cada tupla de saída extraída. Os nomes de campo que são especificados no<having clause\>referem-se a quaisquer aliases que sejam especificados no<select list\>. Essa cláusula é opcional. -
[consolidate on <column\>[using '<policy\>' ]]Define como manipular intervalos de sobreposição conforme definido na consolidação
<policy\>. Nesta especificação,<column\>deve ser o nome de um campo de saída que faz parte da instruçãoextract. Essa cláusula é opcional. -
[limit<maximum number of output tuples for each document\>]Limita o número de tuplas de saída de cada documento para o máximo especificado. Essa cláusula é opcional.
Observações de uso
A semântica da instrução extract é a seguinte:
- Avalie a especificação de extração sobre cada tupla da relação de entrada. Para cada resultado que a extração produz, é produzida uma tupla de saída que contém os valores extraídos, além de quaisquer colunas da tupla original especificadas
em
<select list\>. - Renomeie as colunas da tupla de saída de acordo com os aliases especificados como parte de
<select list\>e de<extraction specification\>. - Aplique qualquer predicados na cláusula
havingopcional para a tupla de saída resultante. - Consolide as tuplas que passam os predicados de acordo com a cláusula
consolidationopcional e inclua as tuplas resultantes na saída. - Se a cláusula
limitopcional estiver presente, limite a saída para o número especificado de tuplas para cada documento.
A semântica da cláusula from de uma instrução extract pattern é diferente de outras formas de instruções extract que não têm uma especificação de padrão. Se pelo menos uma das visualizações em <from list\> não contém nenhuma tupla em um determinado documento, a saída da instrução extract está vazia. Essa saída está vazia porque o conjunto de todas as combinações de tuplas nas visualizações de entrada está vazio.
No caso especial de instruções extract pattern, a cláusula from é um item temporário que declara os nomes de relações que estão envolvidas na especificação de padrão. A semântica da instrução é acionada apenas pela
especificação do padrão. Em particular, a saída da instrução pode ser não vazia mesmo quando algumas das visualizações de entrada estiverem vazias.
Exemplos
Exemplo 1: Extraindo números de telefone a partir de uma visualização pré-definida
Esta instrução extract de amostra avalia uma expressão regular para números de telefone dos Estados Unidos em todo o texto de entrada que é representado pela visualização predefinida Document. Em seguida, a saída é restrita aos
três primeiros números de telefone que são identificados por documento. Os nomes de campo na cláusula having referem-se aos aliases no início da instrução 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;
Exemplo 2: extraindo blocos de palavras alteradas para letras maiúsculas
Neste exemplo, a instrução extract identifica blocos de duas a três palavras alteradas para letras maiúsculas. Em AQL, um bloco refere-se a um span contíguo de tokens, neste caso, de dois a três tokens. Este exemplo também usa
uma política de consolidação para excluir blocos que estão contidos dentro de blocos maiores do conjunto de saída de tuplas.
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';
A cláusula consolidate é aplicada ao campo capswords pela especificação de blocos de extração. A diferença é que o campo de destino referido pela cláusula consolidation é um campo de saída da instrução
extract. O campo de destino da instrução select é um campo de entrada. Esse comportamento é semelhante ao da cláusula having.
Exemplo 3: uma instrução extract ou select aninhado como um nome de visualização
A visualização de entrada para uma instrução extract pode ser um nome de visualização, como no Exemplo 2, ou uma instrução extract ou select aninhada, como neste exemplo:
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;
Exemplo 4: extrair uma instrução com uma lista de seleção
Neste exemplo, extraímos correspondências para um padrão e, ao mesmo tempo, selecionamos múltiplos atributos por meio das visualizações de entrada.
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;
- Expressões regulares Use uma especificação de extração de expressão regular para identificar os padrões de correspondência contidos pela expressão regular no texto de entrada.
- Dicionários Use a especificação de extração de dicionário para extrair sequências do texto de entrada contidas em um dicionário de sequências.
- Divisões Use a especificação de extração de divisão para dividir um período grande em vários períodos menores.
- Blocos Use a especificação de extração de blocos para identificar blocos de períodos contíguos no texto de entrada.
- Parte do discurso Use a especificação de extração de parte do discurso para identificar locais de diferentes partes do discurso no texto de entrada.
- Padrões de sequência Use a especificação de extração de padrões para executar a correspondência de padrões em um documento de entrada e em outros períodos extraídos do documento de entrada.
Expressões regulares
Use uma especificação de extração de expressão regular para identificar padrões de correspondência que estão contidos pela expressão regular em todo o texto de entrada.
Sintaxe
regex[es] /<regex1>/
[and /<regex2>/ and ... and /<regex n>/]
[with flags '<flags string>']
on <token spec>] <name>.<column>
<grouping spec>
Descrição
-
regex[es] /<regex1\>/Especifica as expressões regulares a serem usadas na extração. Por padrão, a AQL usa a sintaxe de Perl para as expressões regulares, o que significa que os literais de expressão regular são colocados em dois caracteres de barra (//). As sequências de escape de expressão regular têm precedência sobre outros caracteres de escape. A AQL permite expressões regulares na sintaxe de sequência SQL, portanto, uma expressão regular para os números de telefone dos Estados Unidos pode ser expressa como qualquer um dos exemplos:
/\d{3}-\d{5}/'\\d{3}-\\d{5}' -
[and /<regex2\>/ and ... and /<regex n\>/ ]Lista mais expressões regulares para serem usadas na extração.
-
[with flags '<flags string\>']Especifica uma combinação de sinalizações para controlar a correspondência de expressão regular. Este parâmetro é opcional. Essas sinalizações correspondem a um subconjunto das sinalizações que são definidas na implementação Java™. Se a cadeia de bandeiras não for fornecida, a AQL usa apenas a bandeira
DOTALLpor padrão.Para especificar múltiplas sinalizações, separe-as com o caractere
|. Por exemplo, para especificar a correspondência de multilinhas, a correspondência sem distinção entre maiúsculas e minúsculas e a conversão em letras maiúsculas Unicode, use a sequência de sinalizações'MULTILINE|CASE_INSENSITIVE|UNICODE'. -
[<token spec\>]Indica se corresponde à expressão regular somente nos limites de token.
... [[between <number> and] <number> token[s] in] ...As restrições de token são uma parte opcional da especificação. Se as restrições de token forem omitidas, a AQL retornará a correspondência sem sobreposição mais longa em cada posição do caractere no texto de entrada. Se as restrições de token estiverem presentes, a instrução
extractretornará a correspondência mais longa em cada limite de token que estiver dentro do intervalo especificado de tokens em comprimento. Cada correspondência retornada deve iniciar no começo de um token e terminar no final de um token. Se várias correspondências de sobreposição existirem, a instruçãoextractretornará todas elas.Os locais de limites de token dependem de qual tokenizer o componente de tempo de execução está usando para converter em token o documento. Se o motor estiver usando o tokenizer Standard, então um token é definido como uma sequência de caracteres de palavras ou um único caractere de pontuação.
Por exemplo, considere a sequência:
"The fish are pretty," said the boy.Os limites de token são identificados nestes locais:
["][The] [fish] [are] [pretty][,]["] [said] [the] [boy][.] -
<name\>.<column\>O nome da visualização e o nome da coluna na qual a expressão regular é aplicada.
-
<grouping spec\>Determina como manipular a captura de grupos na expressão regular. Os grupos de captura são regiões da correspondência de expressão regular que são identificadas por parênteses na expressão original. Por exemplo, a expressão
(fish)(cakes)tem três grupos de captura:- O grupo 0 é a correspondência inteira
fishcakes. - O grupo 1 é
fish. - O grupo 2 é
cakes. Quando você especifica os IDs do grupo na cláusula de retorno da sintaxe, cada ID do grupo deve corresponder a um grupo válido dentro de cada expressão regular especificada como parte da cláusula extract regex na sintaxe.
Este é o formato da especificação de agrupamento:
return group <number> as <name> [and group <number> as <name>]*Para retornar somente o Grupo 0 (a correspondência inteira), é possível usar um formato alternativo mais curto, como no Exemplo 1. Este formato é equivalente a
return group 0 as <name>. O<name>pode ser um identificador simples ou um identificador entre aspas duplas. - O grupo 0 é a correspondência inteira
Observações de uso
-
Em geral, a AQL suporta os mesmos recursos que a implementação de expressão regular Java 5, conforme descrito em [Padrão de classe: java.util.regex. O componente de tempo de execução contém várias implementações do mecanismo de expressão regular, incluindo a implementação integrada de Java. Durante a compilação, o Optimizer examina cada expressão regular e escolhe o mecanismo mais rápido que pode executar a expressão.
-
Os mecanismos alternativos de execução podem ter uma semântica um pouco diferente para determinados casos extremos. Em particular, a AQL não garante a ordem em que as alternativas são avaliadas.
Por exemplo, suponha que uma instrução extract corresponda à expressão regular
/fish|fisherman/sobre o texto 'fisherman'. A instrução pode corresponder a 'fish' ou 'fisherman', dependendo de qual mecanismo de expressão regular é usado internamente.
| Sequência de sinalização AQL | Sinalização Java | Descrição |
|---|---|---|
| CANON_EQ | CANON_EQ | Equivalência canônica: diferentes codificações Unicode de um mesmo caractere são consideradas equivalentes. |
| CASE_INSENSITIVE | CASE_INSENSITIVE | Execute uma correspondência sem distinção entre maiúsculas e minúsculas. Por padrão, a correspondência sem distinção entre maiúsculas e minúsculas supõe que somente caracteres no conjunto de caracteres US-ASCII são correspondidos. Correspondência de maiúsculas e minúsculas-a correspondência insensitiva pode ser ativada especificando a sinalização UNICODE com esta sinalização. |
| UNICODE | UNICODE_CASE | Caso a correspondência insensitiva case-insensitive seja especificada, use dobragem de caso Unicode para determinar se dois caracteres são equivalentes em uma comparação de caso-insensitivo de uma maneira consistente com o Padrão Unicode. Por padrão, a correspondência sem distinção entre maiúsculas e minúsculas supõe que somente caracteres no conjunto de caracteres US-ASCII são correspondidos. Nota: o comportamento dessa sinalização não é definido quando usado sem a sinalização CASE_INSENSITIVE. |
| DOTALL | DOTALL | Faça com que o caractere de ponto . corresponda a todos os caracteres, incluindo novas linhas. |
| LITERAL | LITERAL | Trate a expressão como uma sequência de caracteres literais, ignorando as sequências de escape normais de expressão normal. |
| MULTILINHAS | MULTILINHAS | Faça os caracteres ^ e $ correspondarem ao início e ao término de qualquer linha, em oposição ao início e ao término do texto inteiro de entrada. |
| UNIX_LINES | UNIX_LINES | Trate somente o caractere de nova linha do UNIX™ como uma quebra de linha, ignorando o caractere de retorno de linha \r. |
- Siga estas diretrizes para fazer com que seus extratores sejam executados mais rapidamente e sejam mais fáceis de manter:
- Evite expressões regulares longas e complexas e use expressões regulares mais simples e menores que são combinadas com instruções AQL.
- Evite o uso desnecessário de lookahead e lookbehind em expressões regulares. Geralmente, é possível alcançar o mesmo efeito incluindo predicados na cláusula having de sua instrução extract.
- Use restrições de token em suas especificações de extração de expressão regular quando possível.
Exemplos
Exemplo 1: usando a equivalência canônica de Unicode para determinar correspondências
Este exemplo mostra como localizar palavras alteradas para letras maiúsculas que não são nomes fornecidos. A equivalência canônica de caractere Unicode é usada para determinar correspondências. Observe o uso da sinalização ‘CANON_EQ’ e que o regex é executado em tokens:
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));
Exemplo 2: uso de grupos de captura
O exemplo a seguir demonstra o uso de grupos de captura em uma instrução extract regex. O código extrai os campos de um número de telefone dos Estados Unidos usando grupos de captura:
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;
Exemplo 3: aplicando múltiplos regex sobre o texto de entrada
É possível especificar diversas expressões regulares na mesma instrução extract regex usando a sintaxe 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;
Exemplo 4: uso indevido de especificação de agrupamento
A expressão regular nesta amostra de código não contém group -1 ou group 3000. Isso resulta em um erro de compilação.
create view ErrorExample as
extract regex /(\d+)/
on D.text
return group -1 as wrongGroup and
group 3000 as nonExistentGroup
from Document D;
Dicionários
Use a especificação de extração de dicionário para extrair sequências de texto de entrada que estão contidas em um dicionário de sequências.
Sintaxe
dictionar[y|ies]
'<dictionary>'
[and '<dictionary>' and ... and '<dictionary>']
[with flags '<flags string>']
Descrição
-
'<dictionary\>'Referencie um dicionário que é criado usando a instrução
create dictionary, a instruçãocreate external dictionaryou um arquivo de dicionário no sistema de arquivos. -
[and '<dictionary\>' and ... and '<dictionary\>']Referencia dicionários adicionais para serem usados para extração.
-
[with flags'<flags string\>']Controla correspondência de dicionário. Atualmente, duas opções são suportadas:
-
Exato
Fornece correspondência exata com distinção entre maiúsculas e minúsculas.
-
IgnoreCase
Fornece correspondência sem distinção entre maiúsculas e minúsculas.
-
Se nenhuma sinalização for especificada, a correspondência do dicionário se baseará em qualquer sinalização especificada durante sua criação. Se nenhuma sinalização for especificada durante a criação, ela corresponderá usando a sinalização
IgnoreCase.
Observações de uso
-
Os dicionários são sempre avaliados em limites de token. Especificamente, uma entrada de dicionário corresponderá a uma região de texto se o primeiro token da entrada corresponder ao primeiro token da região de texto, o segundo token da entrada corresponder ao segundo token da região de texto e assim por diante. Os caracteres entre dois tokens consecutivos são ignorados.
Por exemplo, suponha que você esteja usando um modelo de tokenização simples baseado em espaço em branco que seja apropriado para um idioma como o inglês. Além disso, suponha que o texto de entrada seja “Let’s go fishing!” Se um dicionário consistir no termo
go fish, nenhuma correspondência existirá no texto paraLet's go fishing!. No entanto, se o dicionário consistir na entradago fishing(observe os dois espaços em branco entre go e fishing), existirá uma correspondência no textoLet's go fishing!. O espaço em branco especifica quegoefishingsão dois tokens distintos. Se existir um ou mais caracteres de espaço em branco entre os dois tokensgoefishingno texto de entrada, uma correspondência será feita.Para cada correspondência de uma entrada de dicionário com texto de entrada, a instrução
extract dictionarygera uma tupla de saída.
Exemplos
Exemplo 1: Extraindo termos de arquivos de dicionário
Localize nomes de pessoas usando arquivos de dicionário de nomes e sobrenomes comuns com correspondência que faça distinção entre maiúsculas e minúsculas.
create view Name as
extract
dictionaries
'first.dict'
and 'last.dict'
with flags 'Exact'
on D.text
as name
from Document D;
A seguir está o conteúdo de amostra de last.dict:
#Dictionary for surnames
Anthony
Aparicio
Cate
Lehmann
Radcliff
A seguir está o conteúdo de amostra de first.dict:
#Dictionary for given names
Aaron
Candra
Freeman
Mathew
Matthew
Zoraida
Nota:
-
Um sistema de arquivos de dicionário que é diretamente referenciado em uma instrução
extract dictionarynão pode ser configurado explicitamente com um conjunto de idiomas para que os dicionários sejam compilados e aplicados no tempo de execução. Em vez disso, o conjunto de idiomas será especificado com a instruçãoset default dictionary languagese o módulo contiver essa instrução.Portanto, a referência direta de arquivos de dicionário em uma instrução
extract dictionarynão é recomendada e pode ser descontinuada no futuro. A prática preferencial é definir explicitamente um objeto de dicionário usando a instruçãocreate dictionary from filee, em seguida, usar esse dicionário na instrução extract. -
O compilador e o componente de tempo de execução tentam localizar arquivos de dicionário que são referenciados em AQLs sob o caminho de procura configurado.
Exemplo 2: extraindo termos de um dicionário sequencial
Localize conjunções usando um dicionário sequencial e a correspondência padrão sem distinção entre maiúsculas e minúsculas.
create dictionary ConjunctionDict as
(
'and', 'or', 'but', 'yet'
);
create view Conjunction as
extract
dictionary 'ConjunctionDict'
on D.text
as name
from Document D;
Divisões
Use a especificação de extração dividida para dividir um span grande em vários spans menores.
Sintaxe
split using <name>.<split point column>
[retain [right|left|both] split point[s]]
on <name>.<column to split>
as <output name>
Descrição
A especificação de extração de divisão usa dois argumentos:
- Uma coluna que contém abrangos de destino mais longos de texto.
- Uma coluna que contém pontos de divisão.
O algoritmo de divisão funciona em duas passagens sobre a visualização de entrada. A primeira passagem agrupa todas as tuplas de entrada pela coluna de destino. A segunda passagem passa pelas tuplas em cada grupo, dividindo a coluna de destino com cada valor da coluna de divisão.
-
<name\>.<split point column\>Especifica os pontos de divisão para a extração.
-
[retain [right|left|both] split point[s]]Especifica como tratar os terminais esquerdo e direito de cada resultado. Esse argumento é opcional.
- Se
retain left split pointfor especificado, cada span de saída também conterá o ponto de divisão à sua esquerda, se tal ponto de divisão existir. - Se
retain right split pointfor especificado, o sistema fará com que cada span de saída contenha o ponto de divisão à sua direita. - A extração de divisão também aceita valores nulos como pontos de divisão. Para cada valor, a extração retorna uma tupla que contém o span de entrada inteiro.
- Se
-
<name\>.<column to split\>Especifica a coluna de destino para a extração.
-
<output name\>Define o nome da saída da extração.
Exemplos
Exemplo 1: Pontos de Split e a cláusula retain
Se os pontos de divisão forem todas as instâncias da palavra fish na frase fish are swimming in the fish pond, as várias versões da cláusula retain terão os efeitos a seguir:
-
Cláusula retain omitida
" 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"
-
reter ambos os pontos de divisão
"fish are swimming in the fish" and "fish pond"
Exemplo 2: extração de divisão
Este exemplo divide o documento em sentenças. Ele usa primeiro uma expressão regular para identificar os limites de sentença, em seguida, usa a especificação de extração de divisão para dividir o texto do documento nos limites de sentença.
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;
Bloqueios
Use a especificação de extração de blocos para identificar blocos de spans contíguos através de texto de entrada.
Sintaxe
blocks
with count [between <min\> and] <max\>
and separation [between 0 and] <max\> (tokens| characters)
on <name\>.<column containing spans\>
as <output name\>
Descrição
-
with count [between<min\> and] <max\>Especifica quantos spans podem compor um bloco. Os valores
<min\>e<max\>especificam o número mínimo e máximo de intervalos que podem compor um bloco. -
[between 0 and] <max\>Especifica a distância de separação que é permitida entre os spans antes que eles não sejam mais considerados contíguos.
-
(tokens| characters)Especifica se a distância de separação da amplitude representa o número de tokens ou o número de caracteres.
-
<name\>.<column containing spans\>O nome da visualização e o nome da coluna aos quais o operador de bloco deve ser aplicado.
-
<output name\>Especifica um nome para a saída do operador de blocos.
Observações de uso
- Se as varreduras de entrada contiverem diversos blocos de sobreposição nos períodos de entrada, uma instrução de extração de bloco retornará todos os blocos possíveis. Use a consolidação para filtrar blocos redundantes.
- Uma instrução
extractcom a especificação de extração de bloco produz blocos que consistem, cada um, em uma agregação de valores de um determinado campo de entre múltiplas tuplas de entrada. Portanto, sua lista de seleção não pode incluir campos de sua visualização de entrada.
Exemplos
Exemplo 1: extrair blocos de palavras dentro de um intervalo de caracteres
No código a seguir, a visualização TwoToThreeCapitalizedWords identifica blocos de duas a três palavras alteradas para letras maiúsculas dentro de 100 caracteres uma da outra.
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;
Exemplo 2: extrair blocos de palavras dentro de um intervalo de tokens
O código a seguir identifica blocos de exatamente duas palavras alteradas para letras maiúsculas dentro de cinco tokens uma da outra.
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 do discurso
Use a especificação de extração de parte do discurso para identificar locais de diferentes partes da fala no texto de entrada.
Sintaxe
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>
Descrição
-
'<part of speech spec\>'Identifica as partes do discurso para extrair do texto de entrada. O
'<part of speech spec\>'é uma das sequências a seguir:- Uma sequência que contém uma lista delimitada por vírgula de tags de parte do discurso que são geradas pelo tokenizer Multilingual
- Uma combinação de um nome de parte interna-de-fala e sinalizadores, conforme definido por uma tabela de mapeamento
-
[and '<part of speech spec\>']*Identifica as tags de parte do discurso para extração.
-
[with language '<language code\>']Especifica o idioma a ser usado na extração. O
<language code\>é um código de idioma de duas letras em minúsculas, como 'en' ou 'ja'. Se esse argumento for omitido, o idioma para extração de parte do discurso será assumido como inglês -
[and mapping from <mapping table name\>]Especifica o nome de uma tabela AQL que mapeia as tags brutas de parte do discurso, como "NOUN", para combinações de partes do discurso e de sinalizações de alto nível. Enquanto a tabela de mapeamento opcional pode ter nomes de variáveis, uma tabela de mapeamento de parte da fala é necessária para ter esses nomes de colunas:
-
Tag
A coluna que contém uma tag de parte do discurso do tokenizer Multilingual.
-
basetag
A coluna que contém a tag interna correspondente.
-
flagstr
A coluna que contém uma lista delimitada por vírgula de sinalizações que estão associadas à parte do discurso indicada.
A tabela de mapeamento deve ser definida usando a instrução
create tableno mesmo módulo que a instruçãopart_of_speechde extração que a usa. Ela não pode ser uma tabela importada e não pode ser uma tabela externa.create table POSMapping_EN(tag Text, basetag Text, flagstr Text) as values ('CCONJ','CONJ','coordinating'), ('SCONJ','CONJ','subordinating'); -
-
<input column\>Especifica a coluna da visualização de entrada a partir da qual se extraia informações de parte da fala.
-
<output column\>Especifica o nome da coluna na qual os spans dos tokens com as partes do discurso indicadas são enviados.
-
<input view\>Especifica a visualização de entrada por meio da qual extrair informações de parte do discurso.
Observações de uso
- A extração de parte do discurso funciona somente quando está usando o tokenizer Multilingual. Se o sistema usar o tokenizer Standard, uma extração
part_of_speechgerará um erro.
Exemplos
Exemplo 1: usando uma tag de parte do discurso diretamente em uma instrução extract
A visualização EnglishNoun extrai substantivos em inglês (singular ou em massa) ou substantivos próprios (singular).
create view EnglishNoun
as extract parts_of_speech 'NOUN' and 'PROPN'
with language 'en' on D.text
as noun from Document D;
Padrões de sequência
Use a especificação de extração de padrão para executar a correspondência de padrão em um documento de entrada e em outros spans extraídos do documento de entrada.
Sintaxe
A sintaxe geral de um padrão de sequência é primeiro especificar o padrão a ser correspondido no texto e, em seguida, especificar o que deve ser retornado pelo extrator. A parte final do padrão de sequência especifica o que é a entrada para o padrão; pode ser uma coluna de uma visualização definida anteriormente ou o todo o texto do documento.
pattern <pattern specification> [return clause] [with inline_match on <viewname.colname>]
Descrição
-
<pattern specification\>Um
<pattern specification\>é composto de diversos átomos. Um Atom individual pode ser uma coluna a partir de uma visão já definida, de uma sequência fixa ou de uma expressão regular. É possível especificar seus Átomos como opcionais e de repetição, além de especificar diferenças de token entre os Átomos.A especificação de padrões faz parte de uma instrução AQL maior, que inclui uma cláusula de extração.
Aqui está um exemplo simples de como criar uma visualização que contém três correspondências adjacentes de visualizações definidas anteriormente. Neste exemplo, a combinação inteira é retornada à qual o
group 0se refere: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 os seus Átomos não precisarem ser exatamente adjacentes entre si, será possível usar diferenças de token entre os Átomos para permitir mais correspondências. Este exemplo localiza menções de pessoas que seguem dentro de 0 a 2 tokens por um número de telefone. Veja que a construção
<Token>{0,2}, que indica que é permitido um intervalo de 0 a 2 tokens entre as anotações da pessoa e do telefone.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;As construções de diferença de token são restritas a ocorrer dentro das expressões de sequência. Além disso, cada diferença de token em uma sequência deve ser precedida e seguida por uma expressão "diferença não de token". Como resultado, as instruções
extract patternproduzem exceções:-> 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 ...Use a sintaxe (min,max) para indicar o número de vezes que cada Atom repetirá. Também é possível usar a sintaxe ? para indicar que um Átomo ou um Átomo de repetição é opcional. Os átomos, juntamente com suas indicações para repetição e opcionais, são combinados para criar sequências.
Aqui está um exemplo mais complexo que mostra como repetir elementos. Localize os nomes de hotéis candidatos identificando ocorrências de uma a três palavras alteradas para letras maiúsculas, seguidas de um token 'Hotel' ou '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;Também é possível usar o operador
|para indicar uma escolha entre átomos, como emextract pattern <A.match>| <B.match> <C.match> as match from Apple A, Bacon B, Chocolate C;. Esse padrão pode ser explicado como “corresponder umA.matchOU uma sequência de umB.matchseguido de umC.match. É possível ver um exemplo completo que usa o operador|no Exemplo 1.Depois que você cria seu padrão, cada correspondência com seu
<pattern specification>cria um resultado de saída de acordo com a cláusula de retorno da especificação do padrão, bem como o<select list>opcional no início da instruçãoextract. Os resultados são filtrados e consolidados de acordo com as cláusulashaving,consolidateelimitda instruçãoextract. Por exemplo, se existirem diversas correspondências de sobreposição para a especificação de padrão, todas as correspondências possíveis serão retornadas e será possível usar uma cláusulaconsolidationpara filtrar as saídas redundantes.Considere o exemplo anterior, mas agora o objetivo é remover as correspondências que contenham a palavra 'Sheraton' e consolidar as correspondências resultantes removendo aquelas que estão contidas dentro de uma correspondência maior. Por exemplo, não desejamos localizar “Best Garden Hotel” e também “Garden Hotel” no mesmo span de texto.
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';
Agora que você está familiarizado com a sintaxe e alguns exemplos, este diagrama descreve a sintaxe integral para a especificação de padrão. Consulte essa sintaxe integral quando iniciar a construção de padrões para ver como estruturar o padrão que você deseja construir.
Se você estiver familiarizado com expressões regulares baseadas em caracteres do POSIX, você reconhecerá que a sintaxe é semelhante. Nesse caso, a sintaxe permite espaço em branco entre os elementos e o que um elemento pode ser para se adequar
aos propósitos de AQL também é definido. Observe que o termo Alternation neste caso significa escolha. O uso de uma barra vertical entre os elementos indica que existe uma escolha, que pode ser agrupada usando ( ).
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 )
Especificamente, um Atom pode ter seis formatos:
-
<view_name.column_name\>Especifica uma coluna de uma das visualizações, tabela ou referências de função de tabela que são nomeadas na lista from da instrução
extract pattern. -
'string'
Especifica uma correspondência para a sequência especificada usando a semântica de correspondência de dicionário padrão de AQL.
-
<'string' [match parameters]\>Especifica uma correspondência para a sequência especificada usando a semântica de correspondência de dicionário que é especificada pelo
[match parameters]. O formato de[match parameters]é maiúsculas e minúsculas(exact | insensitive). Esse formato especifica o tipo de padronização de caracteres (maiúsculos ou minúsculos) usado para determinar as correspondências de sequência. Para especificar uma correspondência exata que faça distinção entre maiúsculas e minúsculas, selecione exact. Para especificar uma correspondência sem distinção entre maiúsculas e minúsculas, selecione o valor padrão insensitive. -
/regex/Especifica uma correspondência de expressão regular baseada em caracteres com correspondência restrita a um único token no texto do documento. Além disso, a sintaxe permite que uma construção de diferença de token especial seja especificada em uma expressão de sequência para indicar uma correspondência entre o número
minemaxde tokens. -
<token\>Uma correspondência para qualquer token.
-
[return clause]Gera os valores extraídos para cada correspondência da expressão padrão de acordo com a cláusula de retorno. A cláusula
returntem a mesma semântica que a cláusulareturnem uma instruçãoextract regex. -
[with inline_match on <viewname.colname\>]Para os Átomos, como os Átomos de sequência e de regex, a cláusula
with inline_matchdetermina qual objeto de texto o sistema usa para extração de sequência ou de regex. Por exemplo, se a cláusula forwith inline_match on Email.subject, todos os dicionários e expressões regulares definidos em sequencial na especificação padrão serão aplicados no campo de assunto da visualizaçãoEmail. Se owith inline_matchestiver ausente, a extração de sequência e de expressão regular será executada por padrão no Document.text inteiro. Neste caso, o viewname deve ser o nome de uma view ou table que é definido no módulo atual, ou importado de outro módulo; as referências a funções de tabela não são permitidas na cláusula inline_match. -
[with language as <language code(s)\>]Especifica uma lista delimitada por vírgulas de códigos de idioma de duas letras, como en (inglês) ou zh (chinês) para os idiomas nos quais avaliar a sequência. Não há correspondência em documentos cujo código de idioma não esteja contido nessa sequência. Se o parâmetro language for omitido, o idioma de avaliação será padronizado para um dos conjuntos de idiomas a seguir:
- Se ele for declarado, os conjuntos de idiomas que são especificados por meio da instrução set default language no módulo de contenção.
- Os conjuntos de idiomas que contêm alemão (de), espanhol (es), inglês (en), francês (fr), italiano (it) e o idioma não especificado (x_unspecified)
Observações de uso
-
A semântica de uma instrução
extract patterné acionada pela especificação de padrão. Cada correspondência constrói um resultado de saída de acordo com a cláusula de retorno da especificação de padrão e a lista de seleção na parte superior da instruçãoextract. Os resultados são filtrados e consolidados de acordo com as cláusulashaving,consolidateelimitda instrução extract. Se existirem diversas correspondências de sobreposição para a especificação de padrão, uma extração de padrão gerará todas as correspondências possíveis. Use a consolidação para filtrar saídas redundantes. -
A semântica da cláusula
fromde uma instruçãoextract patterné diferente de outras formas de instruçõesextractque não têm uma especificação de padrão. A semântica geral de uma instruçãoextractrequer que a especificação de extração seja avaliada em cada combinação das visualizações definidas em<from list\>. Se pelo menos uma das visualizações em<from list\>não contiver nenhum resultado em um documento específico, a saída da instrução de extração estará vazia, pois o conjunto de todas as combinações de resultados nas visualizações de entrada estará vazio. No caso especial de instruções extract pattern, a cláusula from é um item temporário que declara os nomes de relações que estão envolvidas na especificação de padrão. A semântica da instrução é acionada apenas pela especificação do padrão. Em particular, a saída da instrução pode ser não vazia mesmo quando algumas das visualizações de entrada estiverem vazias. -
Uma instrução
extractque usa a extração de padrão de sequência poderá transportar para frente as colunas de qualquer visualização na listafrom, mas somente se o nome da visualização não aparecer em um elemento de repetição da especificação de padrão. Por exemplo, a instruçãoCapsWordOneToThreeresulta em um erro de compilação. O erro ocorre porque a coluna transportadaCW.typena parte superior da instruçãoextractpertence ao nome da visualizaçãoCW, que está no elemento de repetição<CW.word>{1,3}da especificação de padrão.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;Para as colunas que são transportadas de nomes de visualização que aparecem em elementos alternativos ou opcionais da especificação de padrão, o valor da coluna de saída é
nullquando a alternativa correspondente ou o elemento opcional não está presente no texto. Um exemplo que ilustra esse ponto está na visualizaçãoPersondo Exemplo 1. -
Os grupos que ocorrem sob um elemento de repetição não podem ser gerados na cláusula
returnda instrução. Por exemplo, a instrução a seguir causa uma exceção: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;
Exemplos
Exemplo 1: padrão de Sequência com grupos de captura
O objetivo deste exemplo é localizar nomes de pessoas identificando ocorrências do nome, opcionalmente seguido pela inicial do segundo nome, seguido por um sobrenome e a correspondência inteira que é opcionalmente precedida por uma saudação comum. Além disso, o extrator retorna a correspondência inteira como referência, o primeiro grupo como saudação e o segundo grupo como nome e transporta os valores do nome, da inicial do meio e do sobrenome das respectivas visualizações de entrada.
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;
Uma vez que a expressão de subpadrão ('Mr.'|'Ms.'|'Miss')? é opcional, o valor da coluna de saída de saudação é null quando uma saudação não está presente no texto. Da mesma forma, uma vez que a subexpressão padrão
<M.initial>? é opcional, o valor do meio da coluna de saída é null quando uma inicial média não está presente.
Exemplo 2: padrão de sequência com correspondência de sequência e parâmetros de correspondência
O objetivo deste exemplo é localizar ocorrências de notas de reunião para projetos conhecidos, examinando as anotações do título do documento. Observe a cláusula with inline_match, que especifica que a correspondência de sequência
é feita sobre o campo de correspondência da visualização Title, em oposição ao texto do documento inteiro.
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;
Exemplo 3: padrão de sequência que retorna resultados não vazios mesmo quando uma visualização de entrada está vazia
A instrução a seguir gera resultados mesmo quando a visualização de entrada LastName está vazia. A segunda parte da especificação de padrão, <L.name\>?, contém um elemento opcional. A semântica da especificação de padrões
é projetada para a saída de todas as spans que são compostas por uma amplitude FirstName.name ou um span FirstName.name que é imediatamente seguido por um LastName.name span. Portanto, em documentos
para os quais a visualização LastName está vazia, o resultado da instrução consiste em todos os spans que compreendem um único span FirstName.name que é identificado por meio desse 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;
A instrução select
A instrução select em AQL fornece um mecanismo poderoso para o uso de várias especificações para construir e combinar conjuntos de tuplas.
Sintaxe
A instrução select é semelhante em estrutura a uma instrução 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>`];
Descrição
-
<select list\>Uma lista delimitada por vírgula de expressões de saída.
-
<from list\>Uma lista delimitada por vírgula que é a origem das tuplas a serem selecionadas.
-
[where <where clause\>]Define um predicado a ser aplicado sobre cada tupla que é gerada por meio do produto Cartesiano de todas as tuplas nas relações na cláusula
from. Essa cláusula é opcional. -
[consolidate on<column\>[using '<policy\>' [with priority from <column\> priority order]]]Define uma política de consolidação para gerenciar spans de sobreposição. Essa cláusula é opcional.
-
[group by<group by list\>]Agrupa as tuplas que são produzidas por meio do mesmo documento por valores comuns de um campo especificado. Essa cláusula é opcional.
-
[order by<order by list\>]Ordena as tuplas de saída que são produzidas pela instrução
selectde cada documento. A ordem é baseada nos valores da lista order-by, uma lista de expressões delimitadas por vírgula. Essa cláusula é opcional. -
[limit <maximum number of output tuples for each document\>]Limita o número de tuplas de saída para cada documento para o máximo especificado. Essa cláusula é opcional.
Notas de uso
A semântica da instrução select é a seguinte:
- Determine os dados de entrada (em tuplas) usando o produto Cartesiano de relações na lista de origem.
- Para cada tupla de entrada gerada, filtre-a aplicando os predicados na cláusula
where(opcional). - Se a cláusula
group byopcional estiver presente, agrupe as tuplas produzidas do mesmo documento pelos valores especificados na lista agrupar por e calcule o resultado das funçõesaggregateda lista de seleção. - Consolide as tuplas de sobreposição de acordo com a política definida na cláusula
consolidation(opcional). Se a cláusulaorder byopcional estiver presente, solicite essas tuplas pelos valores da lista order-by. - Compute todas as expressões dentro da lista
selectem cada tupla e renomeie as colunas conforme especificado pelas cláusulasas. - Se a cláusula
limitopcional estiver presente, limite o número de tuplas de saída para o número especificado de tuplas para cada documento.
Exemplos
Um exemplo de como usar a instrução select é extrair números de telefone que correspondem a um padrão. Suponha que a visualização PhoneNumbers que extrai números de telefone do padrão XXX-XXX-XXXX para os Estados
Unidos já esteja definida. Esta instrução select avalia a expressão regular para o padrão 444-888-XXXX em todo o texto de entrada. A visualização tem as colunas de saída documentText e phoneNumber.
Além disso, a saída é limitada à primeira ocorrência desse padrão de número de telefone que é identificado por documento.
create view PhoneNumbersPattern1 as
select D.documentText, D.phoneNumber
from PhoneNumbers D
where MatchesRegex(/444-888-\d{4}/,D.phoneNumber)
limit 1;
Outro exemplo de como é possível usar a instrução select é localizar mapeamentos aproximados de pessoas e seus números de telefone correspondentes. Suponha que a visualização Person já esteja definida e que tenha
as colunas person e a visualização PhoneNumbers. Esta instrução select avalia a cláusula where para localizar spans de texto que contenham uma menção de pessoa seguida de um número de telefone
dentro de 1 3 palavras ou tokens. A entrada para essa instrução é representada por uma junção das visualizações Person e PhoneNumbers na lista 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);
A coluna personPhoneSpan conterá os spans correspondentes que fornecem o mapeamento aproximado de pessoa-telefone.
personPhoneSpan
John : 433-999-1000
Martha Mob 433-999-1001
- A lista de seleção A lista de seleção em uma instrução AQL
selectouextractconsiste em uma lista delimitada por vírgulas de expressões de saída. - A lista de origem A segunda parte de uma instrução
selectouextractna AQL é a da lista de origem. A lista from é uma lista separada por vírgula que é a origem das tuplas a serem selecionadas ou extraídas. - A cláusula where A cláusula
whereopcional define um predicado a ser aplicado em cada tupla gerada do produto Cartesiano de todas as tuplas nas relações na cláusulafrom. - A cláusula consolidate on A cláusula
consolidate onopcional especifica como os períodos de sobreposição são resolvidos nas tuplas geradas por uma instruçãoselectouextract. Tuplas com spans não sobrepostos não são afetadas quando essa cláusula é usada. - A cláusula group by A cláusula
group byopcional de uma instruçãoselectdireciona o componente de tempo de execução para agrupar as tuplas produzidas do mesmo documento por valores comuns de um campo especificado. - A cláusula order by A cláusula
order byopcional direciona o componente de tempo de execução para ordenar as tuplas de saída produzidas pela instrução select de cada documento com base nos valores da lista order by, que é um conjunto de expressões delimitado por vírgulas - A cláusula limit A cláusula
limitopcional especifica um limite no número de tuplas de saída produzidas pela instrução select para um documento. - A instrução select... into A instrução
select ... intoé útil para definir uma visualização e especificar que é uma visualização de saída em uma única instrução.
A lista de seleção
A lista de seleção em uma instrução AQL select ou extract consiste em uma lista delimitada por vírgula de expressões de saída.
Sintaxe
Cada expressão select deve estar em uma das formas a seguir:
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>
Descrição
-
<viewname\>.<colname\> as <alias\>-
<viewname\>Especifica a visualização por meio da qual selecionar colunas.
-
<colname\>Especifica a coluna nessa visualização.
-
<alias\>Especifica o nome pelo qual o campo selecionado é conhecido. Esse campo é um campo opcional. Ele é selecionado para fazer parte de cada tupla de saída. Se
<alias\>não for especificado, o nome da coluna será<colname\>por padrão. Pode ser um identificador simples ou um identificador duplo citado.
-
-
<viewname\>.*Especifica o nome de uma visualização. Essa sintaxe indica que todas as colunas da visualização especificada devem ser transportadas para a instrução
selectouextractcircundante.Como a SQL, a AQL permite a instrução
select *abreviada. O efeito dessa instrução é selecionar todas as colunas de todas as entradas que estão especificadas na cláusulafromda instruçãoselect. No entanto, a instrução extract * abreviada não é suportada. -
<expr\> as <alias\>Representa a designação de uma expressão para um atributo da visualização abrangente.
-
<expr\>Especifica uma expressão que é composta por chamadas de função escalar, chamadas de função agregada ou uma constante.
-
<name\>Representa o nome da coluna que detém o resultado da expressão especificada por
<expr\>como<alias\>. Se<alias\>não for especificado, o nome da coluna será<name\>por padrão. Pode ser um identificador simples ou um identificador duplo citado.
-
-
when<function1()\> then <expr1\> when <function2()\> then <expr2\> ... when <functionN()\> then <exprn\> [else ] <expr_default\> as <name\>-
<function1()\>, <function2()\>, <functionN()\>Especifique funções escalares que retornam o tipo Boolean.
-
<expr1\>, <expr2\>, <exprn\>, <expr_default\>Especifique expressões que sejam compostas de chamadas de função escalar e devem retornar o mesmo tipo.
Se o resultado de
<function1()\>for true, o resultado da expressãocaseserá o resultado de<expr1\>e nenhuma das cláusulaswhensubsequentes serão avaliadas. Caso contrário, as cláusulaswhensubsequentes (se houver) serão avaliadas da mesma maneira.Quando nenhuma das condições das cláusulas
whené atendida, o resultado dessa expressão de caso é o resultado da expressão padrão<expr\_default\>. Essa expressão é especificada na cláusulaelseopcional. Se a cláusula[else]estiver ausente, o resultado desta expressãocaseénull. -
Observações de uso
-
A instrução a seguir não é suportada:
select * from Document;Os conteúdos da visualização
Documentpodem não ser totalmente conhecidos no contexto ou escopo atual do arquivo .aql em que esta instruçãoselecté emitida. A falta de informações sobre os conteúdos é porque múltiplas instruçõesrequire document with columnsfornecidas fora do arquivo atual .aql podem alterar a definição de esquema eventual dessa visualizaçãoDocumentespecial quando ela é usada no nível de um módulo. A instrução Document.* abreviada não é uma construção AQL válida. -
É possível selecionar explicitamente os campos por meio da visualização
Document. O exemplo a seguir mostra uma seleção explícita válida de campos por meio de uma visualizaçãoDocument:select D.label as label, D.text as text from Document D;
Exemplos
Os exemplos a seguir ilustram várias formas da lista de seleção.
Exemplo 1: designação de valor explícito usando uma constante
Este exemplo mostra a designação de um valor constante a um atributo de visualização dentro da lista de seleção. O campo chamado polaridade indica se a polaridade de PS.match é positiva ou negativa (Observe a designação explícita
de um valor constante para esse atributo).
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;
Exemplo 2: designação de valor explícito usando chamada de função
O exemplo a seguir ilustra como o resultado de uma chamada de função é explicitamente designado a um atributo de visualização dentro da lista de seleção.
create view Citizenship as
select
P.Name as name,
MatchesDict('USCities.dict', P.birthPlace) as isUSCitizen
from
Person P;
Exemplo 3: expressão select list de uma extração de dicionário
O exemplo a seguir ilustra como a expressão select list pode escolher valores do tipo Span a partir de um resultado de extração de dicionário.
create view PersonNames as
select N.match as name
from
(extract
dictionary 'firstNames.dict'
on D.text
as match
from Document D
)N;
Exemplo 4: Exemplos de expressões de caso
Este primeiro exemplo mostra como especificar a manipulação nula em campos específicos:
create view School as
select
case
when Not(NotNull(P.education)) then 'Unknown'
else GetString(P.education)
as name
from Person P;
Este exemplo explica como classificar dados:
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;
A lista de
A segunda parte de uma instrução select ou extract em AQL é a lista from. A lista from é uma lista separada por vírgula que é a origem das tuplas a serem selecionadas ou extraídas.
Sintaxe
from <from list item> <name> [, <from list item> <name>]
Descrição
-
<from list item\>Uma visualização, tabela, referência de função de tabela ou instrução AQL aninhada. Todas as instruções aninhadas em AQL devem ser circundadas por parênteses.
-
<name\>Nome local do
<from list item\>, que tem o escopo definido na instruçãoselectou na instruçãoextract. Um nome local pode ser um identificador simples ou um identificador com aspas duplas. Os nomes locais que contêm espaços, caracteres de pontuação ou palavras-chave AQL devem estar entre aspas duplas.
Exemplos
Exemplo 1: Uma lista from com uma visualização e uma instrução aninhada
Este exemplo mostra uma lista from que referencia uma visualização e uma instrução extract aninhada. O exemplo designa o resultado da instrução ao nome local FN. O exemplo também designa as saídas da visualização
LastName para o nome local 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);
Os nomes a seguir estão contidos no dicionário externo first.dict:
#Dictionary for given names
Aaron
Candra
Freeman
Mathew
Matthew
Zoraida
A cláusula where
A cláusula where opcional define um predicado a ser aplicado a cada tupla gerada por meio do produto Cartesiano de todas as tuplas nas relações na cláusula from.
Sintaxe
select <select list>
from <from list>
[where <where clause>]
Descrição
-
<where clause\>Especifica um ou mais predicados. Uma junção ocorre quando qualquer predicado em uma cláusula
whereenvolve campos de mais de uma visualização que pertence à listafrom. Este predicado deve ser uma conjunção de um conjunto de funções de predicado integrado ou outras funções definidas pelo usuário que retornam o tipo de dados Boolean:function1() and function2() and ... and functionn()A cláusula
whereé opcional e poderá ser omitida de uma instruçãoselectse não existir nenhum predicado para aplicar.
Exemplos
Exemplo 1: filtrar as tuplas associadas usando um predicado na cláusula WHERE
Este exemplo mostra uma cláusula where que localiza apenas as frases que consistem em nomes válidos seguidos de 0 a 1 caractere por sobrenomes válidos.
-- 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);
Os nomes a seguir estão contidos no dicionário externo first.dict:
#Dictionary for given names
Aaron
Candra
Freeman
Mathew
Matthew
Zoraida
Os nomes a seguir estão contidos no dicionário externo last.dict:
#Dictionary for surnames
Anthony
Lehman
Radcliff
A cláusula consolidate on
A cláusula consolidate on opcional especifica como os spans de sobreposição são resolvidos entre as tuplas que são geradas por uma instrução select ou extract. Tuplas com spans não sobrepostos não são afetadas
quando essa cláusula é usada.
Sintaxe
O código a seguir é um exemplo da estrutura geral dessa cláusula:
consolidate on <target>
[using '<policy>'[ with priority from <priority_column>
[ <priority_order> ]]]
Descrição
-
<target\>Especifica uma coluna em uma visualização na cláusula
fromou uma expressão que é composta de chamadas de função escalar envolvendo colunas de visualizações que são especificadas na cláusulafromcomo argumentos. -
'<policy\>'Especifica uma das políticas de consolidação a seguir que são suportadas por Análise de texto:
-
ContainedWithin
Essa política é a inadimplência. Se os spans A e B se sobrepuserem e A contiver completamente B, essa política removerá a tupla que contém o span B da saída. Se A e B forem os mesmos, então removerá um deles. A escolha de qual tupla será removida é arbitrária.
-
NotContainedWithin
Se spans A e B se sobrepõem, e A contém completamente B, esta política então remove o span A da saída. Se A e B forem os mesmos, então removerá um deles. A escolha de qual tupla será removida é arbitrária.
-
ContainsButNotEqual
Essa política é a mesma que ContainedWithin, exceto que os spans que são exatamente iguais são retidos.
-
ExactMatch
Se um conjunto de spans cobrir a mesma região de texto, essa política retornará exatamente um deles. Todos os outros spans serão deixados intocados.
-
LeftToRight
Essa política processa os spans em ordem da esquerda para a direita. Quando a sobreposição ocorre, ela mantém o span de sobposição mais à esquerda, mais longo e sem sobreposição. Essa política emula a política de manipulação de sobreposição da maioria dos mecanismos de expressão regular.
-
-
<priority\_column\>Especifica uma coluna do tipo Text, String, Integer ou Float. Pode ser especificado apenas com a política de consolidação
LeftToRight. -
<priority\_order\>Especifica ordem crescente ou decrescente. Pode ser especificado apenas com a política de consolidação
LeftToRight. A ordem crescente assegura que se uma tupla T1 tiver prioridade 1 e uma tupla T2 tiver prioridade 2, T1 terá uma prioridade mais alta que T2. Por contraste, se a ordem de prioridade for decrescente, o T2 tem uma prioridade maior. O valor padrão da ordem de prioridade é crescente.
Observações de uso
- Quando a cláusula de prioridade está presente, a semântica da consolidação segue esta ordem:
- O processo abrange da esquerda para a direita e, quando os spans se sobrepõem, eles retêm os spans mais à esquerda.
- Se você tiver múltiplos spans de sobreposição que se iniciam no mesmo deslocamento, retenha aqueles com a prioridade mais alta de acordo com a ordem de prioridade.
- Quebre os empates restantes mantendo os spans mais longos entre os spans com a mesma prioridade.
- A consolidação trata os nulos como idênticos. Todas as entradas com um
<consolidate target\>nulo resultam em uma tupla de saída única, que é escolhida aleatoriamente entre essas entradas. Esse comportamento é semelhante a como as tuplas são consolidadas com um span idêntico na coluna de destino. A exceção para resultar em uma tupla de saída única será se a política for ContainsButNotEqual. Nesse caso, o<consolidate target\>nulo gera todas as entradas com destino de consolidação nulo.
Exemplos
Exemplo 1: consolidar em coluna única
Este exemplo direciona o sistema para examinar o campo Person.name de todas as tuplas de saída e para usar a política de consolidação ContainedWithin para resolver a sobreposição.
consolidate on Person.name
using 'ContainedWithin'
Exemplo 2: Consolidar na expressão, envolvendo várias colunas
Este exemplo direciona o sistema para examinar o resultado da aplicação da função escalar CombineSpans para os campos Person.firstname e Person.lastname em cada tupla de saída. Ele resolve a sobreposição
usando a política de consolidação ContainedWithin.
consolidate on
CombineSpans(Person.firstname, Person.lastname)
using 'ContainedWithin'
Exemplo 3: consolidar usando a política LeftToRight e a ordem de prioridade
Suponha que as tuplas de Termo a seguir sejam extraídas do texto de entrada John Doe:
match: `John`,
priority: `1`
e
match: `John Doe`,
priority: `2`
Ambos os spans têm o mesmo deslocamento inicial. Ao consolidar usando a política LeftToRight para a ordem de prioridade crescente, a tupla (match: John, priority: 1) é retida porque ela tem a prioridade mais alta.
Ao consolidar usando a ordem de prioridade decrescente, a tupla (match: John Doe, priority: 2) é retida, como no exemplo a seguir:
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;
A cláusula group by
A cláusula opcional group by de uma instrução select direciona o componente de tempo de execução para agrupar tuplas que são produzidas do mesmo documento por valores comuns de um campo especificado.
Sintaxe
select <select list>
from <from list>
[where <where clause>]
...
[group by <group by list>]
Descrição
-
<group by list\>Especifica uma lista delimitada por vírgula de expressões que envolve colunas das visualizações na cláusula
frome nas chamadas de função escalar. Ao aplicar a cláusulagroup by, cada grupo de tuplas que compartilha valores comuns para todas as expressõesgroup byproduz uma tupla de saída única que é representativa para o grupo inteiro.Um campo ou expressão que não aparece na cláusula
group bynão pode aparecer na lista de seleção, a menos que ela seja usada em uma chamada de função agregada. A ordem de expressões na lista não importa.A cláusula
group bytrata todos os nulos como idênticos. OGroup byem uma coluna com valores nulos resulta em um único grupo.
Exemplos
Exemplo 1: computando valores agregados
Use a cláusula group by para computar valores agregados. Este exemplo conta o número de ocorrências de cada nome no documento. Neste exemplo, Count é uma função agregada.
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);
Nesse caso, first.dict é um dicionário externo que contém as entradas a seguir:
#Dictionary for given names
Aaron
Candra
Freeman
Matthew
Zoraida
As etapas a seguir descrevem a semântica dessa instrução:
- Agrupe tuplas que são produzidas pela subconsulta na cláusula
frompelo conteúdo de texto de seu campofirstname. - Para cada grupo, conte o número de tuplas com um valor de
firstnamenão nulo. Produza uma tupla de saída única para cada grupo desse tipo, com dois valores, o nome e o número de tuplas nesse grupo.
Exemplo 2: problemas com o agrupamento de campos dissimilares
Este exemplo ilustra uma instrução que não é válida.
select GetText(P.firstname) as first,
GetText(P.lastname) as last,
Count(P.firstname) as occurrences
from Person P
group by GetText(P.firstname);
A inclusão de GetText(P.lastname) no select list não é aceita, uma vez que as tuplas com os mesmos valores de firstname podem ter valores de lastname diferentes, o que leva à ambiguidade.
A cláusula order by
A cláusula order by opcional direciona o componente de tempo de execução a ordenar as tuplas de saída que são produzidas pela instrução select por meio de cada documento com base nos valores da ordem por lista, que é um conjunto
delimitado por vírgula de expressões.
Sintaxe
select ...
[order by <order by list>]
Descrição
-
<order by list\>Especifica uma lista de expressões delimitadas por vírgula.
A ordem é baseada nos valores de uma lista de expressões delimitadas por vírgula. A cláusula order by suporta expressões que retornam tipos de dados numéricos (Número inteiro ou Valor flutuante), Texto ou Período. Se uma expressão na cláusula
order byretornar um tipo Span, as tuplas de resultado serão comparadas por meio da comparação dos valores de span relevantes. No exemplo a seguir, os valores de span do campopersonsão comparados.order by P.personA cláusula
order bytrata nulos como não ordenados (entre si). Os nulos são ordenados mais baixos que outros objetos.
Exemplos
Exemplo 1: ordem por múltiplas expressões
Suponha que a pessoa seja um campo do tipo Span. A cláusula order by a seguir especifica que a instrução retorna tuplas dentro de cada documento. Elas são ordenadas lexicograficamente pelo texto do campo de pessoa e, em seguida,
pelo início do campo de pessoa.
order by GetText(P.person), GetBegin(P.person)
A cláusula limit
A cláusula limit opcional especifica um limite sobre o número de tuplas de saída que são produzidas pela instrução select para um documento.
Sintaxe
select <select list>
from <from list>
...
[limit <maximum number of output tuples for each document>];
Descrição
-
<maximum number of output tuples for each document\>Especifica o número máximo de tuplas de saída para cada documento. Se o valor limite for maior ou igual ao número total de tuplas que poderiam ser retornadas, todas as tuplas serão retornadas.
Exemplos
Exemplo 1: limitando o número de retornos
Este exemplo retorna os três primeiros nomes de pessoa em cada documento:
create view SampleView as
select *
from Person P
order by GetBegin(P.name)
limit 3;
A instrução select... into
A instrução select ... into é útil para definir uma visualização e especificar que se trata de uma visualização de saída em uma única instrução.
Sintaxe
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>];
Descrição
-
<output view name\>Especifica o nome da visualização de saída que é definida pela instrução. A instrução
select ... intoé idêntica à instruçãoselect, exceto pela cláusulainto <output view name\>adicional.
Exemplos
Exemplo 1: definindo uma visualização
Este exemplo define uma visualização que é chamada PersonPhone e também especifica essa visualização como uma visualização de saída.
select P.name as name,
Ph.number as phoneNumber
into PersonPhone
from Person P, Phone Ph;
Este exemplo é equivalente às duas instruções a seguir:
create view PersonPhone as
select P.name as name,
Ph.number as phoneNumber
from Person P, Phone Ph;
output view PersonPhone;
A instrução detag
A instrução detag em AQL fornece a função para desmarcar ou remover toda a marcação de documentos HTML ou XML antes de executar os extratores AQL.
A instrução detag também pode reter os locais originais de tags e todos os valores armazenados nelas. Quando uma instrução detag remove tags de um documento, o componente de tempo de execução lembra o mapeamento entre
os deslocamentos do texto com tag removida e da origem de marcação original. A função Remap, uma função integrada especial que mapeia os spans do texto com tag removida de volta para seus spans equivalentes da origem original.
Sintaxe
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 ...]];
Descrição
-
<input view name\>.<text column\>-
<input view name\>Especifica o nome da visualização de entrada na qual fazer o processo de remoção de tag. O
<input view name\>pode ser um identificador simples ou um identificador entre aspas duplas. -
<text column\>Especifica o campo de texto da visualização de entrada na qual fazer o processo de remoção de tag. O
<text column\>pode ser um identificador simples ou um identificador entre aspas duplas.
-
-
<output view name\>Especifica o nome da visualização de saída que contém o texto com tag removida. A visualização de saída contém uma única coluna que é chamada text, que contém o texto com tag removida. O
<output view name\>pode ser um identificador simples ou um identificador entre aspas duplas. -
always|neverEspecifica se deve verificar se os conteúdos são HTML ou XML antes de a instrução
detagser processada. Ao executar textos não HTML e não XML por meio de um removedor de tag, problemas podem ocorrer quando o texto contém caracteres especiais XML, como<,>ou&. Se a cláusuladetect content_typeestiver ausente, o valor padrão será always e o sistema sempre detectará o conteúdo.-
alwaysEspecifica que a verificação sempre ocorre antes que a operação seja tentada para evitar problemas com a análise de documentos que não são HTML ou XML. Se o valor de
<text column\>não parecer conter uma marcação, o sistema ignorará a remoção de tag do documento atual. -
neverEspecifica que a verificação nunca ocorre antes que a operação de remoção de tag seja tentada. O sistema tenta remover tag do texto de destino, mesmo que o texto não contenha nenhum conteúdo HTML ou XML.
-
-
<element name\>Especifica o nome do elemento HTML ou XML a ser anotado. A cláusula
annotateopcional pode direcionar o componente de tempo de execução para lembrar informações sobre as tags removidas criando uma ou mais visualizações. -
<auxiliary view name\>Especifica o nome da visualização que é criada para conter as tags originais e seus atributos. Pode ser um identificador simples ou um identificador duplo citado.
-
<attribute name\>Nome de um atributo do elemento HTML ou XML.
-
<column name\>O nome da coluna em
<auxiliary view name\>que é usado para armazenar os valores de<attribute name\>. Pode ser um identificador simples ou um identificador duplo citado.
Exemplos
Exemplo 1: especificando a visualização de saída de remoção de tag e uma visualização auxiliar
Neste exemplo, a visualização DetaggedDoc é criada para conter a versão com tag removida do texto original no atributo text da visualização Document. Além de criar uma visualização DetaggedDoc,
a cláusula anotate cria uma visualização auxiliar chamada Anchor. Essa visualização auxiliar tem duas colunas. Uma coluna, chamada match, contém o texto âncora. A outra coluna, chamada linkTarget,
contém o destino real do link como texto. Os spans na coluna de correspondência estão sobre o valor de texto da visualização DetaggedDoc.
detag Document.text as DetaggedDoc
annotate
'a' as Anchor
with attribute 'href' as linkTarget;
Exemplo 2: usando a função Remap
O exemplo a seguir ilustra como a função Remap é usada para mapear os spans do texto com tag removida de volta para seus equivalentes na origem original.
-- 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;
Documentando a instrução detag com o AQL Doc
O comentário do AQL Doc para uma instrução detag contém as seguintes informações:
- Descrição geral sobre a função da instrução.
- O @field para cada campo de texto da visualização de entrada na qual fazer o processo de remoção de tag.
- @auxView especifica o nome da visualização.
- O @auxViewField especifica o nome completo da coluna da visualização.
/**
* 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;
As instruções create dictionary e create external dictionary
As instruções create dictionary e create external dictionary são usadas para definir dicionários de palavras ou frases para identificar termos de correspondência no texto de entrada por meio de instruções de extração
ou funções de predicado. A instrução create dictionary permite a especificação de conteúdo de dicionário no código AQL de origem e o conteúdo do dicionário é serializado dentro da representação compilada do módulo (o arquivo .tam).
A instrução create external dictionary permite especificar o conteúdo do dicionário quando o extrator é instanciado, em vez de no código AQL de origem, e você não precisa recompilar o módulo. Portanto, os dicionários externos
são construções poderosas que permitem que o desenvolvedor de AQL exponha pontos de customização em um módulo compilado.
Os dicionários podem ser criados por meio de três origens:
- Arquivos de dicionário
- Declarações de dicionário sequencial
- As tabelas que são criadas com a instrução
create tablee a instruçãocreate external table.
Sintaxe
A instrução create dictionary interna tem três formas sintáticas, from file, from table e um formato sequencial.
-
dicionário interno
Do arquivo:
create dictionary <dictionary name> from file '<file name>' [with language as '<language code(s)>'] [and case (exact | insensitive)] [and lemma_match];Por meio da tabela:
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 sequencial
create dictionary <dictionary name> [with language as '<language code(s)>'] [and case (exact | insensitive)] [and lemma_match] as ( '<entry 1>', '<entry 2>', ... , '<entry n>' ) ; -
Dicionário externo
create external dictionary <dictionary-name> required [true|false] [with language as '<language codes\>'] [and case (exact | insensitive )] [and lemma_match];
Descrição
-
<dictionary name\>Especifica um nome para o novo dicionário interno ou externo. Pode ser um identificador simples ou identificador com aspas duplas.
-
'<file name\>'Especifica o nome do arquivo que contém entradas de dicionário. Os arquivos de dicionário são arquivos de texto delimitados por retorno de linha com uma entrada de dicionário por linha. As entradas em um arquivo de dicionário podem consistir em múltiplos tokens.
-
<table name\>Especifica o nome da tabela por meio da qual incluir entradas de dicionário. Os dicionários não podem ser criados por meio de uma tabela que é importada de outro módulo.
-
<column name\>Especifica o nome da coluna na tabela por meio da qual incluir entradas de dicionário.
-
required [true|false]Especifica se o conteúdo externo para o dicionário externo é necessário para executar o módulo.
-
trueSe a cláusula for
required true, você deve fornecer um URI para a localização do arquivo que contém o conteúdo externo. O arquivo especificado deve possuir conteúdo. Se o URI não for fornecido ou se o arquivo não contiver conteúdo, o componente de tempo de execução emitirá uma exceção. -
falseSe a cláusula for
required false, o módulo poderá ser executado com sucesso mesmo se um URI para o conteúdo externo não for fornecido para esse dicionário. Se um URI não for fornecido, o componente de tempo de execução o tratará como um dicionário vazio.
O uso de
create external dictionary <dictionary-name\> allow_emptyagora está descontinuado e resulta em um aviso do compilador. -
-
'<language code(s)\>'Especifica uma lista delimitada por vírgulas de códigos de idioma de duas letras, como en (inglês) ou zh (chinês) para os idiomas ou para os idiomas de documentos para dicionários externos, nos quais avaliar o dicionário. O dicionário não produz resultados em documentos cujo código de idioma não está contido nessa sequência.
Se o parâmetro de idioma for omitido, o idioma de dicionário será padronizado para um dos conjuntos de idiomas a seguir:
- Os conjuntos de idiomas que são especificados por meio da instrução
set default language, se ela for declarada, no módulo de contenção. - Os conjuntos de idiomas que contêm alemão (de), espanhol (es), inglês (en), francês (fr), italiano (it) e o idioma não especificado (x_unspecified).
- Os conjuntos de idiomas que são especificados por meio da instrução
-
lemma_matchUse a lematização para localizar correspondências para palavras semelhantes a um termo de dicionário em seus documentos.
Lemmatização é o processo de determinação da lima para uma determinada palavra. Um lema é uma palavra que pode ser usada como uma correspondência para um único termo determinado. Por exemplo, o termo "go" pode ser correspondido aos termos "goes", "indo", "gone", ou "went". Esse processo envolve tarefas complexas, como entender o contexto e determinar a parte do discurso de uma palavra em uma sentença. A lematização está disponível para todos os idiomas para os quais o tokenizer IBM Multilingual fornece suporte de parte do discurso.
A correspondência de lema é executada somente para dicionários declarados com a cláusula
lemma match.A semântica para extração de dicionário com a cláusula
lemma_matché a seguinte:- A forma lematizada para cada token do documento de entrada é computado.
- O dicionário é avaliado com relação ao documento lematizado. Não é possível usar a opção
lemma_matchcom a opçãocase exact. Se ambas forem usadas, um erro do compilador será retornado.
-
case (exact | insensitive)Especifica o tipo de conversão, em letras maiúsculas, que o dicionário executa quando ele determina se uma região específica do documento corresponde.
-
exactEspecifica uma correspondência exata com distinção entre maiúsculas e minúsculas.
-
insensitiveEspecifica uma correspondência sem distinção entre maiúsculas e minúsculas. Esta opção é o valor padrão.
-
-
'<entry 1\>', '<entry 2\>', ... , '<entry n\>'Especifica as sequências que você deseja incluir no dicionário sequencial. As entradas em um dicionário sequencial podem consistir em um ou mais tokens.
Observações de uso
-
Os formatos
from fileefrom tablesão recomendados, especialmente quando você prevê a modificação das entradas ou quando há muitas entradas. Usando esses formatos, é possível modificar os conteúdos do dicionário sem modificar o código. -
Quando a instrução
create dictionaryé processada pelo compilador modular AQL, as referências a locais do arquivo de dicionário especificadas na sintaxecreate dictionary ... from filedevem ser relativas à raiz do módulo no qual esta instruçãocreate dictionaryé emitida. -
É possível especificar comentários em um arquivo de dicionário, precedendo o comentário com o caractere
#. Os comentários podem começar em qualquer lugar em uma linha. -
Para especificar comentários que abrangem diversas linhas, deve-se preceder cada linha com o caractere de comentário. Se o caractere de comentário fizer parte de uma entrada de dicionário, ele deverá ser escapado usando o caractere de barra invernada (\), como em
\#. Se o caractere de barra invertida fizer parte da entrada do dicionário, ele deverá ser escapado consigo mesmo, como em\\. -
Para os dicionários externos, quando os módulos estão sendo carregados, você deve especificar uma lista de URIs para dicionários externos, conforme requerido pelos módulos que estão sendo carregados.
-
Lematização de dicionários: a diferença primária entre a semântica correspondente do dicionário existente e a semântica lematizada é que a correspondência é executada com relação à forma lematizada do documento, em vez da forma original do documento.
As entradas de dicionário pertencentes a um dicionário com a correspondência de lema ativada têm estes pré-requisitos:
- Uma entrada de dicionário pode conter um ou mais tokens, em que cada token de entrada é um lema. Para criar um dicionário de lemas, é possível usar a função escalar [GetLemma.
- Os tokens de uma entrada de dicionário devem ser separados por um espaço em branco. Se o token consistir em espaços em branco, eles deverão ser escapados usando o caractere de barra invertida (\).
-
A tabela a seguir mostra as diferenças entre a instrução
create external dictionarye a instruçãocreate dictionary:
create external dictionary |
create dictionary |
|---|---|
|
|
Exemplos
Exemplo 1: criando um dicionário externo
O dicionário externo, PersonPositiveClues, espera ser preenchido com valores de um arquivo externo no tempo de carregamento. Ele também espera ser correspondido contra algumas línguas ocidentais conforme especificado por suas bandeiras.
module PersonModuleEnglish;
create external dictionary PersonPositiveClues
allow_empty false
with case exact;
export dictionary PersonPositiveClues;
Exemplo 2: lematização
Considere um dicionário que tenha a correspondência de lema ativada e contenha duas entradas: go shop e went shopping. O documento contém o texto Anna went shopping. A forma lematizada do documento de entrada é Anna go shop.
A correspondência de lema retorna went shopping como uma correspondência para a entrada go shop. O texto do documento original não é comparado com as entradas de dicionário, somente o texto do documento lematizado. Portanto, não existe nenhuma
correspondência no documento para a entrada went shopping.
Documentando as instruções create dictionary e create external dictionary com o AQL Doc
O comentário do AQL Doc para uma instrução create dictionary contém as seguintes informações:
Descrição geral sobre o dicionário.
/**
* A dictionary of terms used to greet people.
*
*/
create dictionary GreetingDict as
(
'regards', 'regds', 'hello', 'hi', 'thanks', 'best', 'subj', 'to', 'from'
);
O comentário do AQL Doc para uma instrução create external dictionary contém a descrição geral sobre o dicionário que é criado. A sequência a seguir ilustra o formato:
/**
* Customizable dictionary of given names.
* Evaluated on English, French, Italian, German, Portuguese, Spanish text.
*/
create external dictionary CustomFirstNames_WesternEurope
allow_empty true;
A instrução create table
A instrução create table cria uma tabela AQL.
A instrução create table em AQL é usada para definir tabelas de consulta estática para aumentar as anotações com mais informações.
Sintaxe
create table <table name> (
<colname> <type> [, <colname> <type>]* )
as values
( <value> [, <value>]*),
...
( <value> [, <value>]*);
Descrição
-
<table name\>Especifica o nome da tabela a ser criada. O
<table name\>pode ser um identificador simples ou um identificador entre aspas duplas. -
<colname\>Especifica o nome da coluna a ser criada.
-
<type\>Especifica o tipo de dados AQL para a coluna associada. Todas as colunas devem ser do tipo Text, Integer, Float ou Boolean.
-
<value\>Especifica as tuplas a serem preenchidas na tabela criada.
Exemplos
Exemplo 1: criando uma tabela de nomes de empresas
Neste exemplo, a instrução create table inclui mais metadados de local para as anotações de nome de empresa:
-- 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;
Documentando a instrução create table com o AQL Doc
O comentário do AQL Doc para uma instrução create table contém as seguintes informações:
- Descrição geral sobre a tabela.
- @field para cada nome de coluna no esquema desta tabela.
/** 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');
A instrução create external table
É possível usar a instrução create external table para especificar uma tabela com conteúdo estabelecido quando um módulo compilado é executado em todos os documentos de entrada. Você fornece o conteúdo da tabela durante o tempo
de carregamento em vez de no código AQL de origem e não precisa recompilar o módulo.
As tabelas externas são construções poderosas que permitem que o desenvolvedor de AQL exponha pontos de customização em um módulo compilado.
Sintaxe
create external table <table-name\>
(<colname\> <type\>
[, <colname\> <type\>]* )
allow_empty <true|false>;
Descrição
-
<table-name\>Especifica o nome da tabela externa a ser criada. O
<table-name\>pode ser um identificador simples ou um identificador entre aspas duplas. -
<colname\>Especifica o nome da coluna a ser criada.
-
<type\>Especifica o tipo de dados AQL para a coluna associada. Todas as colunas devem ser do tipo Text, Integer, Float ou Boolean.
-
[, <colname\> <type\>]*Especifica colunas adicionais e objetos AQL a serem usados na tabela externa.
-
allow_empty [true|false]Especifica o valor para a cláusula
allow_empty.-
trueSe a cláusula for
allow_empty true, o módulo pode ser executado com sucesso mesmo se um URI para o conteúdo externo não for fornecido para esta tabela. Se o URI não for fornecido, o componente de tempo de execução o tratará como uma tabela vazia. -
falseSe a cláusula for
allow_empty false, será preciso fornecer um URI para o local do arquivo que tem o conteúdo externo. O arquivo especificado deve possuir conteúdo. Se o URI não for fornecido ou se o arquivo não contiver conteúdo, o componente de tempo de execução emitirá uma exceção.
-
Observações de uso
- A representação compilada do módulo contém metadados sobre os objetos externos (visualizações, dicionários e tabelas) definidos pelo módulo.
- Quando os módulos estão sendo carregados, deve-se especificar uma lista de URIs para tabelas externas, conforme necessário para os módulos sendo carregados.
- O formato suportado para o conteúdo de uma tabela externa é um arquivo CSV (.csv) com cabeçalho.
A tabela a seguir mostra as diferenças entre a instrução create external table e a instrução create table:
create external table |
create table |
|---|---|
|
|
Exemplos
Exemplo 1: criando uma tabela externa que é preenchida no tempo de carregamento
A tabela externa, PersonNegativeClues, espera ser preenchida no tempo de carregamento por causa da sinalização, allow_empty false.
module PersonModuleFrench;
create external table PersonNegativeClues (name Text)
allow_empty false;
export table PersonNegativeClues;
Exemplo 2: criando um dicionário com uma tabela externa
Os dicionários também podem ser criados por meio de tabelas externas, de forma semelhante aos criados por meio de tabelas sequenciais que são declaradas com a instrução 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;
Documentando a instrução create external table com o AQL Doc
O comentário do AQL Doc para uma instrução create external table contém as seguintes informações:
- Descrição geral sobre a tabela.
- @field para cada nome de coluna no esquema desta tabela.
/** 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;
A instrução create external view
A instrução create external view no AQL permite a especificação de mais metadados sobre um documento como uma nova visualização, além da visualização Document predefinida que mantém o conteúdo textual e de rótulo.
Sintaxe
create external view <view_name> (
<colname> <type> [, <colname> <type>]*
)
external_name '<view_external_name>';
Descrição
-
<view_name\>Especifica o nome interno da visualização externa. A visualização externa é referida por este nome nas regras AQL. Um
<view_name\>pode ser um identificador simples ou um identificador entre aspas. Um<view_name\>não pode conter o caractere de ponto. -
<colname\>Especifica o nome da coluna a ser definida na visualização externa.
-
<type\>Especifica o tipo de dados para a coluna associada. Os tipos de dados que são suportados para colunas de visualização externa são Text, Span, Integer e Float.
-
'<view_external_name\>'Especifica o nome externo da visualização externa. Os sistemas externos que preenchem as tuplas na visualização externa referem-se à visualização externa pelo nome externo. O
'<view_external_name\>'deve ser uma constante do tipo Sequência de caracteres envolta em aspas simples ('ExternalName').
Exemplos
Para ilustrar visualizações externas, considere um aplicativo de exemplo que requer que você identifique os nomes de pessoas em e-mails.
Exemplo 1: identificando os nomes de pessoas em e-mails
Suponha que o texto de um e-mail seja "Ena, envie-me o documento ASAP". Embora um humano possa entender que Ena é um nome de uma pessoa com base no texto do e-mail, as regras de AQL escritas para identificar nomes de pessoas com alta precisão de texto geral podem ser muito conservadoras e incapazes de tirar a mesma conclusão com alta confiança, com base no fato de que Ena é uma palavra capitalizada.
Uma maneira de impulsionar a cobertura das regras é usar palavras dos campos From, To e CC do e-mail como mais evidências.
Se o e-mail for endereçado a "Ena Smith" e o aplicativo disponibilizar essas informações para o extrator, o desenvolvedor do extrator poderá gravar mais regras de AQL para impulsionar a cobertura do extrator que é baseada no conhecimento de domínio de que os e-mails geralmente são endereçados a pessoas.
Por exemplo, é possível escrever regras de AQL para identificar tokens de pessoas por meio dos campos de metadados de e-mail. Você então usa essa informação como pistas fortes quando você decide se um token capitalizado no texto do e-mail é um nome de pessoa. Em geral, os metadados de e-mail não fazem parte do e-mail real, mas o aplicativo pode disponibilizar esses metadados para o extrator usando uma visualização externa.
Para cada e-mail que deve ser processado, o aplicativo pode transmitir o texto do e-mail como texto do documento (para preencher a visualização Document) no tempo de execução. Ele também pode passar os metadados extras usando
uma visualização externa adequadamente definida.
A instrução a seguir define uma visualização externa que é nomeada EmailMetadata. A visualização externa possui um esquema que contém três campos do tipo Texto. No tempo de execução, a visualização EmailMetadata é
preenchida automaticamente por meio de um tipo externo denominado EmailMetadataSrc. Em seguida, é possível referenciar a visualização EmailMetadata em suas regras de AQL, de forma semelhante a como você referenciaria
qualquer outra visualização.
create external view EmailMetadata
(fromAddress Text, toAddress Text, ccAddress Text)
external_name 'EmailMetadataSrc';
Documentando a instrução create external view com o AQL Doc
O comentário do AQL Doc para uma instrução create external view contém as seguintes informações:
- Descrição geral sobre a visualização.
- @field para cada nome de coluna na visualização.
/**
* 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';
Formatos de arquivo para artefatos externos
Três tipos de artefatos externos são suportados: visualizações externas, dicionários externos e tabelas externas.
Dicionário externo
O formato para o arquivo que contém entradas para um dicionário externo é definido aqui:
- Arquivo de texto delimitado por retorno de linha.
- Uma entrada de dicionário por linha.
- A extensão de arquivo recomendada é .dict, mas outras extensões de arquivo podem ser suportadas.
- As entradas no dicionário podem consistir em múltiplos tokens.
- Os comentários podem ser especificados precedendo o conteúdo do comentário com o caractere,
#. - Os comentários podem começar em qualquer lugar em uma linha.
- Os comentários de multilinhas devem conter o caractere
#no início de cada linha. - As entradas de dicionário poderão conter caracteres de comentário, se cada caractere de comentário for escapado com um caractere de barra invertida. Por exemplo,
\#.
Tabela externa
O formato de arquivo suportado para o conteúdo de uma tabela externa é um arquivo .csv com cabeçalho.
O exemplo a seguir mostra uma instrução create external table e o arquivo .csv que especifica o conteúdo dessa tabela externa.
create external table Company2Location
(name Text, location Text)
allow_empty false;
A primeira linha do arquivo .csv contém o cabeçalho. As linhas restantes contêm os dados.
name,location
IBM,USA
Infosys,India
LG,Korea
Vodafone,UK
Visualização externa
O conteúdo de visualizações externas pode ser especificado das maneiras a seguir:
- Quando você executa um extrator, você pode especificar conteúdo de visualização externa para uma coleta de dados apenas quando estiver usando o formato de entrada JSON.
Funções integradas
A AQL possui uma coleção de funções integradas para uso em regras de extração.
- Funções agregadas As funções agregadas são usadas para implementar operações (como contagem, operações matemáticas e outras) em um conjunto de valores de entrada. Essas funções retornam apenas um resultado.
- Funções de predicado As funções de predicado testam um determinado predicado sobre seus argumentos de entrada e retornam um valor booleano correspondente.
- Funções escalares As funções escalares executam uma operação sobre os valores de um campo em um conjunto de tuplas de entrada e retornam um valor não booleano, como um Período, um Texto ou um Número inteiro. Essas funções
podem ser usadas dentro da lista
selectde uma instruçãoselectou de uma instruçãoextract. Elas também podem ser usadas como entradas para funções de predicado.
Funções agregadas
As funções agregadas são usadas para implementar operações (como contagem, operações matemáticas e outras) em um conjunto de valores de entrada. Essas funções retornam apenas um resultado.
Essas funções podem ser usadas dentro da lista select de uma instrução select, mas não dentro de uma instrução extract.
O exemplo a seguir é a forma geral de uma chamada de função agregada:
Aggregate_Function_Name(argument)
O argument pode ser:
-
Uma expressão que consiste em uma coluna de uma visualização na cláusula
fromou uma combinação de funções escalares que envolvem colunas das visualizações na cláusulafrom.Na maioria dos casos, exceto conforme indicado, os valores nulos para o argumento são ignorados.
-
O caractere
*no caso especial da função agregadaCount(*).Nesse caso, todas as linhas da saída são contadas, incluindo valores nulos.
| Função agregada | Tipo de argumento | Tipo de retorno | Valor de retorno |
|---|---|---|---|
| Avg(expression) | Integer, Float | Valor flutuante | A média de todos os valores de entrada ou nulos, se nenhuma linha for selecionada |
| Count(*) | Integer | O número de todas as linhas de entrada | |
| Count(expression) | Qualquer | Integer | O número de todos os valores de entrada não nulos |
| List(expression) | Integer, Float, Text, Span | Lista de valores escalares do mesmo tipo que o argumento de entrada | Uma lista não ordenada de valores de entrada não nulos: um pacote, não um conjunto, portanto, pode conter duplicatas. Uma lista vazia se somente valores nulos forem selecionados |
| Max(expression) | Integer, Float, Text, Span | O mesmo que o tipo de argumento | O elemento máximo em todos os valores de entrada ou null se nenhuma linha for selecionada |
| Min(expression) | Integer, Float, Text, Span | O mesmo que o tipo de argumento | O elemento mínimo em todos os valores de entrada ou nulos, se nenhuma linha for selecionada |
| Sum(expression) | Integer, Float | O mesmo que o tipo de argumento | A soma de todos os valores de entrada ou nulos, se nenhuma linha for selecionada |
Limitações da versão atual:
A versão atual de AQL suporta a criação de valores escalares por meio da Lista de funções aggregate.
Exemplos
O exemplo a seguir ilustra como as funções agregadas podem contar o número de anotações de nome de pessoa ou calcular conjuntos de nomes associados a cada sobrenome distinto identificado em um 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);
O exemplo a seguir ilustra o uso das funções 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;
Funções de predicado
As funções de predicado testam um determinado predicado sobre seus argumentos de entrada e retornam um valor booleano correspondente.
Os argumentos de entrada para prever funções incluem valores de retorno de outras funções escalares ou agregadas, além de dicionários, expressões regulares e muito mais. Essas funções podem ser empregadas dentro da cláusula where de uma instrução select e a cláusula having de uma instrução extract.
E
A função And aceita um número variável de argumentos booleanos e retorna os resultados de uma operação lógica AND em todos os argumentos de entrada.
O otimizador de AQL não tenta otimizar a ordem de avaliação dos argumentos para essa função como parte da operação lógica AND. Se qualquer entrada for null, o resultado será null.
Considere este formato de consulta:
select ...
from ...
where And(predicate1, predicate2);
Como resultado, um formato de consulta que usa a operação AND frequentemente é executado consideravelmente mais lento do que a mesma consulta na forma de:
select ...
from ...
where predicate1 and predicate2;
Quando possível, use o estilo SQL e a palavra-chave em vez dessa função.
Contém
A função Contains usa dois spans como argumentos:
Contains(<span1>, <span2>)
Esta função retorna TRUE se span1 completamente contém span2. Se span2 iniciar em ou após o início de span1 e terminar em ou antes do término de span1, o span2 estará completamente contido. Se qualquer argumento for null, a função retornará null.
ContainsDict
A função ContainsDict verifica se o texto de um span contém qualquer entrada de um determinado dicionário. Essa função aceita como argumentos de entrada um dicionário, uma especificação de sinalização opcional e um span para avaliar.
ContainsDict('<dictionary>', ['<flags>', ]<span>)
A função ContainsDict retornará TRUE se o span contiver uma ou mais correspondências do dicionário. As sinalizações podem ser Exact ou IgnoreCase.
- Se
Exactfor usado, uma correspondência com distinção entre maiúsculas e minúsculas será executada com relação a cada termo no dicionário. - Se
IgnoreCasefor usado, a correspondência que é executada com relação a cada termo no dicionário não fará distinção entre maiúsculas e minúsculas. - Se nenhuma sinalização for especificada, a correspondência do dicionário se baseará em qualquer sinalização especificada durante sua criação. Se nenhuma sinalização tiver sido especificada durante a criação, ela corresponderá usando a sinalização
IgnoreCase.
Se o span for null, a função retornará null.
O exemplo a seguir ilustra o uso da função 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);
Os dicionários são sempre avaliados em limites de token. Por exemplo, se um dicionário consistir no termo peixe, nenhuma correspondência existirá no texto Vamos pescar.
ContainsDicts
A função ContainsDicts verifica se o texto de uma span contém qualquer entrada de quaisquer dicionários fornecidos. Essa função aceita como argumentos de entrada dois ou mais dicionários, uma especificação de sinalização opcional
e um span para avaliar.
ContainsDicts('<dictionary>','<dictionary>','<dictionary>', ['<flags>', ]<span>)
A função ContainsDicts retornará TRUE se o span contiver uma ou mais correspondências de pelo menos um dos dicionários especificados. As sinalizações podem ser Exact ou IgnoreCase.
- Se
Exactfor usado, uma correspondência com distinção entre maiúsculas e minúsculas será executada com relação a cada um dos termos nos dicionários. - Se
IgnoreCasefor usado, a correspondência executada com relação a cada um dos termos nos dicionários será sem distinção entre maiúsculas e minúsculas. - Se nenhuma sinalização for especificada, a correspondência do dicionário se baseará em qualquer sinalização especificada durante sua criação. Se nenhuma sinalização tiver sido especificada durante a criação, ela corresponderá usando a sinalização
IgnoreCase.
Se um ou ambos os argumentos forem nulos, a função retornará null.
O exemplo a seguir ilustra o uso da função ContainsDicts com a sinalização 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
A função ContainsRegex verifica se o texto de um span corresponde a uma determinada expressão regular. Essa função aceita uma expressão regular com a qual corresponder, uma especificação de sinalização opcional e o span de entrada
com relação com o qual corresponder.
ContainsRegex(/<regular expression>/, ['<flags>', ]<span>)
A função retornará TRUE se o texto do span, que é usado como uma sequência Java™ separada, contiver uma ou mais correspondências da expressão regular. A função retornará null se o span for null. As sinalizações
opcionais afetam o comportamento de correspondência, de forma semelhante a sinalizações usadas em expressões regulares Java.
A sequência de sinalizações é formada combinando uma ou mais das sinalizações a seguir usando | como o separador:
- CANON_EQ
- CASE_INSENSITIVE
- DOTALL
- LITERAL
- MULTILINHAS
- UNICODE (sem sentido sem CASE_INSENSITIVE)
- UNIX_LINES
Um exemplo de uma sequência de sinalizações é
'UNICODE | CASE_INSENSITIVE'
Considere este exemplo em que ContainsRegex identifica nomes de produtos juntamente com suas menções de número de versão em ambos os lados. Ao contrário do exemplo para o MatchesRegex, uma correspondência de número
de versão não é estritamente identificada usando-se o regex, mas pelo contexto em torno de uma menção de nome do produto contendo um token que corresponde contra o 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)
);
Igual a
A função Equals usa dois argumentos de tipo arbitrário:
Equals(<arg1>, <arg2>)
Dois spans serão considerados iguais se ambos iniciarem e terminarem nos mesmos deslocamentos e contiverem o mesmo texto. Se um ou ambos os argumentos forem nulos, a função retornará null.
O exemplo a seguir ilustra o uso da função 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));
Segue
A função predicado Follows leva dois argumentos de span e dois argumentos inteiros:
Follows(<span1>, <span2>, <minchar>, <maxchar>)
A função retornará TRUE se o número de caracteres entre o término de span1 e o início de span2 estiver entre minchar e maxchar, inclusive. Se qualquer argumento for null,
a função retornará null.
FollowsTok
A função de predicado FollowsTok é uma versão de Follows; no entanto, os argumentos de distância FollowsTok são em termos de tokens em vez de caracteres:
FollowsTok(<span1>, <span2>, <mintok>, <maxtok>)
A função FollowsTok retorna TRUE se o número de tokens entre o final de span1 e o início de span2 está entre mintok e maxtok, inclusive. Se qualquer argumento for
null, a função retornará null.
GreaterThan
A função de predicado GreaterThan usa dois argumentos de tipo arbitrário:
GreaterThan(<arg1>, <arg2>)
A função retorna TRUE se <arg1> é maior que <arg2>. A função retornará FALSE se um dos argumentos for null.
IsNull
A função IsNull testa se os dados são, ou não, nulos. Ela usará um único argumento de qualquer tipo e retornará TRUE se o argumento único for null; caso contrário, FALSE. O comportamento
desse predicado e o predicado NotNull já definido é diferente de todos os outros predicados que retornam nulo na entrada nula.
MatchesDict
A função MatchesDict usa um dicionário (como em uma extração de dicionário), uma especificação de sinalização opcional e um período como argumentos:
MatchesDict('<dictionary>', ['<flags>', ]<span>)
A função MatchesDict retornará TRUE se o span corresponder exatamente a um ou mais dos termos no dicionário. As sinalizações podem ser Exact ou IgnoreCase.
- Se
Exactfor usado, uma correspondência com distinção entre maiúsculas e minúsculas será executada com relação a cada termo no dicionário. - Se
IgnoreCasefor usado, a correspondência que é executada com relação a cada termo no dicionário não fará distinção entre maiúsculas e minúsculas. - Se nenhuma sinalização for especificada, a correspondência do dicionário se baseará em qualquer sinalização especificada durante sua criação. Se nenhuma sinalização tiver sido especificada durante a criação, ela corresponderá usando a sinalização
IgnoreCase.
Se qualquer argumento for null, a função retornará null.
Os dicionários são sempre avaliados em limites de token. Por exemplo, se um dicionário consistir no termo peixe, nenhuma correspondência existirá no texto Vamos pescar.
MatchesRegex
A função MatchesRegex tem uma sintaxe semelhante a ContainsRegex. Ao contrário da função ContainsRegex, a função MatchesRegex retornará TRUE apenas se o texto inteiro do período,
usado como uma sequência Java separada, corresponder à expressão regular. Se qualquer argumento for null, a função retornará null. As sinalizações opcionais afetam o comportamento de correspondência semelhante a
sinalizações usadas em expressões regulares Java.
MatchesRegex(/<regular expression>/, ['<flags>', ]<span>)
A sequência de sinalizações é formada combinando um subconjunto dessas sinalizações usando | como o separador:
- CANON_EQ
- CASE_INSENSITIVE
- DOTALL
- LITERAL
- MULTILINHAS
- UNICODE (sem sentido sem CASE_INSENSITIVE)
- UNIX_LINES
Um exemplo de uma sequência de sinalizações é
'UNICODE | CASE_INSENSITIVE'
Considere este exemplo em que MatchesRegex é usado para identificar nomes de produtos juntamente com suas menções de número de versão à direita. Ao contrário do exemplo na seção ContainsRegex, o número da versão exata
é identificado como o token imediatamente seguinte à menção do nome do produto.
-- 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
A função Not usa um único argumento Boolean e retorna seu complemento. Se o argumento for null, a função retornará null.
NotNull
A função NotNull leva um único argumento de qualquer tipo.
Como seu nome sugere, a função NotNull retornará TRUE se o valor do argumento não for null e FALSE se o argumento for null.
Ou
A função Or usa um número variável de argumentos Boolean não nulos. Se qualquer argumento for null, a função retornará null.
A função Or retornará TRUE se qualquer uma delas for avaliada como TRUE.
Overlaps
A função Overlaps usa dois argumentos de span:
Overlaps(<span1>, <span2>)
A função retornará TRUE se os dois spans de entrada se sobrepuserem no texto do documento. A função retornará null se o argumento for null.
Funções escalares
Funções escalares executam uma operação sobre os valores de um campo por meio de um conjunto de tuplas de entrada e retornam um valor não booleano, como um Span, Text ou Integer. Essas funções podem ser usadas dentro da lista select de uma instrução
select ou de uma instrução extract. Elas também podem ser usadas como entradas para funções de predicado.
Se um objeto Text for fornecido onde um objeto Span é necessário, um objeto Span convertido será automaticamente gerado, o qual é baseado nesse objeto Text, com deslocamentos iniciais e finais cobrindo todo o comprimento do objeto Text.
Se um objeto Span for fornecido onde um objeto Text é necessário, um objeto Text convertido será automaticamente gerado por meio do valor de texto do objeto Span.
Chomp
A função Chomp é semelhante ao operador Chomp em Perl, exceto que Chomp opera sobre spans em vez de sequências:
Chomp(<span1>)
O exemplo a seguir ilustra o uso da função 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 o span de entrada contiver algum espaço em branco no início ou no término, a função Chomp reduzirá o span suficientemente para remover o espaço em branco. Em seguida, a função retornará um novo span sem nenhum espaço em branco
à esquerda ou à direita. Se o span de entrada não tiver um espaço em branco à esquerda ou à direita, a função Chomp retornará o mesmo span. Se o span de entrada for null, o Chomp retornará null.
CombineSpans
A função CombineSpans usará dois spans como entrada e retornará o span mais curto que cobre completamente ambos os spans de entrada se os spans forem baseados no mesmo objeto de texto.
CombineSpans(['IgnoreOrder',] <span1>, <span2>)
A função CombineSpans é sensível à ordem de seus spans de entrada, a menos que você use o parâmetro IgnoreOrder. Quando o parâmetro IgnoreOrder opcional é usado, a ordem dos dois spans é ignorada.
O exemplo a seguir ilustra o uso da função 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);
A semântica da função é a seguinte:
- Se
span1ouspan2fornull, ou as duas spans estiverem sobre diferentes objetos Texto, a função retornaránull. - Caso contrário, se
span1for menor quespan2ou o parâmetroIgnoreOrderfor usado, a função retornará o span mais curto que cobrespan1espan2. - Caso contrário (
span1é maior quespan2eIgnoreOrdernão é usado), a função retornará um erro de tempo de execução.
Com base na definição de Span, os diferentes cenários de argumentos para a função CombineSpans são conforme a seguir:
-
O intervalo 2 é sempre após o intervalo 1. Em outras palavras, a ordem da esquerda para a direita é mantida:
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] -
O intervalo 2 não é após o intervalo 1. Em outras palavras, a ordem da esquerda para a direita não é mantida:
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
A função GetBegin usa um único argumento de span e retorna o deslocamento de início do span de entrada.
Por exemplo,
GetBegin([5, 10])
retorna o valor 5.
Da mesma forma, a função GetEnd retorna o deslocamento final de seu span de entrada.
O exemplo a seguir ilustra o uso das funções GetBegin e GetEnd.
create view PersonOffsets as
select GetBegin(P.name) as offsetBegin, GetEnd(P.name) as offsetEnd
from Person P;
Para ambas as funções, se o argumento for null, a função retornará null.
GetLanguage
A função GetLanguage usa um único argumento de span e retorna o código de idioma com duas letras do texto de origem do span. Se o argumento for null, a função retornará null.
Essa instrução produzirá resultados significativos somente se a origem de dados estiver identificando campos de texto com os idiomas apropriados.
GetLemma
A função GetLemma usa um único objeto Span ou Text como um argumento e retorna uma sequência que contém a forma lematizada do span de entrada. Se o argumento for null, a função retornará null. Com entradas
do dicionário para correspondência de lema, essa função pode determinar a forma lematizada de vários tokens conforme retornada pelo tokenizer. Por exemplo, para o span went shopping, GetLemma retornará a sequência de lema go shop.
Os resultados dessa função seguem estas regras:
- Se o intervalo de entrada começar no início de um token e terminar no final de um token, o resultado conterá a sequência de lemas que começa com o lema do primeiro token, seguida por um espaço em branco, pelo lema do segundo token, por um espaço em branco e assim por diante (por exemplo, cachorro cato peixe pássaro...). Se o lema para um token consistir em espaços em branco, escape o espaço em branco usando o caractere de barra invertida (\).
- Se o período da entrada começar ou terminar com espaço em branco (por exemplo, ele começa entre dois tokens ou termina entre dois tokens), a função ignorará o espaço em branco inicial e final.
- Se o período da entrada começar no meio de um token ou terminar no meio de um token, a saída consistirá no conteúdo a seguir, nesta ordem, e separada por um espaço em branco:
- A forma superficial do primeiro token parcial, se ele existir.
- A sequência de lemmas que correspondem ao primeiro a últimos tokens completos. Se o lema de qualquer um dos tokens completos consistir em espaços em branco, escape-os usando o caractere de barra invertida (\).
- A forma superficial do último token parcial, se ele existir.
Essa função retorna um erro se o tokenizer que estiver sendo usado não for capaz de produzir lemas.
É possível usar a função GetLemma() para criar dicionários de formas lematizadas. Chame GetLemma() em uma entrada que contém os termos cuja forma lematizada você deseja incluir no dicionário.
GetLength
A função GetLength usa um único argumento de span e retorna o comprimento do span de entrada. Se o argumento for null, a função retornará null.
Por exemplo,
GetLength([5, 12])
retorna um valor de 7.
GetLengthTok
A função GetLengthTok usa um único argumento de span e retorna o comprimento do span de entrada em tokens. Se o argumento de entrada for null, a função retornará null.
GetString
A função GetString usa um único objeto AQL como seu argumento e retorna um objeto de Texto formado da representação de sequência do objeto.
Para argumentos de período e de texto, os valores retornados são diferentes dos retornados por GetText(). Para objetos de Texto, o valor retornado inclui aspas simples em torno da sequência de texto. Para objetos de span, o valor
retornado incluirá, além disso, deslocamentos entre parênteses.
Para listas escalares, essa função retorna os valores de GetString() dos elementos da lista, concatenados com pontos e vírgulas. Para argumentos Integer, Float, Boolean e String, essa função retorna o valor do argumento como uma
sequência. Para argumentos null, essa função retorna null.
GetText
A função GetText usa um único span ou texto como um argumento. Para entrada de span, ela retorna o objeto de texto com base na sequência de texto real que o span marca. Para entrada de texto, ele retorna o objeto de texto de entrada.
Se a entrada for null, essa função retornará null. Por exemplo:
GetText([5, 12])
O span retorna a subsequência do documento da posição de caractere 5 - 12.
A função GetText tem dois usos primários.
Teste para igualdade de sequência entre o texto marcado por dois spans.
-- 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;
Dividindo um documento em subdocumentos menores.
Por exemplo, se o documento principal for um blog que consiste em múltiplas entradas de blog, será possível usar o GetText para criar um subdocumento para cada entrada de 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
A função LeftContext leva um Span e um Integer como entrada:
LeftContext(<input span>, <nchars>)
A função LeftContext(<input span\>, <nchars\>) retorna um novo intervalo que contém os caracteres nchars do documento imediatamente à esquerda de <input span\>. Se o intervalo de entrada começar
menos de <nchars\> caracteres do início do documento, LeftContext() retornará um intervalo que começa no início do documento e que continua até o início do intervalo de entrada.
Por exemplo, LeftContext([20, 30], 10) retorna o período [10, 20]. O período LeftContext([5, 10], 10) retorna [0, 5].
Se a entrada começar no primeiro caractere do documento, LeftContext() retornará um período de comprimento zero. Da mesma forma, a função RightContext retorna o texto à direita de seu span de entrada. Para ambas as
funções, se qualquer um dos argumentos for null, a função retornará
null.
LeftContextTok e RightContextTok
As funções LeftContextTok e RightContextTok são versões de LeftContext e RightContext que tiram distâncias em termos de tokens:
LeftContextTok(<input span>, <num tokens>)
RightContextTok(<input span>, <num tokens>)
O exemplo a seguir ilustra o uso da função 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;
Para ambas as funções, se qualquer um dos argumentos for null, a função retornará
null.
Remap
A função Remap usa um único argumento de span:
Remap(<span>)
Se o span de entrada estiver sobre um objeto de texto que foi produzido transformando outro objeto de texto, a função Remap converterá o span em um span sobre o texto de "origem" original.
Por exemplo, se o span N.name estiver sobre um documento com tag removida que é produzido executando HTML por meio da instrução AQL detag, então
Remap(<N.name>)
retornará um span equivalente sobre o HTML original.
Se o argumento de período tiver sido produzido executando a instrução detag em um documento vazio, a função remapeará os períodos para o início do documento (ou seja, Document.text[0-0]). Além disso, se a instrução detag produzir uma sequência vazia, a função remapeará os spans para o início do documento. A única parte de AQL que produz tal objeto de texto derivado é a instrução detag.
O exemplo a seguir ilustra o uso da função 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 o argumento para Remap não for um objeto de texto derivado ou um span sobre um objeto de texto derivado, a função gerará um erro. Se o argumento for null, a função retornará null.
SpanBetween
A função SpanBetween leva duas spans como entrada e retorna a span que exatamente cobre o texto entre as duas spans se os spans se baseiam no mesmo objeto de texto, e retorna null se eles forem baseados em diferentes
objetos de texto:
SpanBetween(['IgnoreOrder',] <span1>, <span2>)
Quando o parâmetro IgnoreOrder opcional é usado, a ordem dos dois spans é ignorada pelo compilador de AQL.
Se não houver texto entre os dois intervalos, SpanBetween retornará um intervalo vazio que começa no final de <span1>.
Assim como CombineSpans, SpanBetween reconhece à ordem de suas entradas, a menos que você use o parâmetro IgnoreOrder. Portanto,
SpanBetween([5, 10], [50, 60])
retorna o span [10, 50], enquanto
SpanBetween([50, 60], [5, 10])
retorna o span [60, 60].
Se o argumento para SpanBetween for null, a função retornará null.
SpanIntersection
A função SpanIntersection usará dois spans como entrada e retornará um span que cobre o texto que ambas as entradas cobrirão se os spans forem baseados no mesmo objeto de texto e retornará null se eles forem baseados
em diferentes objetos de texto:
SpanIntersection(<span1>, <span2>)
Por exemplo,
SpanIntersection([5, 20], [10, 60])
retorna o span [10, 20], enquanto
SpanIntersection([5, 20], [7, 10])
retorna o span [7, 10].
Se os dois spans não se sobrepuserem, o SpanIntersection retornará null. Se uma das entradas de span for null, a função retornará null.
SubSpanTok
A função SubSpanTok usa como entrada um span e um par de deslocamentos para o span:
SubSpanTok(<span>, <first_tok>, <last_tok>)
Como o nome da função sugere, os argumentos <first_tok> e <last_tok> são distâncias em tokens, de acordo com o que o tokenizer do sistema estiver configurado para usar.
A função SubSpanTok retorna um novo span que cobre o intervalo indicado de tokens, inclusive, dentro do span de entrada. Se o intervalo especificado iniciar dentro do span e for além do término do span, a parte do intervalo que
estiver contida será retornada. Se o <first_tok> representar uma distância além do intervalo de destino, SubSpanTok retornará um intervalo de comprimento zero que começa no início do intervalo de entrada.
Se qualquer entrada for null, a função retornará null.
ToLowerCase
A função ToLowerCase leva um único objeto como seu argumento e retorna uma representação de cadeia minússola do objeto. A conversão em uma sequência ocorre da mesma maneira que a função GetString() executa a conversão.
O uso primário dessa função é executar junções de igualdade que são sem distinção entre maiúsculas e minúsculas:
where Equals(ToLowerCase(C.company), ToLowerCase(N2C.name))
Se o objeto de entrada for null, a função retornará null.
A instrução create function
Para executar operações em valores extraídos que não são suportados pela AQL, é possível definir funções customizadas para usar em regras de extração chamadas de funções definidas pelo usuário (UDFs).
A AQL suporta funções escalares definidas pelo usuário e funções de tabelas definidas pelo usuário. Java™ e PMML são as únicas linguagens de implementação suportadas para UDFs. Uma função escalar retorna um único valor escalar e uma função de tabela retorna uma ou mais tuplas, em outras palavras, uma tabela.
Implemente funções definidas pelo usuário (UDFs) seguindo quatro etapas:
-
Implementando a função
A AQL suporta funções definidas pelo usuário (UDFs) que são implementadas em Java ou PMML.
-
Declarando-a em AQL.
É possível tornar as funções escalares definidas pelo usuário e os modelos de aprendizado de máquina de arquivos PMML disponíveis para a AQL usando a instrução
create function. -
Usando-a em AQL.
As funções definidas pelo usuário funcionam com as instruções e as cláusulas AQL.
-
Depurando a UDF.
Como as funções definidas pelo usuário (UDFs) baseadas em Java são implementadas como métodos públicos em classes Java, você depurará as UDFs da mesma maneira que depura os programas Java.
Implementando funções definidas pelo usuário
A AQL suporta funções definidas pelo usuário (UDFs) que são implementadas em Java™ ou em PMML.
Esta seção se concentra especificamente em UDFs que são implementadas em Java. Para UDFs implementadas em PMML, o modelo de aprendizado de máquina é armazenado dentro do arquivo XML de PMML. Consulte a documentação do PMML para saber como criar esses modelos: [http://dmg.org/pmml/v4-1/GeneralStructure.html]
É possível implementar uma UDF Escalar como um método público em uma classe Java. É possível implementar uma UDF de tabela como um método público em uma classe Java que amplia a API com.ibm.avatar.api.udf.TableUDFBase. Além disso, uma UDF de
tabela pode, opcionalmente, substituir o método initState() da superclasse com.ibm.avatar.api.udf.TableUDFBase.
Se a UDF tiver um parâmetro de entrada do tipo Span, Text ou ScalarList ou o tipo de retorno da UDF for Span, Text ou ScalarList, a classe Java deverá importar as classes com.ibm.avatar.algebra.datamodel.Span, com.ibm.avatar.algebra.datamodel.Text ou com.ibm.avatar.algebra.datamodel.ScalarList para compilar.
As funções da tabela requerem APIs adicionais para fornecer informações do esquema de saída. Essas APIs pertencem à classe base com.ibm.systemt.api.udf.TableUDFbase. Se uma subclasse contiver mais de uma função da tabela, um objeto Java separado será criado para cada instância.
Para que o código UDF recupere recursos que não são de classe do arquivo JAR, o único método suportado é getResourceAsStream(). Outros métodos para acessar recursos (tais como getResource(), getResources(),
getSystemResource()) não são suportados. Por exemplo, um arquivo JAR UDF que contém o arquivo de propriedades my.properties no package (pacote de arquivos) do pacote, pode acessá-lo com a seguinte instrução Java:
InputStream in = this.getClass().getClassLoader().
getResourceAsStream(“com/ibm/myproject/udfs/my.properties”);
Ciclo de vida de UDFs implementadas em Java
As operações a seguir são executadas quando o extrator é compilado (a API CompileAQL.compile()), instanciado (API OperatorGraph.createOG()) e validado (API OperatorGraph.validateOG()), exatamente uma
vez para cada instrução create function na AQL:
- Carregue a classe Java que contém o método UDF, usando um novo carregador de classes. A classe é procurada dentro do JAR de UDF especificado na instrução de função create correspondente. Quaisquer outras classes que forem necessárias ao carregar essa classe também serão procuradas dentro do mesmo JAR de UDF e, se não localizadas, a procura será delegada ao carregador de classes que instanciou o Runtime.
- Crie uma instância dessa classe.
- Para UDFs de tabela, chame o método
initState().
Como essas etapas são executadas para cada instrução create function, se uma classe Java contiver diversos métodos UDF (e todos eles forem usados na AQL em diferentes instruções create function), a classe será carregada diversas vezes, cada
vez em um carregador de classes separado (Etapa 1). Além disso, diversas instâncias da classe são criadas (Etapa 2) e o método initState() é chamado uma vez para cada instância (Etapa 3). O motivo de cada UDF resultar em um
carregador de classes separado é permitir que diferentes UDFs usem versões diferentes da mesma classe (ou biblioteca).
No tempo de execução (API OperatorGraph.execute()), a classe UDF não é carregada novamente porque a classe é carregada durante a instanciação do extrator. O método Java que implementa a UDF é chamado, quando necessário, para computar
partes da saída. Quando o extrator é usado em um encadeamento único, isso significa que existe de zero a possivelmente muitas chamadas para cada documento de entrada (e muito provavelmente diversas chamadas ao longo da vida do objeto Gráfico
do operador). Quando o extrator é compartilhado entre diversos encadeamentos, diferentes encadeamentos podem atingir o método ao mesmo tempo (com entradas diferentes).
Se for necessário que uma parte específica do código UDF seja avaliada exatamente uma vez, por exemplo, para inicializar estruturas de dados necessárias para o método UDF nas chamadas, esse código não deverá ser colocado no método de avaliação UDF, uma vez que esse método é muito provavelmente executado diversas vezes ao longo da vida do extrator (como o objeto OperatorGraph), podendo ser atingido quase simultaneamente quando o extrator for compartilhado entre diversos encadeamentos. Em vez disso:
- Para UDFs escalares, siga os princípios padrão de programação Java. Por exemplo, coloque o código em um bloco estático.
- Para UDFs de tabela, coloque o código no método
initState()ou siga os princípios de programação Java padrão. Por exemplo, coloque o código em um bloco estático.
Ao fazer isso, lembre-se de que a classe pode ser carregada diversas vezes durante a compilação, a instanciação e a validação do extrato, conforme explicado nas Etapas 1-3 acima. Se o código que inicializa a UDF for colocado em um bloco estático, esse código será executado cada vez que a classe for carregada (potencialmente diversas vezes), introduzindo, portanto, uma sobrecarga durante a compilação e a instanciação do gráfico do operador. Se a sobrecarga for grande, siga estas melhores práticas:
- Para minimizar a sobrecarga durante o tempo de compilação, a melhor prática é colocar recursos pesados de tempo de compilação, como grandes dicionários ou UDFs com o tempo de inicialização grande em um módulo AQL separado e exportá-los. Tente compilar somente os módulos do AQL que foram mudados e outros módulos que dependam deles.
- Para minimizar a sobrecarga durante a instanciação e validação do gráfico de operador:
- Se o código de inicialização for necessário para um único método UDF, coloque esse método UDF em uma classe Java separada (e coloque o código de instanciação pesado em um inicializador estático como antes ou use algum outro mecanismo que assegure que o código seja executado uma vez).
- Se o código de inicialização for compartilhado por múltiplos métodos UDF, o Runtime e o AQL não fornecerão um mecanismo explícito para assegurar que o código de inicialização seja executado exatamente uma vez. Nessa situação, se o tempo de inicialização for proibitivo, a única solução será colocar os recursos compartilhados e o código de inicialização no caminho de classe do sistema. Ou seja, coloque o código de inicialização em uma nova classe MySeparateClass.java e armazene o resultado da inicialização em uma variável estática dessa classe, como MySeparateClass.myVar. Compacte MySeparateClass.java com todos os recursos que são necessários durante a inicialização em um arquivo JAR e coloque esse JAR no caminho de classe do sistema. Os métodos UDF podem referir-se ao modelo inicializado usando a variável estática MySeparateClass.myVar. O código de inicialização agora é executado exatamente uma vez, quando a classe MySeparateClass.java é carregada pelo carregador de classes do sistema.
Dica:
A representação compilada de um módulo (o arquivo .tam) contém o código binário serializado da UDF. Portanto, se o mesmo código UDF for referenciado por instruções create function em dois módulos diferentes, o código
UDF será serializado na representação compilada de ambos os módulos. Em outras palavras, o código UDF é serializado duas vezes. Nesses casos, é possível evitar a redundância criando um módulo separado que age como uma biblioteca de UDFs
e reutilizar essa biblioteca em outros módulos. Para criar uma biblioteca de UDFs, siga estas etapas:
- Crie um módulo.
- Coloque todos os arquivos JAR de UDF dentro desse módulo.
- Defina todas as funções necessárias com as instruções
create function. - Exporte todas elas com instruções
export functionpara que possam ser importadas e usadas em outros módulos.
Exemplos
Exemplo 1: implementando uma UDF escalar
Este exemplo mostra a implementação de uma UDF escalar denominada toUpperCase. Essa UDF usa como entrada um valor do tipo Span e gera um valor de sequência que consiste no conteúdo de texto da entrada Span, convertido em maiúsculas.
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();
}
Exemplo 2: implementando uma UDF escalar que usa uma tabela como entrada
Este exemplo mostra a implementação de uma UDF escalar nomeada TableConsumingScalarFunc. Esta UDF toma como entrada duas listas de tuplas e gera um valor de sequência que concatena o conteúdo das duas listas de tuplas de entrada.
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 ();
}
}
Exemplo 3: implementando uma UDF de tabela que usa uma tabela como entrada
Este exemplo mostra a implementação de uma UDF de tabela nomeada TableConsumingTableFunc. Essa UDF usa como entrada duas listas de tuplas e gera uma única lista de tuplas que contém tuplas da primeira entrada intercaladas com tuplas da segunda entrada. Observe que a implementação se amplia por meio da classe base com.ibm.avatar.api.udf.TableUDFBase, que fornece APIs para obter os esquemas de entrada e saída.
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)); }
}
}
}
Declarando funções definidas pelo usuário
É possível tornar as funções escalares definidas pelo usuário e os modelos de aprendizado de máquina de arquivos PMML disponíveis para a AQL usando a instrução create function.
Sintaxe
A sintaxe geral da instrução create function é conforme a seguir:
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>]*
Descrição
-
<function-name\>O
<function-name\>declara o nome de AQL da UDF. A UDF é referida no código AQL com esse nome -
<input-schema-definition\>Especifica os parâmetros de entrada da UDF. Um parâmetro de entrada tem um nome, que é especificado como
<column-name\>e que pode ser um tipo escalar ou um localizador de tabelas. Quando a linguagem é PMML, a função deve usar uma única tabela chamadaparamscomo o argumento. -
<column-name\>Especifica o nome de uma coluna na entrada ou na saída da UDF.
-
<data-type\>O tipo de um parâmetro escalar de entrada para a UDF, o tipo de uma coluna no esquema de uma tabela de entrada para a UDF ou no esquema da tabela de saída da UDF. Os valores possíveis para
<data-type\>são: Integer, Float, String, Text, Span, Boolean ou ScalarList. -
table (<output-schema-definition\>) as locatorEsse tipo de entrada permite que uma função use como entrada os conteúdos inteiros de uma determinada visualização AQL conforme computado no documento atual. O parâmetro de localizador referencia visualizações ou tabelas como argumentos.
-
<return-type\>Para UDFs escalares, o
<return-type\>especifica o tipo do valor escalar que é retornado pela UDF. Os valores possíveis para o tipo de retorno são: Integer, Float, String, Text, Span, Boolean ou ScalarList. Se o tipo de retorno for Integer, a função Java™ que implementa a UDF retornará objetos do tipo Integer. A implementação UDF não pode retornar o tipo int primitivo. Se o tipo de retorno for Texto ou Span, especifique o parâmetro de entrada a partir do qual o tipo de retorno é derivado. É possível especificar o parâmetro de entrada usando a especificação like opcional, uma vez que os spans são sempre de uma coluna subjacente. Se o tipo de retorno for ScalarList, especifique o parâmetro de entrada por meio do qual o tipo escalar dentro do ScalarList deve ser inferido. Quando a linguagem é PMML, a função deve retornar uma tabela. -
<output-schema-definition\>Para UDFs de tabela, o
<output-schema-definition\>especifica o esquema de saída da tabela que é retornado pela UDF, incluindo os nomes de colunas e seus tipos. -
<ext-name\>O external_name especifica onde localizar a implementação da UDF. Quando o idioma é Java, ele é uma sequência do formulário
'<jar-file-name\>:<fully-qualified-class-name\>!<method-name\>'que consiste em três partes:- Nome do arquivo JAR: quando você compila a AQL modular, as referências de local de arquivos JAR de UDF devem ser relativas à raiz do módulo no qual a referência é feita.
- Nome de classe: nome completo de classe que contém a implementação UDF
- Nome do método: o método deve ser um método público da classe. A assinatura de método deve corresponder aos tipos de parâmetro que são especificados na instrução
create function. A conversão de tipo automático não é feita pelo componente de tempo de execução. Quando a linguagem é PMML, a cláusula external_name especifica uma sequência que é a localização do arquivo PMML em relação ao diretório-raiz do módulo. A implementação atual suporta modelos que são expressos usando o padrão PMML versão 4.1 e os avalia usando a biblioteca org.jpmml versão 1.0.22.
-
languageA especificação de linguagem aponta para a linguagem de implementação da UDF. O componente de tempo de execução suporta somente UDFs que são implementadas em Java™.
-
deterministic/not deterministicO deterministic/not deterministic opcional especifica se a função é stateless. Uma função determinística sempre retorna o mesmo valor para o mesmo conjunto de valores de entrada.
-
return null on null inputO return null on null input opcional especifica o comportamento da função quando um ou mais dos valores de entrada são nulos. Se o retorno de nulo na entrada nula for especificado, o sistema retornará
nullna entrada nula sem chamar a UDF. Se chamada de entrada nula for especificada, a UDF é invocada até mesmo para valores de entrada nulos.
Notas de uso para UDFs implementadas em PMML
As funções criadas de arquivos PMML usam uma única tabela chamada params como argumento e geram uma tabela. A implementação da função mapeia campos de entrada entre os esquemas de entrada e de saída declarados na instrução create
function e o esquema especificado no arquivo PMML. Em outras palavras, a seção DataDictionary que descreve os nomes e os tipos de campos que podem aparecer nos registros de entrada e saída que o modelo produz e consome,
a seção MiningSchema que informa quais arquivos denominados definidos na seção DataDictionary estão em cada tupla que representa um vetor de recurso e a seção Output que informa quais campos denominados
na seção DataDictionary estão presentes em cada tupla da representação externa da saída do modelo. Essas funções devem ser funções de tabela; cada linha na tabela é transmitida para o modelo PMML e produz uma linha de saída.
Essas informações do esquema são necessárias porque os sistemas do tipo PMML e AQL não correspondem perfeitamente. Por exemplo, a PMML tem vários tipos para representar os registros de data e hora, enquanto a AQL requer atualmente que os usuários codifiquem os registros de data e hora como valores de sequência. As informações do esquema também permitem que os desenvolvedores que conhecem a AQL, mas não a PMML, entendam o conjunto de regras da AQL.
O compilador AQL verifica o esquema de entrada com relação ao esquema de entrada do arquivo PMML para assegurar que os dois esquemas sejam compatíveis. Se os dois esquemas contiverem campos com o mesmo nome, mas tipos incompatíveis, a compilação
falhará com uma mensagem de erro apropriada. Se os esquemas de entrada ou de saída da função contiverem colunas adicionais ou ausentes, a função resulting ignorará essas colunas e não gerará um erro. A ordem de nomes de colunas
pode ser diferente entre a definição de AQL e o arquivo de PMML. Se um nome de coluna aparecer nos esquemas de entrada e de saída, mas não no esquema PMML, os valores dessa coluna serão transmitidos para a saída da função.
Exemplos
Exemplo 1: declarando UDFs escalares com valores escalares como entrada usando Java
O exemplo a seguir mostra uma instrução create function que declara uma função denominada udfCombineSpans. A função definida pelo usuário usa dois spans como entrada e retorna um span mesclado semelhante ao primeiro
span de entrada. A função real UDF Java™ é compactada em um arquivo JAR denominado udfs.jar, no diretório udfjars. O método que implementa a função é combineSpans na classe com.ibm.test.udfs.MiscScalarFunc.
O método também declara uma função udfSpanGreaterThan que retornará true se o período for maior que o tamanho especificado.
/**
* 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;
O próximo exemplo mostra como declarar uma função denominada udfCompareNames que recebe uma lista de nomes nameList e um único nome myName. A saída é uma lista semelhante à lista de entrada, que contém apenas as entradas de nameList semelhantes 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;
Exemplo 2: declarando UDFs escalares com tabelas como entrada usando Java
O exemplo a seguir ilustra o uso do tipo de entrada table as locator. Ele mostra uma instrução create function que declara uma função chamada MyScalarFunc. A implementação Java™ da UDF é empacotada dentro da classe
com.ibm.test.udfs.TableConsumingScalarFunc.
Esta UDF toma como entrada duas listas de tuplas e gera um valor de sequência que concatena o conteúdo das duas listas de tuplas de entrada. A implementação Java™ da UDF está incluída em Implementando funções definidas pelo usuário.
-- 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;
Exemplo 3: Declarando UDFs de tabela usando Java
O exemplo a seguir ilustra o uso da cláusula return table. O exemplo mostra uma instrução create function que declara uma função de tabela chamada MyScalarFunc. A implementação Java™ da UDF é empacotada dentro da
classe TEST.UDFS.TABLECONSUMINGTABLEFUNC. Essa UDF usa como entrada duas listas de tuplas e gera uma lista de tuplas que mesclam as listas de entrada. A implementação Java™ da UDF está incluída em Implementando funções definidas pelo usuário.
-- 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;
Exemplo 4: declarando uma UDF de tabela implementada em PMML
O exemplo a seguir mostra uma instrução create function que declara uma função de tabela denominada IrisDecisionTree usando a linguagem PMML. A implementação de PMML da UDF é especificada no arquivo IrisTree.xml, mostrado no exemplo
a seguir. O modelo armazenado no IrisTree.xml é um modelo de árvore de decisão.
-- 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>
Documentando a instrução create function com comentários
O comentário do AQL Doc para uma instrução de função create contém as informações a seguir:
- Uma descrição geral sobre a função.
- A descrição @param que especifica cada nome de parâmetro que é usado na função. Indique o tipo do parâmetro, se é um tipo escalar ou uma tabela. Se o parâmetro for uma tabela, descreva o esquema da tabela, incluindo os nomes e os tipos de coluna na ordem em que aparecem no esquema da tabela esperada como entrada.
- A descrição @return que especifica as informações que são retornadas pela função. Se a função retornar uma tabela, especifique o esquema de saída da tabela, incluindo nomes de colunas e tipos na ordem em que eles aparecem no esquema da tabela de saída.
/**
* 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;
Usando funções definidas pelo usuário
As funções definidas pelo usuário funcionam com as instruções e as cláusulas AQL.
As funções escalares definidas pelo usuário funcionam com as instruções e as cláusulas AQL, semelhantes a funções integradas. Especificamente, as UDFs escalares podem ser usadas nas cláusulas select, where, having,
group by e order by da mesma maneira que as funções escalares integradas, como GetBegin e LeftContext. Funções escalares definidas pelo usuário que retornam um tipo booleano podem ser usadas
como predicados em where e having cláusulas.
As funções de tabela definidas pelo usuário (UDFs de tabela) podem ser usadas na cláusula from de uma instrução select ou de uma instrução extract.
Exemplos
Exemplo 1: usando UDFs escalares implementadas em Java com valores escalares como entrada
Este exemplo demonstra como usar as funções udfCombineSpans e udfSpanGreaterThan que são declaradas em Declarando funções definidas pelo usuário.
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);
Exemplo 2: usando UDFs escalares implementadas em Java com tabelas como entrada
O exemplo a seguir mostra como usar uma função escalar que usa tabelas como entrada. Este exemplo ilustra o uso da função UDF da tabela MyScalarFunc, cuja implementação Java™ está incluída em Implementando funções definidas pelo usuário. Elas são os mesmos tipos de coluna, mas têm nomes de coluna diferentes.
-- 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;
Exemplo 3: usando UDFs de tabela implementadas em Java
Este exemplo ilustra o uso da função UDF da tabela MyTableFunc, cuja implementação Java™ está incluída em Implementando funções definidas pelo usuário.
-- 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;
Como no Exemplo 2, O exemplo define duas visualizações: FirstInputView com schema (match Span) e SecondInputView com schema (spanCol Span, textCol Text). A última visualização no exemplo,
TabFuncOutput, chama a função table MyTableFunc na cláusula from, com as duas visualizações de entrada. Conforme explicado no Exemplo 2, uma visualização é compatível com um argumento de localizador
de tabela de uma função, desde que o número de colunas e os tipos de colunas no esquema da visualização de entrada e do localizador de tabela correspondam. No entanto, não é necessário que os nomes da coluna correspondam.
Finalmente, a cláusula select descarta a coluna outStr na tabela de saída de MyTableFunc, mantendo somente as duas primeiras colunas outSpan1 e outSpan2.
Exemplo 4: usando uma UDF de tabela implementada em PMML
Este exemplo ilustra o uso da função UDF da tabela IrisDecisionTree que é declarada no exemplo 4 de Declarando funções definidas pelo usuário.
-- 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;