어노테이션 조회 언어(AQL) 참조
어노테이션 조회 언어(AQL)는 IBM Watson® Knowledge Studio 고급 규칙 추출기를 작성하는 데 사용하는 기본 언어입니다.
- 데이터 모델: AQL의 데이터 모델은 SQL 데이터베이스(예: DB2®)에서 사용하는 표준 관계형 모델과 유사합니다. AQL의 모든 데이터는 튜플, 하나 이상 열의 데이터 레코드 또는 필드에 저장됩니다. 튜플의 콜렉션이 뷰를 형성합니다. 뷰의 모든 튜플에 동일한 스키마가 있습니다. 즉, 모든 튜플에 필드의 이름과 유형이 있습니다.
- 실행 모델: 런타임 컴포넌트에는 한 번에 하나의 문서(document-at-a-time) 실행 모델이 있습니다. 런타임 컴포넌트에서 문서의 콜렉션을 받고 각 문서에서 추출기를 실행하여 해당 문서에서 정보를 추출합니다.
- AQL 명령문: AQL 명령문을 사용하여 모듈, 뷰, 테이블, 사전 및 함수를 작성하고 사용할 수 있습니다.
- 기본 제공 함수: AQL에는 추출 규칙에 사용할 수 있는 기본 제공 함수 콜렉션이 있습니다.
- create function 명령문: AQL에서 지원하지 않는 추출된 값에 대해 연산을 수행하려면 사용자 정의 함수(UDF)라는 추출 규칙에서 사용할 사용자 정의 함수를 정의할 수 있습니다.
어노테이션 조회 언어(AQL) 구문
많은 프로그래밍 언어와 마찬가지로 AQL은 공통 구문 및 문법을 기반으로 합니다.
프로그래밍 언어의 렉시칼 구조는 예약어, ID, 상수 등과 같은 언의 기본 컴포넌트 또는 토큰을 정의하는 기본 규칙 세트입니다.
AQL 구문은 SQL 구문과 유사하지만, 다음과 같이 몇 가지 중요한 차이점이 있습니다.
-
AQL은 대소문자를 구문합니다.
-
AQL에서는 상관 하위 조회 및 회귀 조회와 같은 고급 SQL 기능을 지원하지 않습니다.
-
AQL에는 SQL에 없는 새로운 명령문 유형인
extract
가 있습니다. -
AQL에서는 키워드(예약어)를 뷰, 열 또는 함수 이름으로 사용할 수 없습니다.
-
AQL에서는 정규식을 Perl 구문으로 표현할 필요가 없으며 허용되지도 않습니다. 정규식은 Perl 구문과 같이 슬래시(
/
)로 시작하고 슬래시(/
)로 끝납니다. 또한 AQL은 작은따옴표 ('
)로 시작하고 작은따옴표 ('
)로 끝나는 정규식을 허용합니다. 예를 들어, AQL에서 정규식으로'regex'
대신/regex/
을(를) 사용할 수 있습니다. -
ID: ID는 모듈, 뷰, 테이블, 사전, 함수, 속성 및 함수 매개변수의 이름을 포함하여 AQL 오브젝트의 이름을 정의하는 데 사용합니다.
-
예약어: 예약어는 AQL 구조 컨텍스트에서 고정된 의미가 있으며 재정의할 수 없는 단어입니다. 키워드는 언어 구문에서 특수한 의미가 있는 예약어입니다.
-
상수: 상수는 String, Integer, Float 또는 Boolean과 같은 데이터 유형 중 하나일 수 있는 고정 값입니다.
-
주석: 다른 사용자가 코드를 이해하고 자체 설명 컴파일 모듈을 생성할 수 있도록 주석을 사용하여 기본 설명으로 AQL 코드를 보강하십시오.
-
표현식: AQL 표현식은 단일 스칼라 값으로 평가되는 하나 이상의 스칼라 값과 함수의 조합입니다.
ID
ID는 모듈, 뷰, 테이블, 사전, 함수, 속성 및 함수 매개변수의 이름을 포함하여 AQL 오브젝트의 이름을 정의하는 데 사용합니다.
두 가지 유형의 대소문자 구분되는 AQL ID가 있습니다.
-
단순 ID
단순 식별자는 소문자(
a-z
) 또는 대문자(A-Z
) 또는 밑줄 문자((_
)로 시작해야 합니다. 이후 문자는 소문자 또는 대문자, 밑줄 문자 또는 숫자(0-9
)가 될 수 있습니다. 단순 식별자는 AQL 키워드와 달라야 합니다. -
큰따옴표로 묶인 ID
큰따옴표로 묶인 식별자는 큰따옴표 문자(
"
)로 시작하고 끝납니다. 시작과 끝 큰따옴표 문자 사이에 모든 문자를 사용할 수 있습니다. 큰따옴표로 묶은 ID에는 마침표(.
) 문자가 포함될 수 없습니다. 이름 내에 큰따옴표 문자가 있으면 백슬래시 문자(\)를 그 앞에 지정하여 이스케이프 처리해야 합니다(예:\”
).
예약어
예약어는 AQL 구조 컨텍스트에서 고정된 의미가 있으며 재정의할 수 없는 단어입니다. 키워드는 언어 구문에서 특수한 의미가 있는 예약어입니다.
다음 AQL 예약 키워드는 각각 언어 내에서 정립된 용도가 있으므로 ID로 사용할 수 없습니다.
all
allow
allow_empty
always
and
annotate
as
ascending
ascii
attribute
between
blocks
both
by
called
case
cast
ccsid
character
characters
columns
consolidate
content\_type
count
create
default
descending
detag
detect
deterministic
dictionary
dictionaries
document
element
else
empty\_fileset
entries
exact
export
external
external_name
extract
fetch
file
first
flags
folding
from
function
group
having
import
in
include
infinity
inline_match
input
into
insensitive
java
language
left
lemma_match
like
limit
mapping
matching_regex
minus
module
name
never
not
null
on
only
order
output
part_of_speech
parts_of_speech
parameter
pattern
point
points
priority
regex
regexes
retain
required
return
right
rows
select
separation
set
specific
split
table
tagger
then
token
Token
tokens
unicode
union
up
using
values
view
views
when
where
with
다음 예약어는 기본 제공 스칼라 유형의 이름입니다.
Text
Span
Integer
Float
String
Boolean
ScalarList
다음과 같은 기타 예약 이름은 ID로 사용할 수 없습니다.
Dictionary
Regex
Consolidate
Block
BlockTok
Sentence
Tokenize
RegexTok
PosTag
상수
상수는 String
, Integer
, Float
또는 Boolean
데이터 유형 중 하나일 수 있는 고정 값입니다.
상수는 select
또는 extract
절의 select 목록에서 사용하거나 기본 제공 또는 UDF 함수 및 술어에서 인수로 사용합니다. AQL에서는 다음 유형의 상수를 지원합니다.
-
문자열 상수
작은따옴표(‘)로 묶인 문자열입니다(예: ‘a string’).
-
정수 상수
따옴표로 묶지 않은 32비트 부호 있는 정수 값입니다(예: 10 또는 -1).
-
부동 소수점 상수
따옴표로 묶지 않은 단일 정밀도 32비트 부동 소수점 값입니다(예: 3.14 또는 -1.2).
-
부울 상수
따옴표로 묶지 않은 true 또는 false 값입니다.
-
널 상수
따옴표로 묶지 않은 널 값입니다.
주석
다른 사용자가 코드를 이해하고 자기 설명적 컴파일된 모듈을 생성할 수 있도록 주석을 사용하여 기본 설명으로 AQL 코드를 보강하십시오.
주석을 사용하면 AQL 개발자가 AQL 소스 코드를 쉽게 이해할 수 있도록 기본 설명을 사용하여 AQL 코드를 보강할 수 있으며, 자체 설명 컴파일된 AQL 모듈을 생성할 수 있습니다. AQL에서는 세 가지 유형의 주석이 지원됩니다.
-
단일 행 주석
단일 행 주석은 이중 하이픈(
--
)으로 시작합니다. -
다중 행 주석
다중 행 주석은 슬래시와 별표(
/*
)로 시작하고 별표와 슬래시(*
)로 끝납니다. 다중 행 주석을 중첩할 수 없습니다. 예를 들어, 다음과 같이 중첩된 다중 행 주석은 허용되지 않습니다./* A comment with a /*nested comment*/ */
-
AQL Doc 주석
AQL Doc 주석에서는 다른 사용자가 컨텍스트를 이해할 수 있는 요소가 풍부한 방법 또는 일반 언어로 모듈 또는 AQL 오브젝트를 설명하는 방법을 제공합니다. AQL 컴파일러에서 무시되는 단일 행 주석 및 다중 행 주석과 달리, AQL Doc 주석은 컴파일된 모듈(.tam 파일)의 메타데이터로 직렬화되며 외부에서 사용할 수 있습니다.
명령문 및 모듈의 AQL 문서에 있는 모든 주석의 형식은 다음과 같습니다.
-
주석은 일반 텍스트로 되어 있습니다(HTML 태그가 지원되지 않음).
-
주석은 정방향 슬래시와 두 개의 별표(
/**
)로 시작되며 별표 정방향 슬래시(*/
)로 끝납니다. 선택적으로 각 행은 별표(*
)로 시작할 수 있습니다. -
별표 앞에 임의의 수의 공백을 사용할 수 있습니다.
-
At 기호(
@
)가 접두부로 지정된 특수 태그는 각 행의 시작 부분 또는 선택적 별표 다음에 사용할 수 있습니다. -
AQL Doc 주석은 중첩할 수 없습니다. AQL Doc 시스템에는 두 가지 단위 레벨이 있습니다. 각 아티팩트를 문서화하는 형식은 명령문과 구문을 설명하는 주제에 자세히 설명되어 있습니다.
-
모듈 레벨 주석
모듈 레벨 주석은 모듈 폴더 바로 아래에 있는 module.info라는 특수 파일에 포함되어 있습니다. 주석에서는 모듈의 시맨틱과 모듈의 뷰
Document
스키마를 설명해야 합니다. -
명령문 레벨 주석
명령문 레벨 주석은 AQL 오브젝트를 작성하는 명령문 바로 앞에 있는 소스 AQL 파일에 포함되어 있습니다. 단일 행 주석 및 다중 행 주석은 명령문의 AQL Doc 주석과 명령문 자체 사이에 허용됩니다.
다음 최상위 레벨 AQL 명령문은 AQL Doc 주석을 사용하여 문서화할 수 있습니다.
- create external view 명령문
- create external table 명령문
- create external dictionary 명령문
- create 함수
- detag 명령문
- select... into 명령문 AQL Doc 주석은 모듈의 컴파일된 표시에서 직렬화됩니다.
-
표현식
AQL 표현식은 단일 스칼라 값으로 평가되는 하나 이상의 스칼라 값과 함수의 조합입니다.
표현식은 다음 네 가지 유형 중 하나일 수 있습니다.
- 상수
- 열 참조
- 스칼라 함수 호출
- 집계 함수 호출
상수
표현식은 다음 예에서와 같이 Integer
, Float
또는 String
유형의 상수일 수 있습니다.
select 'positive' as polarity
표현식은 문자열 상수 positive
입니다.
열 참조
표현식은 다음 예와 같이 열 참조일 수 있습니다.
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);
이 뷰에서는 개인의 전체 이름(예: “Samuel Davis”, “Vicky Rosenberg”)으로 해석할 수 있는 텍스트를 식별합니다. F.name
및 L.name
표현식은 각각 F
및 L
뷰의 이름 열을 반환하는 열-참조 표현식입니다. from
명령문에서는 F
및 L
뷰를 FirstName
및 LastName
뷰(올바른 이름과 성을 정의하고 이 예에서는 표시되지 않음)의 로컬 이름으로 정의합니다.
스카라 함수 호출
표현식은 하나 이상의 스칼라 함수 호출로 구성될 수 있습니다. 각 호출에는 마찬가지로 유형 상수, 열 참조 또는 스칼라 함수 호출의 표현식인 인수가 포함될 수 있습니다. 스칼라 함수 호출은 기본 제공 스칼라 함수 또는 스칼라 사용자 정의 함수 중 하나일 수 있습니다. 다음 예를 고려하십시오.
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);
이 뷰에서는 성이 같은 사람을 함께 그룹화하고 성을 소문자로 표시하여 모든 이름을 인쇄함으로써(예: 성 keaton, 이름 (Elyse, Alex, Diane)) 잠재적 가족 구성원을 식별합니다. 이름을 소문자로 표시하기 위해 GetText
함수 호출의 출력은 ToLowerCase
함수 호출의 인수로 사용됩니다. 이 예의 scalar
함수 호출 표현식은 ToLowerCase
,
(GetText(P.lastname)
, ToLowerCase(GetText(P.firstname))
및 GetText(P.lastname)
입니다.
집계 함수 호출
표현식은 집계 함수 호출일 수 있습니다. 이 표현식 유형은 유형 열 참조 또는 유형 스칼라 함수 호출의 다른 표현식을 인수로 사용할 수 있습니다. 다음 예제는 표현식 유형 열 참조가 있는 집계 함수 호출을 표시합니다.
create view CountLastNames as
select Count(Person.lastname)
from Person;
표현식은 단순히 Count(Person.lastname)
이고 문서에 있는 Person.lastname
어노테이션을 계수합니다. 이전 예에서는 표현식 유형 스칼라 함수 호출이 있는 집계 함수 호출의 예가 List(GetText(P.firstname))
스칼라 함수를 이름 목록을 생성하는 인수로 사용하는 List
집계 함수가 있는 GetText
으로
존재합니다. 집계 함수 호출 표현식은 select
명령문의 Aggregate function call expressions are only allowed as expressions in the select
목록에서 표현식으로만 사용할 수 있습니다. 집계 함수 호출 표현식은 select
명령문의 extract
목록에서 사용할 수 없거나,
스칼라 또는 집계 함수 호출의 인수로 허용되지 않습니다.
데이터 모듈
AQL의 데이터 모델은 SQL 데이터베이스(예: DB2®)에서 사용하는 표준 관계형 모델과 유사합니다. AQL의 모든 데이터는 튜플, 하나 이상 열의 데이터 레코드 또는 필드에 저장됩니다. 튜플의 콜렉션이 뷰를 형성합니다. 뷰의 모든 튜플에 동일한 스키마가 있습니다. 즉, 모든 튜플에 필드의 이름과 유형이 있습니다.
입력 문서의 컨텐츠는 문서라는 특수 뷰로 표시됩니다.
튜플의 필드는 AQL의 기본 제공 데이터 유형 중 하나에 속해야 합니다.
-
부울
값이 true 또는 false인 데이터 유형입니다.
-
부동
단일 정밀도 부동 소수점 숫자입니다.
-
정수
3비트 부호 있는 정수입니다.
-
ScalarList
동일한 스칼라 유형(Integer, Float, Text 또는 Span) 값의 콜렉션입니다. 데이터 유형 ScalarList 값은 AQL 기본 제공 집계 함수
List()
의 결과 또는 UDF 결과로 얻을 수 있습니다. -
Span
Span은 Text 오브젝트에서 시작 및 종료 오프셋으로 식별되는 Text 오브젝트의 인접 영역입니다. 입력 텍스트가 다음과 같다고 가정합니다.
Amelia Earhart is a pilot.
Span [0-6]의 텍스트는
Amelia
입니다.이 Span은 다음과 같이 시각화할 수 있습니다.
0A1m2e3l4i5a6
마찬가지로 Span [20-25]의 텍스트는
pilot
입니다.[x-x]의 Span은 문자의 끝과 다음 문자의 시작 사이의 범위를 나타냅니다. 이전 예제에서 [ 0-0]은 문자
A
앞의 빈 문자열입니다. 마찬가지로, [ 3-3]의 Span은e
및l
문자 사이의 빈 문자열입니다.Span 유형의 값은
extract
명령문, 기본 제공 스칼라 함수 또는 UDF의 결과로 얻을 수 있습니다. -
텍스트
문자 순서를 나타내는 AQL 데이터 유형입니다. Text 오브젝트에는 문자열 값이라고 하는 유니코드 문자열이 포함되어 있습니다. 문자열이 다른 Text 오브젝트의 분리된 부분 문자열을 연결하여 구성된 경우 원래 Text 오브젝트의 참조 및 관련 오프셋 맵핑 정보도 포함합니다. 모든 컴포넌트가 서로 대응하여 일치하는 경우 두 개의 Text 오브젝트는 서로 같은 것으로 간주됩니다.
-
Span 및 Text 유형의 값 비교 우선순위 지정 요인은 Span 유형과 Text 유형 값 사이의 비교에 영향을 미칩니다.
Span 및 Text 유형의 값 비교
우선순위 지정 요인은 Span 유형과 Text 유형 값 사이의 비교에 영향을 미칩니다.
Span 유형과 Text 유형의 값은 다음과 같은 방식으로 서로 비교합니다.
- 널 범위 값은 항상 다른 값보다 아래에 정렬됩니다.
- 텍스트 값은 항상 범위 값보다 위에 정렬됩니다.
- Text 유형 값은 먼저 문자열 값의 렉시칼 순서대로 정렬된 다음, 원래 Text 순서 및 오프셋 맵핑 정보(해당되는 경우) 순으로 정렬됩니다.
- Span 유형 값은 먼저 기본 텍스트 오브젝트 순으로 정렬된 다음 시작 오프셋과 종료 오프셋별로 순서대로 정렬됩니다. 시작 오프셋이 더 작은 범위가 더 아래에 정렬됩니다. 같은 오프셋에서 시작하는 두 범위 사이에서는 종료 오프셋이 더 작은 범위가 더 아래에 정렬됩니다.
실행 모델
런타임 컴포넌트에는 한 번에 하나의 문서(document-at-a-time) 실행 모델이 있습니다. 런타임 컴포넌트에서 문서의 콜렉션을 받고 각 문서에서 추출기를 실행하여 해당 문서에서 정보를 추출합니다.
추출기는 하나 이상의 AQL 모듈로 구성되어 각각 관계를 정의하는 뷰의 콜렉션을 작성합니다. 이 뷰 중 일부는 출력 뷰로 지정되어 있으며, 나머지 뷰는 비출력 뷰입니다. 비출력 뷰는 모듈로 가져오거나 모듈에서 내보낸 몇 가지 뷰를 포함할 수 있습니다. 출력 뷰와 내보낸 뷰는 직교한다는 점에 유의하십시오. 예를 들어 내보낸 뷰는 출력 뷰가 될 수 없습니다. 이 뷰 외에도 고유 Document
뷰는 이 추출기에서
어노테이션을 지정한 입력 문서를 나타냅니다.
Document
보기
AQL 모듈 레벨에서 Document
뷰는 해당 모듈에서 어노테이션을 작성하는 현재 문서를 나타내는 특수 뷰입니다. 두 개 이상의 모듈을 결합하여 추출기를 형성하면 모든 모듈의 Document 스키마에 대한 중복되지 않은 유니온이 필수 Document
뷰입니다. require document with columns
명령문을 사용하여 Document
뷰의 스키마를 지정하십시오. 이 명령문이 모듈에 없는 경우 Document
뷰의 기본 스키마는 (text Text, label Text)로 가정됩니다.
-
텍스트
현재 문서의 텍스트 컨텐츠입니다.
-
레이블
어노테이션이 작성되는 현재 문서의 레이블입니다.
Document라는 키워드는 실행 중에 자동으로 채워지는 Document
뷰의 ID로 예약됩니다. 따라서 이름이 같은 다른 뷰나 테이블을 정의할 수 없습니다. 그러나 속성 이름 및 별명의 ID로 Document라는 단어는 사용할 수 있습니다.
AQL 명령문
AQL 명령문을 사용하여 모듈, 뷰, 테이블, 사전 및 함수를 작성하고 사용할 수 있습니다.
AQL에서 지원되는 명령문은 다음과 같습니다.
-
모듈을 작성하고 모듈 사이의 상호작용을 선언하는 명령문
module 명령문
export 명령문
import 명령문
-
AQL 오브젝트 작성용 명령문: 뷰, 사전, 테이블 또는 함수
create dictionary 및 create external dictionary 명령문
create table 명령문
create view 명령문
create external view 명령문
detag 명령문
extract 명령문
select 명령문
require document with columns 명령문
set default dictionary language 명령문
create function 명령문
AQL 문의 구문 사양에는 대괄호([ ]
)가 포함되어 있습니다. 이러한 사양은 문장을 작성할 때 해당 구문이 사용되는 경우 괄호 및 괄호가 보유하는 구문이 선택 사항임을 나타냅니다. 또한 구조체나 인수의 추가 인스턴스를 지정하는 방법을 정의하는 플레이스홀더로 사용됩니다.
module
명령문
module
명령문을 사용하여 자체 포함된 필수 리소스가 있는 모듈을 작성하십시오. 이 리소스를 AQL 오브젝트로 다른 모듈에 내보내고 가져올 수 있습니다.
구문
module <module-name\>;
설명
-
<module-name\>
현재 파일이
<module-name\>
(이)라는 모듈의 일부임을 선언합니다. 모듈 이름은 단순 ID여야 합니다. 큰따옴표로 묶은 ID는 모듈 이름으로 사용할 수 없습니다.모듈의 각 AQL 파일은 단 하나의 모듈 선언이어야 하며, 이 선언은 각 파일에서 첫 번째 명령문이어야 합니다. 이 선언에서는 모듈-이름과 동일한 네임스페이스를 설정합니다. 이 모듈의 AQL 파일에 선언된 모든 뷰(및 사전, 테이블 및 함수와 같은 기타 오브젝트)는 이 단일 네임스페이스에 있습니다. 이 네임스페이스의 모든 AQL 파일에서 액세스할 수 있습니다.
모듈
<module-name\>
의 일부로 선언된 모든 파일은 이 네임스페이스를 강제 실행하기 위해<module-name\>
폴더 내에 있어야 합니다. 이 모듈 폴더에서는 AQL 파일의 순서가 지정되지 않습니다. AQL 컴파일러에서는 모듈의 모든 AQL 파일을 검사하고, 모듈에 선언된 모든 뷰, 사전, 테이블 및 함수를 컴파일하는 올바른 순서를 판별합니다.
사용법 참고
- 기본 AQL 파일이 모듈(모듈식 AQL)의 일부로 있지 않고 호환 모드에서 컴파일된 경우 이 명령문은 지원되지 않습니다.
- 뷰 사이의 순환 종속성은 허용되지 않습니다.
- AQL 모듈에서는 하위 모듈을 지원하지 않습니다.
- 최상위 레벨 모듈 폴더의 하위 폴더에 있는 AQL 파일은 무시됩니다.
예
예제 1: 샘플 모듈
다음 예에서 TheMentions 뷰는 샘플로 이름이 지정된 모듈에 속합니다.
module sample;
create dictionary GetTheDict as ('The', 'the');
create view TheMentions as
extract dictionary 'GetTheDict' on D.text as theMention
from Document D;
export
명령문
AQL의 export
명령문은 AQL 오브젝트를 가져와 다른 모듈에서 사용할 수 있도록 현재 모듈에서 AQL 오브젝트를 내보내는 데 사용합니다.
구문
export view|dictionary|table|function <object-name\>;
설명
-
view|dictionary|table|function
내보낼 오브젝트 유형을 정의합니다. 오브젝트 유형은 뷰, 사전, 테이블 또는 함수가 될 수 있습니다.
-
<object-name\>
내보낼 오브젝트 이름을 정의합니다.
<object-name\>
은(는) 단순 ID 또는 큰따옴표로 묶인 ID일 수 있습니다.
사용법 참고
-
가져온 AQL 오브젝트를 내보낼 수 없습니다. 새 뷰를 작성하여 현재 모듈의 뷰나 테이블을 다시 내보내는 효과를 낼 수 있습니다.
select * from <imported_view_name_or_table_name>;
-
예제에 표시된
export view
및output view
명령문은 서로 직교합니다. 즉, 출력 뷰는 자동으로 내보낸 뷰가 되지 않으므로,export
명령문을 사용하여 명시적으로 내보내야 합니다. 내보낸 뷰는 자동으로 출력 뷰가 되지 않으므로,output view
명령문을 사용하여 명시적으로 출력해야 합니다. 이 예의export
명령문에서는 가져온 뷰인 PersonName.FirstName 뷰를 내보내려고 합니다. 그러면 오류가 발생합니다. 즉, 개발자가 가져온 뷰를 새 뷰로 복사한 다음 해당 사본을 대신 내보내야 합니다.
예
예제 1: 뷰와 사전을 작성한 다음 다른 모듈에서 사용하도록 내보내기
이 예에서는 FirstName 및 NotFirstName 뷰를 생성합니다. FirstName 뷰에서는 FirstNamesDictionary 사전에 표시된 이름에 관한 정보를 수집합니다. 다른 뷰에서는 이름을 제외할 때 남아 있는 이름을 수집합니다. 텍스트를 더 쉽게 추출하려면 두 개의 사전이 필요합니다. 하나의 사전에는 검색하려는 이름이 모두 포함되어 있습니다. 두 번째 사전인 LastNamesDictionary에는 검색할 성이 포함되어 있습니다. 다른 모듈에서 사용할 수 있도록 FirstNamesDictionary 사전을 내보냅니다. 가져온 다음 에제 2의 person 모듈과 같은 다른 모듈에서 사용할 수 있도록 FirstName과 NotFirstName 뷰도 내보냅니다.
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;
예제 2: 사용할 뷰를 가져오지만 부적절하게 내보내어 오류 발생
이 예에서는 두 개의 뷰 가져오기를 보여줍니다. 이러한 보기는 예제 1의 모듈 personName에서 내보냅니다. 이제 모듈 사용자가 해당 보기를 가져오고 참조할 수 있습니다. 그러나 이 모듈에서는 가져온 뷰인 FirstName을 내보내려고 하므로 오류가 발생합니다.
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;
이 코드에서 오류가 발생한 이유는 한 모듈에서 가져온 뷰는 현재 모듈로 내보낼 수 없기 때문입니다. 또한 output view
명령문으로 출력 뷰를 정의하지 않으면 내보낸 뷰가 자동으로 출력 뷰가 되지 않습니다.
import
명령문
import
명령문을 사용하여 현재 모듈의 컨텍스트에 있는 다른 모듈에서 내보낸 오브젝트를 참조할 수 있습니다.
구문
import view|dictionary|table|function <object-name\>
from module <module-name\> [as <alias\>];
설명
-
view\|dictionary\|table\|function
가져올 AQL 오브젝트의 유형을 식별합니다. 오브젝트 유형은 필수입니다.
-
<object-name\>
<object-name\>
은(는) 단순 ID 또는 큰따옴표로 묶인 ID일 수 있습니다. -
<module-name\>
<module-name\>
은(는) 단순 ID여야 합니다. -
<alias\>
이 형식의 가져오기 문(일명:
alias import
)은 지정한 AQL 오브젝트를 원래 이름이 아닌<alias\>
이름으로 현재 모듈의 네임스페이스로 가져옵니다. 규정되지 않은 별명 또는 현재 모듈 이름(AQL 오브젝트를 가져온 모듈)으로 규정된 별명을 사용하여 가져온 요소를 참조할 수 있습니다.alias import
명령문을 통해 규정된 원래 이름이 아니라 별명 이름으로만 요소를 가져오므로 originalModule.elementName을 사용할 수 없습니다.
사용법 참고
-
별명 스펙이 없는 import 명령문을 통해서는 지정된 AQL 오브젝트를 현재 모듈로 가져옵니다. 이는 규정된 이름
<original\_module\_name\>.<object-name\>
아래 현재 모듈에 정의된 AQL문에 AQL 오브젝트를 액세스할 수 있도록 합니다. -
import 명령문은 현재 모듈 이외의 모듈에서 AQL 오브젝트를 가져오는 데만 사용합니다. 모듈의 AQL 파일에 선언된 오브젝트는 동일한 모듈의 다른 AQL 파일에 표시됩니다. import 명령문을 통해 현재 파일의 컨텍스트가 아니라 현재 모듈의 컨텍스트에 오브젝트를 배치합니다. 따라서 모듈 A의 1.aql에서 가져온 뷰는 추가 import 명령문이 없어도 동일한 모듈의 2.aql에 표시됩니다.
-
모든 import 명령문은 모듈 선언 바로 다음에 와야 하며, 다른 유형의 명령문 앞에 있어야 합니다. 임의의 모듈에서 명시적으로 내보낸 AQL 오브젝트만 다른 모듈에 가져올 수 있습니다. 이 요구사항을 준수하지 않으면 컴파일 오류가 발생합니다.
-
import view
명령문 때문에 동일한 모듈(현재 파일로만 한정되지 않음)에 있는 다른 import 명령문 또는create view
명령문과 이름 충돌이 발생하면 컴파일 오류가 발생합니다. 이 제한사항은 뷰 외에도 다른 오브젝트의import
에 적용됩니다. -
AQL 컴파일러는 이전 버전의 AQL에서 사용되는 이름 지정 규칙을 준수합니다.
- 모듈에는 이름이 같은 테이블 및 뷰가 포함될 수 없습니다.
- 테이블 또는 뷰와 이름이 같은 사전이 허용됩니다.
- 테이블, 뷰 또는 사전과 이름이 같은 함수가 허용됩니다.
-
모듈에 있는 하나 이상의 AQL 파일에 있는 여러 다른 import 명령문을 통해 다른 AQL 오브젝트에 동일한 이름을 지정하면 컴파일 오류가 발생합니다.
-
모듈의 AQL 파일에서
import view
명령문을 사용하지 않고 모듈의 내보낸 다른 뷰를 참조하면 컴파일 오류가 발생합니다. 사전, 테이블 또는 함수의 경우에도 마찬가지입니다. -
모듈의 두 AQL 파일이 A 및 B와 같이 서로 다른 두 별명을 사용하는 다른 모듈에서 동일한 뷰 X를 가져오면 두 별명은 동의어로 처리됩니다. 이 규칙은 테이블, 사전 및 함수에도 적용됩니다.
예
예제 1: 다른 모듈로 가져오기 위해 내보내는 뷰 작성
이 예에서는 두 개의 뷰, FirstName
및 NotFirstName
을 작성합니다. FirstName
뷰에서는 FirstNamesDictionary
사전에 표시된 이름에 관한 정보를 수집합니다. 두 번째 뷰에서는 이름을 제외하고 남아 있는 이름을 수집합니다. 텍스트를 더 쉽게 추출하려면 두 개의 사전이 필요합니다. 하나의 사전에는
검색하려는 이름이 모두 포함되어 있습니다. 두 번째 사전인 LastNamesDictionary
에는 검색할 성이 포함되어 있습니다. 예제 2와 3의 다른 모듈(예: FirstName
)로 가져와서 사용할 수 있도록 NotFirstName
및 person
뷰를 내보냅니다.
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;
예제 2: 별명 가져오기를 사용하여 FirstName 뷰 가져오기
이 예제는 예제 1에서 작성하여 내보낸 보기 중 하나를 가져옵니다. 그런 다음 결과를 볼 수 있도록 PersonFirstName
보기가 출력됩니다.
샘플 import 명령문은 별명 가져오기라고 합니다. 모듈 규정자가 없는 FirstName
뷰를 현재 모듈 person
의 네임스페이스로 가져옵니다. 가져온 뷰는 다른 양식이 아니라 별명 이름 PersonFirstName
을 통해서만 액세스할 수 있습니다. 예를 들어 뷰는 별명 이름을 통해서만 가져오므로 가져온 뷰를 personName.FirstName
으로
참조할 수 없습니다.
module person;
`import view FirstName from module personName as PersonFirstName;`
output view PersonFirstName;
예제 3: 별명 가져오기를 사용하지 않고 NotFirstname 뷰 가져오기
이 샘플 import 명령문에서는 규정된 이름 personName.NotFirstName(뷰의 규정되지 않은 이름이 아님)을 현재 모듈 person
의 네임스페이스로 가져옵니다. 항상 규정된 이름만 사용하여 가져온 뷰를 참조하십시오. 기타 참조 모드는 컴파일러 오류로 플래그가 지정됩니다.
module person;
`import view NotFirstName from module personName;`
output view personName.NotFirstName;
import module
명령문
import module
명령문을 사용하여 기존 AQL 모듈을 가져오고 재사용할 수 있습니다.
구문
import module <module-name\>;
설명
-
<module-name\>
가져올 모듈을 지정합니다.
<module-name\>
은(는) 단순 ID여야 합니다.
사용법 참고
-
import 명령문은 현재 모듈이 아니라 다른 모듈에서 AQL 오브젝트를 가져오는 데만 사용합니다.
-
모든 import 명령문은 모듈 선언 바로 다음에 와야 하며, 다른 유형의 명령문 앞에 있어야 합니다. 임의의 모듈에서 명시적으로 내보낸 AQL 오브젝트만 다른 모듈에 가져올 수 있습니다. 이 요구사항을 준수하지 않으면 컴파일 오류가 발생합니다.
-
import view
명령문 때문에 동일한 모듈(현재 파일로만 한정되지 않음)에 있는 다른 import 명령문 또는create view
명령문과 이름 충돌이 발생하면 컴파일 오류가 발생합니다. 이 제한사항은 뷰 외에도 AQL 다른 오브젝트의import
에 적용됩니다. -
모듈의 AQL 파일에서
import view
명령문을 사용하지 않고 모듈의 내보낸 다른 뷰를 참조하면 컴파일 오류가 발생합니다. 사전, 테이블 또는 함수의 경우에도 마찬가지입니다. -
모듈의 두 AQL 파일이 A 및 B와 같이 서로 다른 두 별명을 사용하는 다른 모듈에서 동일한 뷰 X를 가져오면 두 별명은 동의어로 처리됩니다. 이 규칙은 테이블, 사전 및 함수에도 적용됩니다.
예
이 예에서는 import
명령문을 통해 내보낸 뷰 personName.FirstName
및 personName.NotFirstName
의 규정된 이름을 가져옵니다. personName
모듈을 통해 내보내지 않은 뷰는 import 명령문의 일부로 가져오지 않습니다.
-
예제 1: FirstName 및 NotFirstName 뷰를 모두 가져오기
이 예에서는 personName 모듈에서 내보낸 모든 뷰를 표시합니다.
FirstName
및NotFirstName
뷰는 export 명령문의 예제 섹션에서 작성됩니다.module personOther; -- The following statement would import both views FirstName and NotFirstName. import module personName;
set default dictionary language
명령문
set default dictionary language
명령문을 사용하면 추출기 개발자가 포함 모듈의 기본 사전-일치 언어 세트를 사용자 정의할 수 있습니다.
구문
set default dictionary language as '<language codes\>';
설명
-
<language codes\>
명시적
with language as
스펙 없이 선언된 모듈의 사전과 일치하는지 확인하고 컴파일하는 데 사용할 언어를 지정합니다.<language codes\>
세트는 각 언어 코드 주위에 공백이 없는 쉼표로 구분된 목록이어야 합니다. 이 요구사항을 준수하지 않으면 컴파일 오류가 발생할 수 있습니다.이 명령문은 다음 사전에 영향을 줍니다.
create dictionary
또는create external dictionary
명령문을 사용하여 현재 모듈에 명시적으로 선언된 사전과 해당 명령문에with language as
절이 없는 사전.- 외부 파일의 사전.
extract pattern
문의 패턴 스펙에 명시적with language as
스펙 없이<'string' [match parameters]>
유형의 원자와'string'
유형의 원자가 있습니다. 이 명령문이 모듈 내부에 없는 경우 런타임 구성요소는 기본적으로 독일어, 스페인어, 영어, 프랑스어, 이탈리아어 및 지정되지 않은 언어 x의 언어 세트로 설정됩니다. 이는[de,es,en,fr,it,x_unspecified]
세트로 정의됩니다. 한 모듈 내에서 이 명령문의 인스턴스는 하나만 존재할 수 있습니다.
사용법 참고
- 추출기에서 다루는 언어의 범위를 넓히도록
set default dictionary language
명령문을 업데이트할 수 있습니다. 언어를 추가하는 이 기능을 통해 사용자 정의를 용이하게 하고 기존 추출기를 재사용할 수 있습니다.
예
예제 1: 사전 항목과 일치시키는 데 사용할 언어 지정
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;
require document with columns
명령문
require document with columns
명령문을 사용하여 컴파일 시 특수 뷰 Document
의 스키마를 정의할 수 있습니다. 이 스키마 정의에서는 Document
뷰의 각 튜플에서 찾을 필수 필드와 해당 유형 목록을 지정합니다.
구문
require document with columns <columnName\> <columnType\>
[and <columnName\> <columnType\>]*;
설명
-
<columnName\>
스키마에서 사용할 열의 이름을 지정합니다.
<columnName\>
은(는) 단순 ID 또는 큰따옴표로 묶인 ID인 속성 ID입니다. -
<columnType\>
Document
뷰의 스키마에서 사용할 열의 유형을 지정합니다.<columnType\>
은(는) 정수, 부동, 부울 또는 텍스트 데이터 유형 중 하나일 수 있습니다. -
[ and <columnName\> <columnType\> ]*
Document
뷰의 스키마에 추가 열 이름 및 유형을 지정합니다. 이들은<columnName\>
및<columnType\>
과(와) 동일한 규칙을 따릅니다.
이전 버전의 AQL에서는 단일 필드(text Text) 또는 두 필드(text text, label Text)로 구성되도록 특수 뷰 Document
의 스키마가 사전 정의되었습니다. 런타임 시 이 스키마 중에 선택합니다. require document with columns
명령문을 사용하여 컴파일 시 기본 입력 문서 스키마를 대체할 수 있습니다.
사용법 참고
- 모듈식 AQL 코드의 경우
require document with columns
명령문의 범위는 해당 명령문이 정의된 모듈입니다. require document with columns
명령문은 AQL 파일당 하나만 허용됩니다. 단일 모듈 또는 일반 모듈에는require document with columns
명령문이 있는 AQL 파일이 0개, 한 개 또는 여러 개 있을 수 있습니다. 모듈에 있는 모든 AQL 파일에서 전체 모듈 레벨의require document with columns
명령문을 병합하여 모듈 전체require document with columns
를 형성합니다. 이 명령문을 통해 해당 모듈의Document
뷰 스키마를 정의합니다. 모듈 또는 일반 모듈의 AQL 파일에 require 명령문이 없으면 모듈에Document
뷰의 기본 스키마가 있습니다. 이 스키마는 두 개의 열(text Text, label Text)로 구성됩니다. 모듈에 있는 하나 이상의 AQL 파일에 하나의Document
명령문이 있으면 특수 뷰require document with columns
의 기본 열이 설정되지 않습니다.- 추출기를 형성하도록 여러 모듈을 결합할 때 각 모듈의 Document 스키마에 대한 중복되지 않은 유니온을 통해 전체 추출기의
Document
뷰 스키마를 정의합니다. 여러require document with columns
명령문에 있는 열에서 모듈 간 유형 요구사항이 충돌하면 예외가 발생합니다. 예를 들어 함께 로드되는 다른 모듈에 Z 유형의 열 X가 필요하면 모듈에 Y 유형의 열 X가 필요합니다. - 제공된 입력 문서 튜플에 모든 필수 열이 포함되지 않은 경우 추출기를 실행하면 예외가 발생합니다. 열이 해당 필수 유형과 일치하지 않는 경우에도 예외가 발생합니다.
- 모듈에
require document with columns
명령문이 있으면 참조된 특수 뷰Document
의 모든 열이require document with columns
명령문 중 하나 이상에 선언되어 있어야 합니다. 명령문은 동일한 모듈의 여러 다른 AQL 파일에 있습니다. 그러나 모듈 전체require document with columns
명령문을 형성하기 위해 이러한 모든require document with columns
명령문은 모듈의 레벨에서 병합됩니다.
예
예제 1: 열 유형이 비슷한 문서 명령문 필요
다음 예에서는 유형이 같은 네 개의 필드를 포함하는 문서 스키마를 정의합니다. 이 SQL 샘플에서는 문서 스키마에 정의된 대로 데이터 콜렉션의 각 문서 튜플에 네 개의 열이 포함되어야 합니다.
스키마를 준수하는 문서를 작성하는 방법에 관한 세부사항은 JSON 문서 형식을 참조하십시오.
module person;
-- Require document statement with similar field types
require document with columns
inputDocumentText Text
and inputDocumentLabel Text
and documentAuthor Text
and documentCreationDate Text;
예제 2: 열 유형이 다양한 문서 명령문 필요
다음 샘플에서는 필드 유형이 다양한 열을 포함하는 문서 스키마를 정의합니다.
module sample;
-- Require document statement with varying field types
require document with columns
bookText Text
and purchaseCount Integer
and bookPrice Float
and isBookPopular Boolean;
예제 3: 문서 스키마 병합
이 예에서는 first.aql, last.aql 및 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;
병합된 스키마는 (firstName Text, lastName Text, socialSecurityNo Integer)입니다.
create view
명령문
AQL 추출기의 최상위 레벨 컴포넌트는 뷰입니다. 뷰는 튜플 세트를 정의하지만 반드시 계산하지는 않는 논리적 명령문입니다.
구문
create view
명령문에서는 세 개의 양식 중 하나를 사용할 수 있습니다. 가장 간단한 양식에서는 단일 select
또는 extract
명령문의 튜플로 구성된 논리 뷰를 정의합니다. 두 번째는 여러 select
또는 extract
명령문의 다중 집합 유니온(multiset union)에서 발생하는 튜플로
구성된 뷰를 정의하는 다중 조인(multijoin) 양식입니다. 세 번째 양식에서는 두 개의 select
또는 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\>);
설명
-
<viewname\>
<viewname\>
은(는) 단순 ID 또는 큰따옴표로 묶인 ID일 수 있습니다. 마침표 문자는 포함할 수 없습니다. -
<select or extract statement\>
select
또는extract
명령문을 통해서는 포함하는 뷰의 튜플을 계산하는 데 사용하는 출력을 작성합니다.
사용법 참고
- 뷰 이름은 대소문자를 구분합니다. 예를 들어, Person, PERSON 및 person은 서로 다른 뷰 이름입니다.
- 동일한 AQL 모듈 내의 두 뷰는 중복될 수 있으므로 이름을 공유할 수 없습니다. 그러나 서로 다른 두 모듈에 이름이 같은 두 개의 뷰가 있을 수 있습니다. 해당 뷰의 완전한 이름이 고유하기 때문입니다.
- 기본적으로
create view
명령문을 통해 정의된 뷰는 출력 뷰로 지정될 때까지 비출력 뷰입니다. select
및extract
양식의union all
또는minus
명령문에는 호환 가능 출력 스키마가 있어야 합니다. 두 개의 스키마에 동일한 수의 열이 있으며, 열 이름이 동일한 순서로 지정되어 있고, 호환 가능 데이터 유형이 있으면union
또는minus
연산에 호환 가능한 것으로 간주됩니다.- 데이터 유형이 같은 필드는
union
또는minus
호환 가능입니다. - Span 및 Text 데이터 유형은
union
또는minus
호환 가능입니다. Span과 Text 유형 간 유니온의 경우 출력 유형은 Span입니다. 그러나 Text 유형의 오브젝트는 Span 유형으로 자동 변환되지 않습니다. 자동 변환은 함수 호출에 필요한 경우에만 수행됩니다. - 두 개의
ScalarLists
는 기본 스칼라 유형에 관계 없이union
또는minus
호환 가능입니다.
- 데이터 유형이 같은 필드는
예
예제 1: select 또는 extract 명령문으로 뷰 작성
아래 예제에서 Phone
뷰에서는 extract
명령문을 사용하여 튜플을 준비합니다. PhoneNumber
뷰에서는 select
명령문을 사용하여 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;
예제 2: Union All 명령문을 사용하여 뷰 작성
AllPhoneNums
뷰에서는 Phone
및 Extension
뷰의 튜플에서 연합된 세트를 준비합니다. 연합되는 두 개의 뷰에 동일한 스키마가 있습니다.
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);
예제 3: Minus 명령문으로 뷰 작성
다음 예에서는 minus
를 사용하여 튜플 세트에서 원하지 않는 튜플을 필터링해서 제외하는 방법을 보여줍니다.
create view Organization as
(select * from OrganizationCandidates)
minus
(select * from InvalidOrganizations);
예제 4: minus의 스키마 호환성
서로 다른 대상 텍스트에 걸치 범위는 동일한 유형이 아니라는 점에 유의하십시오. String 리터럴을 사용하여 이 차이점을 설명하는 다음 AQL 예제를 확인하십시오.
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);
빈 튜플 목록의 예상 출력이 아니라 필드 유형이 '문자열'인 레코드 세트가 출력됩니다.
OneString
및 TheSameString
뷰의 컨텐츠가 동일하게 보여도 실제 텍스트 값의 기본 AQL 오브젝트는 서로 다릅니다. OneString.match
의 유형은 'Span over OneString.match'입니다. TheSameString.match
의 유형은 'Span over TheSameString.match'입니다.
필드 유형이 서로 다르므로 비교용으로 호환되지 않습니다.
원하는 빈 튜플 목록 출력을 얻으려면 동일한 유형의 값을 비교해야 합니다. 다음 예에서는 GetString()
함수를 통해 span 오브젝트를 string 오브젝트로 변환하여 minus
연산에 호환 가능 유형을 전달합니다.
create view Subtraction as
(select GetString(R.match) from OneString R)
minus
(select GetString(R.match) from TheSameString R);
AQL Doc로 create view
명령문 문서화
create view
명령문의 AQL Doc 주석에는 다음 정보가 포함되어 있습니다.
- 뷰에 관한 일반 설명.
- 뷰에 있는 모든 열 이름의 @field.
예제
/**
* 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;
output view
명령문
output view
명령문에서는 출력 뷰가 될 뷰를 정의합니다. 런타임 컴포넌트에서는 출력 뷰로 표시된 뷰의 튜플만 출력합니다. AQL 컴파일러에서는 출력 또는 내보내기로 표시되거나 출력 또는 내보내기로 표시된 뷰에서 접근할 수 있는 뷰만 컴파일합니다.
구문
output view <view-name\> [as '<alias\>'];
설명
-
<view-name\>
현재 모듈의 네임스페이스에 알려진 대로 출력할 뷰의 이름입니다.
<view-name\>
은(는) 단순 ID 또는 큰따옴표로 묶인 ID입니다. 기본 제공 뷰Document
는 출력일 수 없습니다. -
[as '<alias\>']*
출력 보기의
<alias\>
이름을 정의합니다. 선택적 별명을 지정하지 않으면 다음 이름으로 뷰가 출력됩니다.- 모듈형 AQL에서 보기는
<module-name\>.<view-name\>
이름으로 출력됩니다. 여기서<module-name\>
은(는) 보기가 정의된 모듈의 이름입니다(보기가 출력되는 모듈과 다를 수 있음). - AQL 1.4 이전의 경우, 보기는 이름 아래에 출력됩니다.
<view-name\>
output ... as <alias\>
문은 다른 도메인에 대해 추출기를 사용자 정의할 때 유용합니다. 출력 보기를 정의할 때<alias\>
이름을 사용하면 출력 이름이 사용자 정의의 다른 구현에서 동일하게 됩니다.
<alias\>
이름은 다른select
또는export
문에서 사용할 수 없습니다.<alias\>
을(를) 작은따옴표로 묶어야 하며<alias\>
이름에 마침표가 포함될 수 있습니다. - 모듈형 AQL에서 보기는
사용법 참고
- AQL 추출기를 실행하면 출력 뷰로 정의된 각 뷰의 결과 튜플을 계산합니다. 출력 뷰의 결과 튜플을 계산하는 데 필요한 경우에만 비출력 뷰의 튜플도 계산됩니다.
- 모듈식 AQL에서
output view
명령문은 모듈 이름으로 규정된 완전한 뷰 이름으로 뷰의 튜플을 출력합니다.output view Person;
명령문을 통해personModule.Person
뷰가 출력되는 다음 예를 살펴보십시오.
module personModule;
create view Person as
extract dictionary 'FamousPeopleDict' on D.text as match
from Document D;
output view Person;
이 동작은 뷰가 정의된 모듈의 출력인지 가져온 모듈의 출력인지에 관계없이 별명 가져오기를 사용하여 가져온 경우에도 별명이 없는 모든 뷰 출력에 적용됩니다. 예를 들어, MyPerson
출력 뷰에서 이 예제를 수행하면 로컬 별명인 personModule.Person
이 아니라 원래 규정된 이름인 MyPerson
으로 뷰가 출력됩니다.
module employeeModule;
import view Person from module personModule as MyPerson;
output view MyPerson;
- 별명 출력 명령문은 애플리케이션 도메인 또는 입력 문서의 언어에 따라 동일한 유형의 엔티티에 여러 다른 구현이 있을 수 있는 추출기 라이브러리를 빌드할 때 유용합니다. 출력 뷰를 정의할 때 별명을 사용하면 출력 뷰 간에 일관된 명명법을 보장할 수 있다는 주된 이점이 있습니다. 각각 의미적으로 유사한 뷰를 출력하는 여러 모듈을 처리할 때 사용자의 프로그램 논리에 일관된 명명법이 필요합니다. 모듈식 AQL에서
output view
명령문에 별명 이름을 사용하면 뷰의 튜플이 지정된 별명 이름으로 출력됩니다. 예를 들어 다음 코드에서는 PersonAlias라는 별명 이름으로 결과를 출력하고 별명 이름은 모듈 접두부로 규정되지 않습니다.
module personModule;
create view Person as
extract dictionary 'FamousPeopleDict' on D.text as match
from Document D;
output view Person as 'PersonAlias';
예
다음 예에는 두 개의 모듈, personModuleFrench 및 personModuleEnglish가 포함되어 있습니다. 각 모듈에서는 PersonNameFrench 및 PersonNameEnglish라는 뷰를 출력합니다. 각각 사용자 이름에 맞게 추출기의 시맨틱 변형인 뷰를 출력하는 유사한 모듈이 있다고 가정하십시오. 이러한 모듈은 지정된 입력 언어에 맞게 사용자 정의된 이 뷰의 변동 내용을 사용하여 여러 다른 언어에 맞게 사용자 정의됩니다. 최종적으로 사용자는 처리된 모듈과 관계없이 탐색된 출력 뷰의 이름이 PersonName인 모듈을 프로그램에 사용할 수도 있습니다. 언어, 도메인 또는 다른 용도로 사용자 정의된 각 모듈에서 다양한 결과를 생성해야 하므로 이는 정상입니다. 이러한 모듈의 이용자는 기본 시맨틱이 비슷할 때 다양한 출력 뷰 이름에 맞게 프로그램의 알고리즘을 변경하지 않아도 됩니다.
이 예에서는 PersonName 별명을 사용하므로 이용자가 탐색한 뷰 이름을 변경하지 않아도 됩니다. 그러나 결과는 처리되는 모듈에 따라 달라질 수 있습니다. 예를 들어, 이 예에서 결과적으로 일치하는 항목은 프랑스어 기반(예제 1) 및 영어 기반(예제 2)입니다.
예제 1: 결과적으로 일치하는 항목은 프랑스어 기반임
다음 예제에서는 PersonNameFrench
뷰를 정의하고 구현 중립형 별명 이름인 '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';
예제 2: 결과적으로 일치하는 항목이 영어 기반임
다음 예제에서는 PersonNameEnglish
뷰를 정의하고 구현 중립형 별명 이름인 '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';
예제 모듈의 이용자는 별명 이름 'PersonName'
을 통해 출력 튜플에 액세스할 수 있습니다. 이용자는 결과가 페치되는 실제 모듈을 몰라도 됩니다.
extract
명령문
extract
명령문은 텍스트에서 직접 기본 기능을 추출하는 데 사용합니다.
구문
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>];
설명
-
<select list\>
쉼표로 구분된 출력 표현식 목록입니다. 이러한 출력 표현식의 결과는 추출 스펙의 평가를 통해 생성된 튜플과 함께
extract
명령문의 출력으로 리턴됩니다.<select list\>
의 형식은select
문의<select list\>
과(와) 동일합니다. -
<extraction specification\>
<from list\>
에 정의된 보기의 모든 튜플에 추출 스펙을 적용합니다.extract
명령문에 지정된 해당 별명에 따라 튜플의 열 이름을 바꿉니다. 다음 추출 스펙 중 하나를 사용할 수 있습니다.- 정규식
- 사전
- 분할
- 블록
- 품사
- 순서 패턴
-
<from list\>
기능을 선택할 튜플의 소스인 쉼표로 구분된 목록입니다.
<from list\>
형식은select
문의<from list\>
형식과 유사합니다. 그러나extract
문에 패턴 스펙이 없는 경우<from list\>
에는 단일 항목이 포함될 수 있습니다. -
[having <having clause\>]
추출된 각 출력 튜플에 적용되는 필터링 조건자(
<having clause\>
에서)를 지정합니다.<having clause\>
에 지정된 필드 이름은<select list\>
에 지정된 모든 별칭을 참조합니다. 이 절은 선택사항입니다. -
[consolidate on <column\>[using '<policy\>' ]]
통합
<policy\>
에 정의된 오버랩 범위를 처리하는 방법을 정의합니다. 이 스펙에서<column\>
은(는)extract
문의 일부인 출력 필드의 이름이어야 합니다. 이 절은 선택사항입니다. -
[limit<maximum number of output tuples for each document\>]
각 문서의 출력 튜플 수를 지정된 최대값으로 제한합니다. 이 절은 선택사항입니다.
사용법 참고
extract
명령문의 시맨틱은 다음과 같습니다.
- 입력 관계의 각 튜플을 통해 추출 스펙을 평가합니다. 추출이 생성하는 각 결과에 대해 추출된 값을 포함하는 출력 튜플과
<select list\>
에 지정된 원래 튜플의 모든 열이 생성됩니다. <select list\>
및<extraction specification\>
의 일부로 지정된 별명에 따라 출력 튜플의 열 이름을 바꾸십시오.- 선택적
having
절의 술어를 결과 출력 튜플에 적용합니다. - 선택적
consolidation
절에 따라 술어를 전달하는 튜플을 통합하고 결과 튜플을 출력에 추가합니다. - 선택적
limit
절이 있으면 각 문서에 지정된 튜플 수로 출력을 제한합니다.
from
명령문에서 extract pattern
절의 시맨틱은 패턴 스펙이 없는 다른 양식의 extract
명령문과 다릅니다. <from list\>
에 있는 하나 이상의 뷰에 특정 문서에 대한 튜플이 포함되어 있지 않은 경우에는 extract
문의 출력이 비어 있습니다. 입력 뷰에 있는 모든 튜플 조합의
세트가 비어 있으므로 이 출력이 비어 있습니다.
extract pattern
명령문과 같은 특수 경우에서 from
절은 패널 스펙에 관련된 관계 이름을 선언하는 플레이스홀더입니다. 명령문의 시맨틱은 패턴 스펙을 통해서만 구동됩니다. 특히 일부 입력 뷰가 빈 경우에도 명령문의 출력은 비어 있지 않을 수 있습니다.
예
예제 1: 사전 정의된 뷰의 전화번호 추출
이 샘플 extract 명령문에서는 사전 정의된 뷰 Document
로 표시된 입력 텍스트 전체에서 미국 전화번호의 정규식을 평가합니다. 그런 다음 출력은 문서당 식별된 처음 세 개의 전화번호로 제한됩니다. having 절의 필드 이름은 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;
예제 2: 대문자로 표시된 단어의 블록 추출
이 예에서는 extract
명령문을 통해 2 - 3개의 대문자로 표시된 단어 블록을 식별합니다. AQL에서 블록은 토큰의 연속 범위를 나타내며, 이 경우 2 - 3개의 토큰에 해당합니다. 이 예제에서는 튜플의 출력 세트에서 더 큰 블록에 포함된 블록을 제외하는 통합 정책도 사용합니다.
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';
추출 블록 스펙을 통해 consolidate
절을 capswords
필드에 적용합니다. 차이점은 consolidation
절에서 참조하는 대상 필드가 extract
명령문의 출력 필드라는 것입니다. select
명령문의 대상 필드는 입력 필드입니다. 이 동작은 having
절의 동작과 비슷합니다.
예제 3: 뷰 이름으로 중첩된 extract
또는 select
명령문
extract
명령문의 입력 뷰는 예제 2에서와 같이 뷰 이름이거나 이 예에서와 같이 중첩된 extract
또는 select
명령문일 수 있습니다.
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;
예제 4: select 목록을 사용하여 명령문 추출
이 예에서는 패턴과 일치하는 항목을 추출하는 동시에 입력 뷰에서 여러 속성을 선택합니다.
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;
- 정규식 정규식 추출 스펙을 사용하여 입력 텍스트 전체에서 정규식에 포함된 일치하는 패턴을 식별합니다.
- 사전 사전 추출 스펙을 사용하여 문자열 사전에 포함된 문자열을 입력 텍스트에서 추출합니다.
- 분할 분할 추출 스펙을 사용하여 큰 범위를 여러 개의 작은 범위로 분할합니다.
- 블록 입력 텍스트에서 인접하는 범위의 블록을 식별하려면 블록 추출 스펙을 사용합니다.
- 품사 품사 추출 스펙을 사용하여 전체 입력 텍스트에서 서로 다른 품사의 위치를 식별합니다.
- 순서 패턴 패턴 추출 스펙을 사용하여 전체 입력 문서와 입력 문서에서 추출한 다른 범위에서 패턴 일치를 수행합니다.
정규식
정규식 추출 스펙을 사용하여 입력 텍스트 전체에서 정규식에 포함된 일치하는 패턴을 식별합니다.
구문
regex[es] /<regex1>/
[and /<regex2>/ and ... and /<regex n>/]
[with flags '<flags string>']
on <token spec>] <name>.<column>
<grouping spec>
설명
-
regex[es] /<regex1\>/
추출에 사용할 정규식을 지정합니다. 기본적으로 AQL에서는 정규식으로 Perl 구문을 사용합니다. 즉, 정규식 리터럴은 두 개의 슬래시(//) 문자로 묶입니다. 정규식 이스케이프 순서는 다른 이스케이프 문자보다 우선합니다. AQL에서는 SQL 문자열 구문의 정규식을 허용하므로, 미국 전화번호의 정규식은 다음 예제 중 하나로 표현할 수 있습니다.
/\d{3}-\d{5}/
'\\d{3}-\\d{5}'
-
[and /<regex2\>/ and ... and /<regex n\>/ ]
추출에 사용할 추가 정규식을 나열합니다.
-
[with flags '<flags string\>']
정규식 일치를 제어하기 위한 플래그 조합을 지정합니다. 이 매개변수는 선택사항입니다. 이 플래그는 Java™ 구현에 정의된 플래그의 서브세트에 해당합니다. 플래그 문자열이 제공되지 않으면 AQL에서 기본적으로
DOTALL
플래그만 사용합니다.여러 플래그를 지정하려면
|
문자로 구분하십시오. 예를 들어 다중 행 일치, 대소문자를 구분하지 않는 일치 및 유니코드 대소문자 폴딩을 지정하려면 플래그 문자열'MULTILINE|CASE_INSENSITIVE|UNICODE'
를 사용하십시오. -
[<token spec\>]
토큰 경계에서만 정규식 일치 여부를 확인할지 표시합니다.
... [[between <number> and] <number> token[s] in] ...
토큰 제한조건은 스펙의 선택적 부분입니다. 토큰 제한조건을 생략하면 AQL에서 입력 텍스트의 각 문자 위치에서 가장 긴 겹치지 않는 일치를 리턴합니다. 토큰 제한조건이 있으면
extract
명령문에서 길이가 지정된 범위의 토큰에 있는 모든 토큰 경계에서 가장 긴 일치를 리턴합니다. 리턴된 각 일치는 토큰의 시작 부분에서 시작하고 토큰의 끝에서 종료해야 합니다. 겹치는 일치가 여러 개 있으면extract
명령문이 이를 모두 리턴합니다.토큰 경계의 위치는 런타임 컴포넌트에서 문서를 토큰화하는 데 사용하는 토크나이저에 따라 다릅니다. 엔진에서 표준 토크나이저를 사용하면 토큰이 단어 문자 또는 단일 구두점 문자로 정의됩니다.
예를 들어 다음과 같은 문자열을 고려하십시오.
"The fish are pretty," said the boy.
토큰 경계는 다음 위치에서 식별됩니다.
["][The] [fish] [are] [pretty][,]["] [said] [the] [boy][.]
-
<name\>.<column\>
정규식이 적용되는 뷰 이름과 열 이름.
-
<grouping spec\>
정규식에서 그룹 캡처를 처리하는 방법을 결정합니다. 캡처링 그룹은 원래 표현식에서 괄호로 식별되는 정규식 일치 영역입니다. 예를 들어
(fish)(cakes)
표현식에는 다음 세 가지 캡처링 그룹이 있습니다.- 그룹 0은 일치하는 전체
fishcakes
입니다. - 그룹 1은
fish
입니다. - 그룹 2는
cakes
입니다. 구문의 리턴 절에 그룹 ID를 지정하면 각 그룹 ID가 구문의 추출 정규식 절의 일부로 지정된 각 정규식의 올바른 그룹에 해당해야 합니다.
다음은 그룹화 스펙의 형식입니다.This is the format of the grouping specification:
return group <number> as <name> [and group <number> as <name>]*
그룹 0(전체 일치)만 반환하려면 예 1과 같이 더 짧은 대체 형식을 사용할 수 있습니다. 이 형식은
return group 0 as <name>
과(와) 동일합니다.<name>
은(는) 단순 ID 또는 큰따옴표로 묶인 ID일 수 있습니다. - 그룹 0은 일치하는 전체
사용법 참고
-
일반적으로 AQL에서는 [Class Pattern: java.util.regex에 설명된 대로 Java 5 정규식 구현과 동일한 기능을 지원합니다. 런타임 컴포넌트에는 기본 제공 Java 구현을 비롯하여 여러 정규식 엔진 구현이 포함되어 있습니다. 컴파일 중에 최적화에서 각 정규식을 검사하고 표현식을 실행할 수 있는 가장 빠른 엔진을 선택합니다.
-
대체 실행 엔진에서 특정 코너 케이스의 시맨틱은 약간 다를 수 있습니다. 특히 AQL에서는 대체 엔진을 평가하는 순서를 보장하지 않습니다.
예를 들어, extract 명령문을 통해 'fisherman' 텍스트를 대상으로
/fish|fisherman/
정규식을 일치시킨다고 가정하십시오. 이 명령문은 내부적으로 사용되는 정규식 엔진에 따라 'fish' 또는 'fisherman'과 일치할 수 있습니다.
AQL 플래그 문자열 | Java 플래그 | 설명 |
---|---|---|
CANON_EQ | CANON_EQ | 표준 등치: 동일한 문자의 다른 유니코드 인코딩을 등치하는 것으로 간주합니다. |
CASE_INSENSITIVE | CASE_INSENSITIVE | 대소문자를 구분하지 않는 일치를 수행하십시오. 기본적으로 대소문자를 구분하지 않는 일치에서는 US-ASCII 문자 세트의 문자만 일치한다고 가정합니다. 유니코드 인식 대소문자를 구분하지 않는 일치는 이 플래그와 UNIXCODE 플래그를 지정하여 사용으로 설정할 수 있습니다. |
유니코드 | UNICODE_CASE | 대소문자를 구분하지 않는 일치를 지정하면 유니코드 대소문자 폴딩을 사용하여 유니코드 표준과 일치하는 방식으로 대소문자를 구분하지 않는 비교에서 두 개의 문자가 서로 일치하는지 판별합니다. 기본적으로 대소문자를 구분하지 않는 일치에서는 US-ASCII 문자 세트의 문자만 일치한다고 가정합니다. 참고: CASE_INSENSITIVE 플래그 없이 사용하면 이 플래그의 동작은 정의되지 않습니다. |
DOTALL | DOTALL | 점 문자 . 가 줄바꾸기를 포함한 모든 문자와 일치하게 합니다. |
LITERAL | LITERAL | 표현식을 리터럴 문자의 순서로 취급하고 일반 정규식 이스케이프 순서를 무시합니다. |
MULTILINE | MULTILINE | ^ 및 $ 문자가 전체 입력 텍스트의 시작과 끝이 아니라 행의 시작 및 끝과 일치하게 합니다. |
UNIX_LINES | UNIX_LINES | UNIX™ 줄 바꾸기 문자 만 행 바꾸기로 취급하고, 캐리지 리턴 문자 \r 은 무시합니다. |
- 더 빠르게 추출기를 실행하고 더 쉽게 유지보수하려면 다음 가이드라인을 따르십시오.
- 길고 복잡한 정규식을 피하고 AQL 명령문과 결합된 더 간단하고 작은 정규식을 사용하십시오.
- 정규식에서 lookahead와 lookbehind의 불필요한 사용을 피하십시오. 일반적으로 extract 명령문의 having 절에 술어를 추가하여 동일한 효과를 얻을 수 있습니다.
- 가능한 경우 정규식 추출 스펙에서 토큰 제한조건을 사용하십시오.
예
예제 1: 표준 유니코드 등치를 사용하여 일치 판별
이 예에서는 이름이 아닌 대문자로 표시된 단어를 찾는 방법을 보여줍니다. 일치를 찾는 데 표준 유니코드 문자 등치를 사용합니다. ‘CANON_EQ’
플래그의 사용법과 토큰에서 정규식이 수행된다는 점에 유의하십시오.
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));
예제 2: 캡처링 그룹 사용법Usage of capturing groups
다음 예에서는 extract regex
명령문에서 캡처링 그룹의 사용법을 보여줍니다. 이 코드에서는 캡처링 그룹을 사용하여 미국 전화번호 필드를 추출합니다.
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;
예제 3: 입력 텍스트에 여러 정규식 적용
extract regex
구문을 사용하여 동일한 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;
예제 4: 그룹화 스펙의 오용
이 코드 샘플의 정규식에는 group -1
또는 group 3000
이 포함되어 있지 않습니다. 따라서 컴파일 오류가 발생합니다.
create view ErrorExample as
extract regex /(\d+)/
on D.text
return group -1 as wrongGroup and
group 3000 as nonExistentGroup
from Document D;
사전
사전 추출 스펙을 사용하여 문자열 사전에 포함된 문자열을 입력 텍스트에서 추출합니다.
구문
dictionar[y|ies]
'<dictionary>'
[and '<dictionary>' and ... and '<dictionary>']
[with flags '<flags string>']
설명
-
'<dictionary\>'
create dictionary
명령문,create external dictionary
명령문 또는 파일 시스템의 사전 파일을 사용하여 작성된 사전을 참조합니다. -
[and '<dictionary\>' and ... and '<dictionary\>']
추출에 사용할 추가 사전을 참조합니다.
-
[with flags'<flags string\>']
사전 일치를 제어합니다. 현재 두 가지 옵션이 지원됩니다.
-
정확
대소문자를 구분하는 정확한 일치를 제공합니다.
-
대소문자 무시
대소문자를 구분하지 않는 일치를 제공합니다.
-
플래그가 지정되지 않은 경우 사전이 작성될 때 지정된 플래그를 기준으로 사전이 일치하는지 확인합니다. 작성 중에 플래그를 지정하지 않으면 IgnoreCase
플래그를 사용하여 일치하는지 확인합니다.
사용법 참고
-
사전은 항상 토큰 경계에서 평가됩니다. 특히 항목의 첫 번째 토큰이 텍스트 영역의 첫 번째 토큰과 일치하고 항목의 두 번째 토큰이 텍스트 영역의 두 번째 토큰과 일치하는 식인 경우 사전 항목이 텍스트 영역과 일치합니다. 연속된 두 토큰 사이의 문자는 무시됩니다.
예를 들어, 영어와 같은 언어에 적합한 간단한 공백 기반 토큰화 모델을 사용하고 있다고 가정합니다. 또한 입력 텍스트가 “Let’s go fishing!”이라고 가정합니다. 사전이
go fish
라는 용어로 구성되면Let's go fishing!
텍스트에 일치가 없습니다. 그러나 사전이go fishing
(go와 fishing 사이에 두 개의 공백이 있다는 점에 유의) 항목으로 구성되어 있으면Let's go fishing!
텍스트에 일치하는 항목이 하나 있습니다. 공백은go
와fishing
이 두 개의 개별 토큰임을 지정합니다. 입력 텍스트의 두 토큰go
와fishing
사이에 하나 이상의 공백이 있으면 일치가 있습니다.입력 텍스트와 일치하는 사전 항목별로
extract dictionary
명령문을 통해 출력 튜플을 생성합니다.
예
예제 1: 사전 파일에서 용어 추출
일반적인 이름과 성으로 구성된 사전 파일과 대소문자를 구분하는 일치를 사용하여 개인 이름을 찾습니다.
create view Name as
extract
dictionaries
'first.dict'
and 'last.dict'
with flags 'Exact'
on D.text
as name
from Document D;
다음은 last.dict
의 샘플 컨텐츠입니다.
#Dictionary for surnames
Anthony
Aparicio
Cate
Lehmann
Radcliff
다음은 first.dict
의 샘플 컨텐츠입니다.
#Dictionary for given names
Aaron
Candra
Freeman
Mathew
Matthew
Zoraida
참고:
-
extract dictionary
명령문에서 직접 참조되는 사전 파일 시스템은 언어 세트를 사용하여 명시적으로 구성할 수 없으므로, 런타임 시 사전을 컴파일하고 적용합니다. 대신 모듈에 이 명령문이 포함되어 있으면set default dictionary language
명령문을 사용하여 언어 세트를 지정합니다.따라서
extract dictionary
명령문에서 사전 파일을 직접 참조하는 것은 권장되지 않으며,나중에 중단될 수 있습니다.create dictionary from file
명령문을 사용하여 명시적으로 사전 오브젝트를 정의한 다음 정확한 명령문에서 해당 사전을 사용하는 것이 좋은 방법입니다. -
컴파일러와 런타임 컴포넌트가 AQL에서 참조되는 사전 파일을 구성된 검색 경로에서 찾으려고 합니다.
예제 2: 인라인 사전에서 용어 추출
인라인 사전 및 대소문자를 구분하지 않는 기본 일치를 사용하여 연결을 찾으십시오.
create dictionary ConjunctionDict as
(
'and', 'or', 'but', 'yet'
);
create view Conjunction as
extract
dictionary 'ConjunctionDict'
on D.text
as name
from Document D;
분할
분할 추출 스펙을 사용하여 큰 범위를 여러 개의 작은 범위로 분할합니다.
구문
split using <name>.<split point column>
[retain [right|left|both] split point[s]]
on <name>.<column to split>
as <output name>
설명
분할 추출 스펙에서는 다음 두 인수를 사용합니다.
- 텍스트의 긴 대상 범위를 포함하는 열.
- 분할 지점을 포함하는 열.
분할 알고리즘은 입력 뷰에서 두 개의 패스를 통해 작동합니다. 첫 번째 패스에서는 대상 열별로 모든 입력 튜플을 그룹화합니다. 두 번째 패스에서는 각 그룹의 튜플을 검토하여 분할 열의 각 값으로 대상 열을 분할합니다.
-
<name\>.<split point column\>
추출에 사용할 분할 지점을 지정합니다.
-
[retain [right|left|both] split point[s]]
각 결과의 왼쪽 및 오른쪽 끝점을 처리하는 방법을 지정합니다. 이 인수는 선택적입니다.
retain left split point
가 지정된 경우 분할 지점이 있으면 각 출력 범위의 왼쪽에 분할 지점이 포함됩니다.retain right split point
가 지정된 경우 시스템에서 각 출력 범위의 오른쪽에 분할 지점이 포함되게 합니다.- 분할 추출에서는 분할 지점으로 널 값도 허용합니다. 추출을 통해 이러한 각 값에 대해 전체 입력 범위를 포함하는 튜플을 리턴합니다.
-
<name\>.<column to split\>
추출의 대상 열을 지정합니다.
-
<output name\>
추출의 출력 이름을 정의합니다.
예
예제 1: 분할 지점 및 retain
절
분할 지점이 fish are swimming in the fish pond라는 문구에 있는 fish라는 단어의 모든 인스턴스이면 다양한 버전의 retain
절이 다음과 같은 영향을 미칩니다.
-
retain절이 생략됨
" are swimming in the " 및 " pond"
-
retain right split point
" are swimming in the fish" 및 " pond"
-
retain left split point
"fish are swimming in the " 및 "fish pond"
-
retain both split points
"fish are swimming in the fish" 및 "fish pond"
예제 2: 분할 추출
이 예제에서는 문서를 문장으로 분할합니다. 먼저 정규식을 사용하여 문장 경계를 식별한 다음 분할 추출 스펙을 사용하여 문장 경계에서 문서 텍스트를 분할합니다.
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;
블록
입력 텍스트에서 인접하는 범위의 블록을 식별하려면 블록 추출 스펙을 사용합니다.
구문
blocks
with count [between <min\> and] <max\>
and separation [between 0 and] <max\> (tokens| characters)
on <name\>.<column containing spans\>
as <output name\>
설명
-
with count [between<min\> and] <max\>
블록을 구성할 수 있는 범위 수를 지정합니다.
<min\>
및<max\>
값은 블록을 구성할 수 있는 범위의 최소 및 최대 범위를 지정합니다. -
[between 0 and] <max\>
더 이상 연속적이지 않은 것으로 간주되기 전의 범위 간 허용되는 분리 거리를 지정합니다.
-
(tokens| characters)
범위의 분리 거리가 토큰 수를 나타내는지 아니면 문자 수를 나타내는지 지정합니다.
-
<name\>.<column containing spans\>
블록 연산자가 적용될 뷰 이름 및 열 이름입니다.
-
<output name\>
블록 연산자에서 출력할 이름을 지정합니다.
사용법 참고
- 입력 범위에 겹치는 블록이 여러 개 있으면 block extraction 명령문에서 가능한 모든 블록을 리턴합니다. 중복 블록을 필터링하여 제외하는 데 통합을 사용합니다.
- 블록 추출 스펙이 있는
extract
명령문을 사용하면 각각 여러 입력 튜플에서 특정 필드 값을 집계하여 구성되는 블록이 생성됩니다. 따라서 해당 select 목록에는 입력 뷰의 필드가 포함될 수 없습니다.
예
예제 1: 문자 범위에 단어 블록 추출
다음 코드에서는 TwoToThreeCapitalizedWords
뷰를 통해 서로 100자 이내에 있는 대문자로 표시된 2 - 3개의 단어 블록을 식별합니다.
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;
예제 2: 토큰 범위에서 단어 블록 추출
다음 코드에서는 서로 5개의 토큰 이내에 있는 대문자로 표시된 정확히 두 단어로 구성된 블록을 식별합니다.
create view TwoCapitalizedWords as
extract blocks
with count 2
and separation between 0 and 5 tokens
on CW.word as capswords
from CapitalizedWords CW;
품사
품사 추출 스펙을 사용하여 전체 입력 텍스트에서 서로 다른 품사의 위치를 식별합니다.
구문
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>
설명
-
'<part of speech spec\>'
입력 텍스트에서 추출할 품사를 식별합니다.
'<part of speech spec\>'
은(는) 다음 문자열 중 하나입니다.- 다국어 토크나이저에서 생성하는 쉼표로 구분된 품사 태그 목록을 포함하는 문자열
- 맵핑 테이블에 정의된 대로 표시되는 내부 품사 이름과 플래그 조합
-
[and '<part of speech spec\>']*
추출에 사용할 추가 품사 태그를 식별합니다.
-
[with language '<language code\>']
추출에 사용할 언어를 지정합니다.
<language code\>
은(는) 'en' 또는 'ja' 와 같은 두 글자의 소문자 언어 코드입니다. 이 인수를 생략하면, 품사 추출에 사용하는 언어를 영어로 간주합니다. -
[and mapping from <mapping table name\>]
"NOUN"과 같은 원시 품사 태그를 상위 레벨 품사 및 플래그 조합으로 맵핑하는 AQL 테이블의 이름을 지정합니다. 선택적 맵핑 테이블에 변수 이름이 있을 수 있지만, 품사 맵핑 테이블에는 해당 열 이름이 있어야 합니다.
-
태그
다국어 토크나이저 품사 태그를 보유하는 열입니다.
-
basetag
해당 내부 태그를 보유하는 열입니다.
-
flagstr
표시된 품사와 연관된 쉼표로 구분된 플래그 목록을 보유하는 열입니다.
맵핑 테이블은 해당 테이블을 사용하는 정확한
create table
명령문과 동일한 모듈에서part_of_speech
명령문을 사용하여 정의해야 합니다. 가져온 테이블일 수 없으며 외부 테이블일 수도 없습니다.create table POSMapping_EN(tag Text, basetag Text, flagstr Text) as values ('CCONJ','CONJ','coordinating'), ('SCONJ','CONJ','subordinating');
-
-
<input column\>
품사 정보를 추출할 입력 뷰의 열을 지정합니다.
-
<output column\>
표시된 품사가 있는 토큰 범위를 전송할 열의 이름을 지정합니다.
-
<input view\>
품사 정보를 추출할 입력 뷰를 지정합니다.
사용법 참고
- 품사 추출은 다국어 토크나이저를 사용할 때만 작동합니다. 시스템에서 표준 토크나이저를 사용하는 경우
part_of_speech
추출을 수행하면 오류가 발생합니다.
언어의 품사 태그
지원되는 모든 언어에 대해 다국어 토크나이저에서는 다음 표에 나열된 품사 태그를 사용합니다.
태그 | 설명 |
---|---|
ADJ |
형용사 |
ADP |
부치사 |
ADV |
부사 |
AUX |
조동사 |
CCONJ |
coordinating conjunction(등위 접속사) |
DET |
한정사 |
INTJ |
감탄사 |
NOUN |
명사 |
NUM |
수사 |
PART |
particle(불변화사) |
PRON |
대명사 |
PROPN |
proper noun(고유 명사) |
PUNCT |
구두점 |
SCONJ |
subordinating conjunction(종속 접속사) |
SYM |
기호 |
VERB |
동사 |
X |
기타 |
예
예제 1: extract 명령문에서 직접 품사 태그 사용
EnglishNoun
뷰에서는 영어 명사(단수 또는 불가산) 또는 고유 명사(단수)를 추출합니다.
create view EnglishNoun
as extract parts_of_speech 'NOUN' and 'PROPN'
with language 'en' on D.text
as noun from Document D;
순서 패턴
패턴 추출 스펙을 사용하여 전체 입력 문서와 입력 문서에서 추출한 다른 범위에서 패턴 일치를 수행합니다.
구문
순서 패턴의 일반 구문은 먼저 텍스트에서 일치시킬 패턴을 지정한 다음 추출기에서 리턴할 사항을 지정하는 것입니다. 순서 패턴의 첫 번째 부분에서는 패턴의 입력을 지정합니다. 이 입력은 이전에 정의된 뷰의 열이거나 전체 문서 텍스트일 수 있습니다.
pattern <pattern specification> [return clause] [with inline_match on <viewname.colname>]
설명
-
<pattern specification\>
<pattern specification\>
은(는) 여러 개의 원자로 구성됩니다. 개별 Atom은 이미 정의된 뷰의 열, 고정 문자열 또는 정규식일 수 있습니다. Atom을 선택적이고 반복되게 지정하고 Atom 사이의 토큰 격차를 지정할 수 있습니다.패턴 스펙은 extract 절을 포함하는 대형 AQL 명령문의 일부입니다.
다음은 이전에 정의된 뷰에서 인접하는 세 개의 일치를 포함하는 뷰 작성 방법의 간단한 예입니다. 이 예에서는
group 0
이 참조하는 전체 조합을 리턴합니다.create view Money as extract pattern <C.match> <N.match> <Q.match> return group 0 as match from Currency C, Number N, Quantifier Q;
각각의 Atom이 바로 인접해 있지 않아도 되는 경우 Atom 사이의 토큰 격차를 사용하여 더 많은 일치를 찾을 수 있습니다. 이 예에서는 전화번호를 사용하여 0 - 2개의 토큰 내에서 다음에 오는 사용자의 멘션을 찾습니다.
<Token>{0,2}
구문에 유의하십시오. 이는 개인과 전화 어노테이션 사이에 0-2개 토큰의 갭이 허용됨을 표시합니다.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;
토큰 격차 구성(construct)은 순서 표현식에만 있도록 제한됩니다. 또한 순서의 각 토큰 격차 앞뒤에는 "non-token gap" 표현식이 와야 합니다. 결과적으로
extract pattern
명령문에서예외가 발생합니다.-> 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 ...
(min,max) 구문을 사용하여 각 Atom이 반복되는 횟수를 표시합니다. 또한 ? 구문을 사용하여 Atom 또는 반복 Atom이 선택적임을 표시할 수 있습니다. 반복적이고 선택적이라는 표시와 함께 Atom을 결합하여 순서를 작성합니다.
다음은 요소를 반복하는 방법을 보여주는 더 복잡한 예입니다. 대문자로 표시된 1 - 3개의 단어 다음에 'Hotel' 또는 '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;
|
연산자를 사용하여extract pattern <A.match>| <B.match> <C.match> as match from Apple A, Bacon B, Chocolate C;
에서와 같이 Atoms 사이의 선택사항을 표시할 수도 있습니다. 이 패턴은 "하나의A.match
또는 일련의B.match
다음에C.match
로 일치"와 같이 설명할 수 있습니다. 예제 1에서|
연산자를 사용하는 전체 예를 볼 수 있습니다.패턴을 작성한 후,
<pattern specification>
에 대한 각 일치는extract
문의 시작 부분에 있는 선택적<select list>
뿐만 아니라 패턴 스펙의 리턴 절에 따라 출력 결과를 생성합니다. 이 결과는having
명령문의consolidate
,limit
및extract
절에 따라 필터링되고 통합됩니다. 예를 들어, 패턴 스펙의 겹치는 일치가 여러 개이면 가능한 모든 일치가 리턴되며consolidation
절로 중복 출력을 필터링하여 제외할 수 있습니다.이전 예제를 고려해 보겠습니다. 단, 이제 목표는 'Sheraton'이라는 단어를 포함하는 일치를 제거하고 더 큰 일치에 포함된 일치를 제거하여 결과 일치를 통합하는 것입니다. 예를 들어 동일한 텍스트 범위에서 “Best Garden Hotel”과 “Garden Hotel”도 찾지 않으려 합니다.
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';
이제 구문과 몇 가지 예에 익숙하므로 이 다이어그램에서는 패턴 스펙의 전체 구문을 간략히 설명합니다. 빌드하려는 패턴의 구조화 방법을 보기 위해 패턴 빌드를 시작할 때 이 전체 구문을 참조하십시오.
POSIX 문자 기반 정규식에 익숙하면 구문이 비슷하다는 점을 알 수 있습니다. 이 경우 구문에서 요소 사이에 공백을 사용할 수 있고, AQL 용도에 맞게 요소도 정의할 수 있습니다. 이 경우 Alternation
라는 용어는 선택을 의미합니다. 요소 사이에 세로 막대를 사용하면 ( )
를 사용하여 그룹화할 수 있는 선택사항이 있음을 나타냅니다.
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 )
특히 Atom에는 다음과 같은 6개의 형식이 있을 수 있습니다.
-
<view_name.column_name\>
extract pattern
명령문의 from 목록에 이름 지정된 뷰, 테이블 또는 테이블 함수 참조 중 하나에서 열을 지정합니다. -
'string'
AQL 기본 사전 일치 시맨틱을 사용하여 지정된 문자열에 대한 일치를 지정합니다.
-
<'string' [match parameters]\>
[match parameters]
로 지정된 사전 일치 시맨틱을 사용하여 지정된 문자열에 대한 일치를 지정합니다.[match parameters]
의 형식은 대소문자(exact | insensitive)
입니다. 이 형식은 문자열 일치를 판별하는 데 사용되는 대소문자 폴딩 유형을 지정합니다. 대소문자를 구분하는 정확한 일치를 지정하려면 exact를 선택하십시오. 대소문자를 구분하지 않는 일치를 지정하려면 기본값 insensitive를 선택하십시오. -
/regex/
문서 텍스트에서 단일 토큰으로 제한된 일치를 사용하여 문자 기반 정규식 일치를 지정합니다. 또한 구문에서는 토큰의
min
및max
수 사이의 일치를 표시하도록 순서 표현식에 특수 토큰 격차 생성자를 지정할 수 있습니다. -
<token\>
모든 토큰과 일치하는 사항입니다.
-
[return clause]
return 절에 따라 패턴 표현식과 일치하는 각 항목의 추출된 값을 생성합니다.
return
절에는return
명령문의extract regex
절과 같은 시맨틱이 있습니다. -
[with inline_match on <viewname.colname\>]
문자열과 정규식 Atom과 같은 Atom의 경우,
with inline_match
절을 통해 시스템에서 문자열 또는 정규식 추출에 사용할 텍스트 오브젝트를 결정합니다. 예를 들어 절이with inline_match on Email.subject
이면 패턴 스펙에 인라인으로 정의된 모든 사전과 정규식이Email
뷰의 주제 필드에 적용됩니다.with inline_match
가 없으면 기본적으로 전체 Document.text에서 문자열과 정규식 추출이 실행됩니다. 이 경우 viewname은 현재 모듈에 정의되었거나 다른 모듈에서 가져온 뷰나 테이블의 이름이어야 합니다. 테이블 함수 참조는 with inline_match 절에서 허용되지 않습니다. -
[with language as <language code(s)\>]
쉼표로 구분된 두 글자 언어 코드(예: en(영어) 또는 zh(중국어)) 목록을 문자열을 평가할 언어로 지정합니다. 이 문자열에 포함되어 있지 않은 언어 코드를 사용하는 문서에는 일치가 없습니다. 언어 매개변수를 생략하면 평가 언어가 기본적으로 다음 언어 세트 중 하나로 지정됩니다.
- 선언된 경우 포함 모듈의 set default language 명령문을 통해 지정된 언어 세트.
- 독일어(de), 스페인어(es), 영어(en), 프랑스어(fr), 이탈리아어(it) 및 지정되지 않은 언어(x_unspecified)를 포함하는 언어 세트
사용법 참고
-
extract pattern
명령문의 시맨틱은 패턴 스펙을 통해 구동됩니다. 각 일치는 패턴 스펙의 return 절과extract
명령문의 맨 위에 있는 select 목록에 따라 출력 결과를 생성합니다. 이 결과는 extract 명령문의having
,consolidate
및limit
절에 따라 필터링되고 통합됩니다. 패턴 스펙의 겹치는 일치가 여러 개이면 패턴 추출에서 가능한 모든 일치를 출력합니다. 통합을 사용하여 중복 출력을 필터링하십시오. -
from
명령문에서extract pattern
절의 시맨틱은 패턴 스펙이 없는 다른 양식의extract
명령문과 다릅니다.extract
문의 일반 시맨틱은 추출 스펙이<from list\>
에 정의된 뷰의 각 조합에 대해 평가되어야 합니다.<from list\>
에 있는 하나 이상의 보기가 특정 문서에 대한 결과를 포함하지 않는 경우, 입력 보기의 모든 결과 조합 세트가 비어 있으므로 추출 명령문의 출력이 비어 있습니다. extract pattern 명령문과 같은 특수 경우에서 from 절은 패널 스펙에 관련된 관계 이름을 선언하는 플레이스홀더입니다. 명령문의 시맨틱은 패턴 스펙을 통해서만 구동됩니다. 특히 일부 입력 뷰가 빈 경우에도 명령문의 출력은 비어 있지 않을 수 있습니다. -
순서 패턴 추출을 사용하는
extract
명령문에서는from
목록의 뷰 열을 전달할 수 있지만, 패턴 스펙의 반복 요소에 뷰 이름이 표시되지 않는 경우에만 해당합니다. 예를 들어CapsWordOneToThree
명령문을 실행하면 컴파일 오류가 발생합니다.extract
명령문의 맨 위에 있는 전달된 포워드 열CW.type
이(가) 패턴 스펙의 반복 요소<CW.word>{1,3}
에 있는 뷰 이름CW
에 속하기 때문에 오류가 발생합니다.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;
패턴 스펙의 대체 또는 선택적 요소에 표시되는 뷰 이름에서 전달되는 열의 경우, 해당 대체 또는 선택적 요소가 텍스트에 없으면 출력 열의 값은
null
입니다. 이 점을 보여주는 예는 예제 1의Person
뷰에 있습니다. -
반복 요소 아래 있는 그룹은 명령문의
return
절에 있는 출력일 수 없습니다. 예를 들어 다음 명령문을 실행하면 예외가 발생합니다.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;
예
예제 1: 캡처링 그룹이 있는 순서 패턴
이 예에서는 이름, 선택적으로 중간 이니셜, 성을 순서대로 식별하고 선택적으로 일반적인 인사 호칭이 앞에 붙은 전체 일치 항목을 식별하여 개인의 이름을 찾습니다. 또한 추출기에서는 전체 일치는 reference로, 첫 번째 그룹은 salutation으로, 두 번째 그룹은 name으로 리턴하고, 각 입력 뷰에서 이름, 중간 이니셜 및 성 값을 전달합니다.
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;
하위 패턴 표현식 ('Mr.'|'Ms.'|'Miss')?
은(는) 선택적이므로 인사말이 텍스트에 없는 경우 인사말 출력 열의 값은 null
입니다. 마찬가지로, 패턴 하위 표현식 <M.initial>?
이(가) 선택적이므로 중간 초기가 없는 경우 출력 열 중간 값은 null
입니다.
예제 2: 문자열 일치 및 일치 매개변수가 있는 순서 패턴
이 예제에서는 문서의 제목 어노테이션을 검사하여 알려진 프로젝트의 미팅 기록이 있는지 찾습니다. 전체 문서 텍스트가 아니라 with inline_match
뷰의 일치 필드에 대해서만 문자열 일치를 수행하도록 지정하는 Title
절을 확인하십시오.
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;
예제 3: 입력 뷰가 비어 있는 경우에도 비어 있지 않은 결과를 리턴하는 순서 패턴
다음 명령문에서는 입력 뷰 LastName이 비어 있는 경우에도 결과를 생성합니다. 패턴 스펙의 두 번째 파트인 <L.name\>?
에는 선택적 요소가 포함되어 있습니다. 패턴 스펙의 시맨틱은 FirstName.name
범위 또는 바로 다음에 FirstName.name
범위가 오는 LastName.name
범위로 구성된 모든
범위를 출력하도록 디자인되어 있습니다. 따라서 LastName 뷰가 비어 있는 문서에서 명령문의 결과는 해당 문서에서 식별된 단일 FirstName.name
범위를 포함하는 모든 범위로 구성됩니다.
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;
select
명령문
AQL의 select
명령문에서는 다양한 스펙을 사용하여 튜플 세트를 생성하여 결합하는 강력한 메커니즘을 제공합니다.
구문
select
명령문의 구조는 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>`];
설명
-
<select list\>
쉼표로 구분된 출력 표현식 목록입니다.
-
<from list\>
선택할 튜플의 소스인 쉼표로 구분된 목록입니다.
-
[where <where clause\>]
from
절의 관계에 있는 모든 튜플의 카테시안 곱에서 생성된 각 튜플에 적용될 술어를 정의합니다. 이 절은 선택사항입니다. -
[consolidate on<column\>[using '<policy\>' [with priority from <column\> priority order]]]
겹치는 범위를 관리하는 통합 정책을 정의합니다. 이 절은 선택사항입니다.
-
[group by<group by list\>]
동일한 문서에서 생성된 튜플을 지정된 필드의 공통 값별로 그룹화합니다. 이 절은 선택사항입니다.
-
[order by<order by list\>]
각 문서의
select
명령문을 통해 생성하는 출력 튜플의 순서를 지정합니다. 순서는 쉼표로 구분된 표현식 목록인 order-by 목록 값을 기반으로 지정됩니다. 이 절은 선택사항입니다. -
[limit <maximum number of output tuples for each document\>]
각 문서의 출력 튜플 수를 지정된 최대값으로 제한합니다. 이 절은 선택사항입니다.
사용법 참고
select
명령문의 시맨틱은 다음과 같습니다.
- from 목록에 있는 관계의 카테시안 곱을 사용하여 입력 데이터(튜플에 포함)를 판별합니다.
- 생성된 각 입력 튜플에 대해 (선택적)
where
절의 술어를 적용하여 필터링합니다. - 선택적
group by
절이 있으면 동일한 문서에서 생성된 튜플을 group-by 목록에 지정된 값별로 그룹화하고 select 목록에 있는aggregate
함수 결과를 계산합니다. - (선택적)
consolidation
절에 정의된 정책에 따라 겹치는 모든 튜플을 통합합니다. 선택적order by
절이 있으면 order-by 목록 값에 따라 이 튜플의 순서를 지정합니다. - 각 튜플의
select
list에 있는 모든 표현식을 계산하고as
절에 지정된 대로 열의 이름을 바꿉니다. - 선택적
limit
절이 있으면 각 문서에 지정된 튜플 수로 출력 튜플 수를 제한합니다.
예
select
명령문 사용 방법의 예는 패턴과 일치하는 전화번호를 추출하는 것입니다. 미국의 경우 XXX-XXX-XXXX 패턴의 전화번호를 추출하는 PhoneNumbers
뷰가 이미 있다고 가정하십시오. 이 select
명령문에서는 입력 텍스트 전체에서 444-888-XXXX 패턴의 정규식을 평가합니다. 뷰에는 documentText
및 phoneNumber
라는 출력 열이 있습니다. 또한 문서당 식별되어 첫 번째로 표시되는 이 전화번호 패턴만 출력됩니다.
create view PhoneNumbersPattern1 as
select D.documentText, D.phoneNumber
from PhoneNumbers D
where MatchesRegex(/444-888-\d{4}/,D.phoneNumber)
limit 1;
select
명령문 사용 방법의 또 다른 예로는 사용자와 해당 전화번호의 대략적인 맵핑을 찾는 것이 있습니다. Person
뷰가 이미 정의되어 있으며, person
열과 PhoneNumbers
뷰가 있다고 가정하십시오. 이 select
명령문에서는 where
절을 평가하여 사용자 멘션 다음에
1 - 3개의 단어 또는 토큰 내의 전화번호가 오는 텍스트 범위를 찾습니다. 이 명령문의 입력은 from 목록의 Person
및 PhoneNumbers
뷰를 조인하여 표시합니다.
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);
personPhoneSpan
열에는 대략적인 사용자-전화번호 맵핑을 제공하는 일치 범위가 포함됩니다.
personPhoneSpan
John : 433-999-1000
Martha Mob 433-999-1001
- select 목록 AQL
select
또는extract
명령문의 select 목록은 쉼표로 구분된 출력 표현식 목록으로 구성됩니다. - from 목록 AQL의
select
또는extract
명령문의 두 번째 부분은 from 목록입니다. from 목록은 선택하거나 추출할 튜플의 소스인 쉼표로 구분된 목록입니다. - where 절 선택적
where
절에서는from
절의 관계에 있는 모든 튜플의 카테시안 곱에서 생성된 각 튜플에 적용될 술어를 정의합니다. - consolidate on 절 선택적
consolidate on
절에서는select
또는extract
명령문의 출력인 튜플 전체에서 겹치는 범위를 해결하는 방법을 지정합니다. 겹치지 않는 범위가 있는 튜플은 이 절을 사용해도 영향을 받지 않습니다. - group by 절
group by
명령문의 선택적select
절에서는 동일한 문서에서 생성되는 튜플을 지정된 필드의 공통 값별로 그룹화하도록 런타임 컴포넌트에 지시합니다. - order by 절 선택적
order by
절에서는 쉼표로 구분된 표현식 세트인 order by 목록 값을 기반으로 각 문서에서 select 명령문을 통해 생성한 출력 튜플의 순서를 지정하도록 런타임 컴포넌트에 지시합니다. - limit 절 선택적
limit
절에서는 문서의 select 명령문을 통해 생성되는 출력 튜플 수의 한계를 지정합니다. - select... into 명령문
select ... into
명령문은 하나의 명령문을 통해 뷰를 정의한 다음 출력 뷰가 되도록 지정하는 데 유용합니다.
select 목록
AQL select
또는 extract
명령문의 select 목록은 쉼표로 구분된 출력 표현식 목록으로 구성됩니다.
구문
각 select 표현식의 양식은 다음 중 하나여야 합니다.
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>
설명
-
<viewname\>.<colname\> as <alias\>
-
<viewname\>
열을 선택할 뷰를 지정합니다.
-
<colname\>
해당 뷰에 열을 지정합니다.
-
<alias\>
선택한 필드가 알려진 이름을 지정합니다. 이 필드는 선택적 필드입니다. 각 출력 튜플의 일부가 되도록 선택됩니다.
<alias\>
이(가) 지정되지 않은 경우, 열 이름은 기본적으로<colname\>
입니다. 단순 ID이거나 큰따옴표로 묶은 ID일 수 있습니다.
-
-
<viewname\>.*
뷰의 이름을 지정합니다. 이 구문은 지정된 뷰의 모든 열을 포함된
select
또는extract
명령문에 전달해야 함을 표시합니다.SQL과 같이 AQL을 사용하면 축약형
select *
명령문을 사용할 수 있습니다. 이 명령문을 사용하면from
명령문의select
절에 지정된 모든 입력에서 모든 열을 선택할 수 있습니다. 그러나 축약형 extract * 명령문은 지원되지 않습니다. -
<expr\> as <alias\>
포함 뷰의 속성에 표현식을 지정하는 것을 나타냅니다.
-
<expr\>
스칼라 함수 호출, 집계 함수 호출 또는 상수로 구성된 표현식을 지정합니다.
-
<name\>
<expr\>
에서<alias\>
(으)로 지정된 표현식의 결과를 보유하는 열의 이름을 나타냅니다.<alias\>
이(가) 지정되지 않은 경우, 열 이름은 기본적으로<name\>
입니다. 단순 ID이거나 큰따옴표로 묶은 ID일 수 있습니다.
-
-
when<function1()\> then <expr1\> when <function2()\> then <expr2\> ... when <functionN()\> then <exprn\> [else ] <expr_default\> as <name\>
-
<function1()\>, <function2()\>, <functionN()\>
Boolean 유형을 리턴하는 스칼라 함수를 지정하십시오.
-
<expr1\>, <expr2\>, <exprn\>, <expr_default\>
스칼라 함수 호출로 구성된 표현식을 지정하고 동일한 유형을 리턴해야 합니다.
<function1()\>
의 결과가 true이면case
표현식의 결과는<expr1\>
의 결과이고 후속when
절은 평가되지 않습니다. 그렇지 않으면 동일한 방식으로 후속when
절(있는 경우)을 평가합니다.when
절의 조건이 충족되지 않는 경우, 이 케이스 표현식의 결과는 기본 표현식<expr\_default\>
의 결과입니다. 이 표현식은 선택적else
절에 지정됩니다.[else]
절이 없으면 이case
표현식의 결과는null
입니다. -
사용법 참고
-
다음 명령문은 지원되지 않습니다.
select * from Document;
Document
뷰의 컨텐츠가select
명령문이 실행된 .aql 파일의 범위 또는 현재 컨텍스트에서 완전히 알려져 있지 않을 수 있습니다. 이 컨텐츠의 정보가 부족한 이유는 현재 .aql 파일 외부에서 제공된 여러require document with columns
명령문을 모듈 레벨에서 사용하면 이 특수Document
뷰의 최종트 스키마 정의를 변경할 수 있기 때문입니다. 축약형 Document.* 명령문은 올바른 AQL 생성자가 아닙니다. -
Document
뷰에서 명시적으로 필드를 선택할 수 있습니다. 다음 예에서는Document
뷰에서 명시적으로 올바르게 필드를 선택하는 방법을 보여줍니다.select D.label as label, D.text as text from Document D;
예
다음 예에서는 select 목록의 다양한 양식을 보여줍니다.
예제 1: 상수를 사용한 명시적 값 지정
이 예에서는 select 목록에서 뷰 속성에 상수 값을 지정하는 방법을 보여줍니다. polarity라고 하는 필드는 PS.match
의 극성이 양극인지 음극인지를 나타냅니다(이 속성에 상수 값을 명시적으로 지정함).
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;
예제 2: 함수 호출을 사용한 명시적 값 지정
다음 예에서는 select 목록에서 뷰 속성에 명시적으로 함수 호출 결과를 지정하는 방법을 보여줍니다.
create view Citizenship as
select
P.Name as name,
MatchesDict('USCities.dict', P.birthPlace) as isUSCitizen
from
Person P;
예제 3: 사전 추출의 Select 목록 표현식
다음 예에서는 select list 표현식을 통해 사전 추출 결과에서 Span 유형의 값을 수집하는 방법을 보여줍니다.
create view PersonNames as
select N.match as name
from
(extract
dictionary 'firstNames.dict'
on D.text
as match
from Document D
)N;
예제 4: case 표현식의 예
이 첫 번째 예에서는 특정 필드에서 널 처리를 지정하는 방법을 보여줍니다.
create view School as
select
case
when Not(NotNull(P.education)) then 'Unknown'
else GetString(P.education)
as name
from Person P;
이 예에서는 데이터 분류 방법을 설명합니다.
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;
from 목록
AQL의 select
또는 extract
명령문의 두 번째 부분은 from list입니다. from 목록은 선택하거나 추출할 튜플의 소스인 쉼표로 구분된 목록입니다.
구문
from <from list item> <name> [, <from list item> <name>]
설명
-
<from list item\>
뷰, 테이블, 테이블 함수 또는 중첩된 AQL 명령문입니다. AQL의 중첩된 모든 명령문은 소괄호로 묶어야 합니다.
-
<name\>
select
문 또는extract
문 내에서 범위가 지정되는<from list item\>
의 로컬 이름입니다. 로컬 이름은 단순 ID이거나 큰따옴표로 묶은 ID일 수 있습니다. 공백, 구두점 문자 또는 AQL 키워드를 포함하는 로컬 이름은 큰따옴표로 묶어야 합니다.
예
예제 1: 뷰와 중첩된 명령문이 있는 from 목록
이 예에서는 뷰와 중첩된 extract
명령문을 참조하는 from 목록을 보여줍니다. 이 예에서는 로컬 이름 FN
에 명령문 결과를 지정합니다. 또한 LastName
뷰의 출력을 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);
다음 이름은 외부 사전 first.dict에 포함되어 있습니다.
#Dictionary for given names
Aaron
Candra
Freeman
Mathew
Matthew
Zoraida
where
절
선택적 where
절에서는 from
절의 관계에 있는 모든 튜플의 카테시안 곱에서 생성된 각 튜플에 적용될 술어를 정의합니다.
구문
select <select list>
from <from list>
[where <where clause>]
설명
-
<where clause\>
하나 이상의 술어를 지정합니다.
where
절의 술어에from
목록에 속한 두 개 이상의 뷰에 있는 필드가 포함되면 조인이 수행됩니다. 이 술어는 기본 제공 술어 함수 또는 Boolean 데이터 유형을 리턴하는 기타 사용자 정의 함수 세트의 결합이어야 합니다.function1() and function2() and ... and functionn()
where
절은 선택사항이며 적용할 술어가 없으면select
명령문에서 생략할 수 있습니다.
예
예제 1: WHERE절에서 술어를 사용하여 조인된 튜플 필터링
이 예에서는 0 - 1자 내에서 올바른 성이 뒤에 오는 올바른 이름으로 구성된 문구만 찾는 where
절을 보여줍니다.
-- 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);
다음 이름은 외부 사전 first.dict에 포함되어 있습니다.
#Dictionary for given names
Aaron
Candra
Freeman
Mathew
Matthew
Zoraida
다음 이름은 외부 사전 last.dict에 포함되어 있습니다.
#Dictionary for surnames
Anthony
Lehman
Radcliff
consolidate on
절
선택적 consolidate on
절에서는 select
또는 extract
명령문의 출력인 튜플 전체에서 겹치는 범위를 해결하는 방법을 지정합니다. 겹치지 않는 범위가 있는 튜플은 이 절을 사용해도 영향을 받지 않습니다.
구문
다음 코드는 이 절의 일반적인 구조 예입니다.
consolidate on <target>
[using '<policy>'[ with priority from <priority_column>
[ <priority_order> ]]]
설명
-
<target\>
from
절의 뷰에 열을 지정하거나from
절에 인수로 지정된 뷰의 열을 포함하는 스칼라 함수 호출로 구성된 표현식을 지정합니다. -
'<policy\>'
텍스트 분석에서 지원하는 다음 통합 정책 중 하나를 지정합니다.
-
ContainedWithin
이 정책이 기본값입니다. 범위 A와 B가 겹치고 A가 B를 완전히 포함하면 이 정책에서 범위 B를 포함하는 튜플을 출력에서 제거합니다. A와 B가 동일하면 둘 중 하나를 제거합니다. 제거할 튜플은 임의로 선택할 수 있습니다.
-
NotContainedWithin
범위 A와 B가 겹치고 A가 B를 완전히 포함하면 이 정책에서 범위 A를 출력에서 제거합니다. A와 B가 동일하면 둘 중 하나를 제거합니다. 제거할 튜플은 임의로 선택할 수 있습니다.
-
ContainsButNotEqual
이 정책은 완전히 동일한 범위가 보존된다는 점을 제외하고는 ContainedWithin과 동일합니다.
-
ExactMatch
범위의 세트가 동일한 텍스트 영역을 포함하는 경우 이 정책에서는 정확히 하나의 범위만 리턴합니다. 다른 모든 범위는 그대로 남아 있습니다.
-
LeftToRight
이 정책에서는 왼쪽에서 오른쪽 순으로 범위를 처리합니다. 겹치기가 발생하면 가장 왼쪽에 있는 겹치지 않는 가장 긴 범위를 보존합니다. 이 정책에서는 정규식 엔진 대부분의 겹침 처리 정책을 에뮬레이트합니다.
-
-
<priority\_column\>
Text, String, Integer 또는 Float 유형의 열을 지정합니다.
LeftToRight
통합 정책에서만 지정할 수 있습니다. -
<priority\_order\>
오름차순 또는 내림차순을 지정합니다.
LeftToRight
통합 정책에서만 지정할 수 있습니다. 오름차순에서는우 튜플 T1의 우선순위가 1이고 튜플 T2의 우선순위가 2이면 T1이 T2보다 우선순위가 높습니다. 반대로 우선순위를 내림차순으로 지정하면 T2의 우선순위가 높습니다. 우선순위 순서의 기본값은 오름차순입니다.
사용법 참고
- priority 절이 있으면 통합의 시맨틱은 다음 순서를 따릅니다.
- 왼쪽에서 오른쪽으로 범위를 처리하고, 범위가 겹치면 맨 왼쪽의 범위를 보존합니다.
- 동일한 오프셋에서 겹치는 범위가 여러 개이면 우선순위 순서에 따라 우선순위가 가장 높은 범위를 보존합니다.
- 우선순위가 같은 범위 중에 가장 긴 범위를 보존하여 남은 범위의 우선순위를 구분합니다.
- 통합에서는 여러 널을 동일한 것으로 처리합니다. 널(null)
<consolidate target\>
이(가) 있는 모든 입력은 단일 출력 튜플을 생성하며, 이는 이러한 입력 중에서 무작위로 선택됩니다. 이 동작은 튜플이 대상 열의 동일한 범위와 통합되는 방식과 비슷합니다. 단, 예외적으로 단일 출력 튜플을 생성하지 않는 경우는 정책이 ContainsButNotEqual인 때입니다. 이 경우, 널(<consolidate target\>
)은 널 통합 대상이 있는 모든 입력을 출력합니다.
예
예 1: 단일 열의 통합
이 예에서는 시스템에서 모든 출력 튜플의 Person.name
필드를 검사하고 ContainedWithin
통합 정책을 사용하여 겹침을 해결하도록 지시합니다.
consolidate on Person.name
using 'ContainedWithin'
예제 2: 여러 열을 포함하는 표현식에서 통합
이 예에서는 시스템에서 각 출력 튜플의 CombineSpans
및 Person.firstname
필드에 Person.lastname
스칼라 함수를 적용한 결과를 검사하도록 지시합니다. ContainedWithin
통합 정책을 사용하여 겹침을 해결합니다.
consolidate on
CombineSpans(Person.firstname, Person.lastname)
using 'ContainedWithin'
예제 3: LeftToRight
정책 및 우선순위 순서를 사용하여 통합
입력 텍스트인 John Doe에서 다음 용어 튜플이 추출된다고 가정하십시오.
match: `John`,
priority: `1`
및
match: `John Doe`,
priority: `2`
두 범위의 시작 오프셋이 같습니다. 오름차순 우선순위 순서에 LeftToRight
정책을 사용하여 통합하면 (match: John, priority: 1
) 튜플이 우선순위가 높으므로 보존됩니다. 내림차순 우선순위 순서를 사용하여 통합하면 다음 예와 같이 (match: John Doe, priority: 2
) 튜플이 보존됩니다.
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;
group by
절
group by
명령문의 선택적 select
절에서는 동일한 문서에서 생성되는 튜플을 지정된 필드의 공통값별로 그룹화하도록 런타임 컴포넌트에 지시합니다.
구문
select <select list>
from <from list>
[where <where clause>]
...
[group by <group by list>]
설명
-
<group by list\>
from
절의 뷰 열과 스칼라 함수 호출을 포함하는 쉼표로 구분된 표현식 목록을 지정합니다.group by
절을 적용하면 모든group by
표현식에 공통 값을 공유하는 각 튜플 그룹에서 전체 그룹을 대표하는 단일 출력 튜플을 생성합니다.group by
절에 표시되지 않는 필드나 표현식은 집계 함수 호출에서 사용하는 경우가 아니면 select 목록에 표시될 수 없습니다. 목록에서 표현식 순서는 중요하지 않습니다.group by
절은 모든 널을 동일하게 처리합니다. 널 값이 있는 열의Group by
은(는) 단일 그룹을 생성합니다.
예
예제 1: 집계 값 계산
group by
절을 사용하여 집계 값을 계산하십시오. 이 예에서는 문서에 표시된 각 이름의 수를 계산합니다. 이 예에서 Count
는 집계 함수입니다.
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);
이 경우 first.dict
는 다음 항목을 포함하는 외부 사전입니다.
#Dictionary for given names
Aaron
Candra
Freeman
Matthew
Zoraida
다음 단계에서는 이 명령문의 시맨틱을 설명합니다.
from
절의 하위 조회에서 생성한 튜플을firstname
필드의 텍스트 컨텐츠별로 그룹화합니다.- 그룹마다 널이 아닌
firstname
값이 있는 튜플 수를 계산합니다. 그룹마다 해당 그룹에 있는 튜플의 수와 이름 및 두 개의 값이 있는 단일 출력 튜플을 생성합니다.
예제 2: 서로 다른 필드를 그룹화하는 문제
이 예에서는 올바르지 않은 명령문을 보여줍니다.
select GetText(P.firstname) as first,
GetText(P.lastname) as last,
Count(P.firstname) as occurrences
from Person P
group by GetText(P.firstname);
GetText(P.lastname)
값이 동일한 튜플의 firstname
값이 달라서 모호성이 초래될 수 있으므로 select 목록에는 lastname
을 포함할 수 없습니다.
order by
절
선택적 order by
절에서는 쉼표로 구분된 표현식 세트인 order by 목록 값을 기반으로 각 문서에서 select 명령문을 통해 생성한 출력 튜플의 순서를 지정하도록 런타임 컴포넌트에 지시합니다.
구문
select ...
[order by <order by list>]
설명
-
<order by list\>
쉼표로 구분된 표현식 목록을 지정합니다.
순서는 쉼표로 구분된 표현식 목록인 값을 기반으로 지정됩니다. order by 절에서는 숫자(Integer 또는 Float), Text 또는 Span 데이터 유형을 리턴하는 표현식을 지원합니다.
order by
절의 표현식에서 Span을 리턴하면 관련 범위 값을 비교하여 결과 튜플을 비교합니다. 다음 예에서는person
필드의 범위 값을 비교합니다.order by P.person
order by
절에서는 (널 간에) 순서가 지정되지 않는 것으로 널을 처리합니다. 널은 다른 오브젝트 아래 정렬됩니다.
예
예제 1: Order by 다중 표현식
사용자가 Span 유형의 필드라고 가정하십시오. 다음 order by
절에서는 명령문을 통해 각 문서의 튜플을 리턴하도록 지정합니다. 사용자 필드의 텍스트를 기준으로 한 다음, 사용자 필드의 시작을 기준으로 사전 순으로 정렬합니다.
order by GetText(P.person), GetBegin(P.person)
limit
절
선택적 limit
절에서는 문서의 select 명령문을 통해 생성되는 출력 튜플 수의 한계를 지정합니다.
구문
select <select list>
from <from list>
...
[limit <maximum number of output tuples for each document>];
설명
-
<maximum number of output tuples for each document\>
각 문서의 최대 출력 튜플 수를 지정합니다. 한계 값이 리턴될 수 있는 총 튜플 수보다 크거나 같으면 모든 튜플이 리턴됩니다.
예
예제: 리턴 수 제한
이 예에서는 각 문서에 있는 처음 세 사용자의 이름을 리턴합니다.
create view SampleView as
select *
from Person P
order by GetBegin(P.name)
limit 3;
select... into
명령문
select ... into
명령문은 하나의 명령문을 통해 뷰를 정의한 다음 출력 뷰가 되도록 지정하는 데 유용합니다.
구문
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>];
설명
-
<output view name\>
명령문에서 정의하는 출력 뷰의 이름을 지정합니다.
select ... into
문은 추가into <output view name\>
절을 제외하고select
문과 동일합니다.
예
예제 1: 뷰 정의
이 예에서는 PersonPhone
이라는 뷰를 정의하고 이 뷰를 출력 뷰로도 정의합니다.
select P.name as name,
Ph.number as phoneNumber
into PersonPhone
from Person P, Phone Ph;
이 예는 다음 두 명령문과 동일합니다.
create view PersonPhone as
select P.name as name,
Ph.number as phoneNumber
from Person P, Phone Ph;
output view PersonPhone;
detag
명령문
AQL의 detag
명령문에서는 AQL 추출기를 실행하기 전에 HTML 또는 XML 문서에서 모든 마크업을 제거하거나 태그를 해제하는 기능을 제공합니다.
detag
명령문에서는 이 태그에 저장된 모든 값과 원래 위치도 보존할 수 있습니다. detag
명령문을 통해 문서에서 태그를 제거하면 런타임 컴포넌트에서 태그 해제된 텍스트의 오프셋과 원래 마크업 소스의 오프셋 간 맵핑을 기억합니다. 특수 기본 제공 함수인 Remap
함수에서 태그 해제된 텍스트의 범위를 원래 소스의 해당 범위로 다시 맵핑합니다.
구문
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 ...]];
설명
-
<input view name\>.<text column\>
-
<input view name\>
태그 해제 프로세스를 수행하는 입력 뷰의 이름을 지정합니다.
<input view name\>
은(는) 단순 ID 또는 큰따옴표로 묶인 ID일 수 있습니다. -
<text column\>
태그 해제 프로세스를 수행하는 입력 뷰의 텍스트 필드를 지정합니다.
<text column\>
은(는) 단순 ID 또는 큰따옴표로 묶인 ID일 수 있습니다.
-
-
<output view name\>
태그 해제된 텍스트를 포함하는 출력 뷰의 이름을 지정합니다. 출력 뷰에는 태그 해제된 텍스트를 보유하는 text라는 단일 열이 포함되어 있습니다.
<output view name\>
은(는) 단순 ID 또는 큰따옴표로 묶인 ID일 수 있습니다. -
always|never
detag
명령문을 처리하기 전에 컨텐츠가 HTML 또는 XML임을 확인할지 지정합니다. 분리자를 통해 비HTML 및 비XML 텍스트를 실행하는 경우 텍스트에<
,>
또는&
과(와) 같은 XML 특수 문자가 포함된 경우 문제점이 발생할 수 있습니다.detect content_type
절이 누락되어 있으면 기본값은 항상이며 시스템에서 항상 컨텐츠를 발견합니다.-
always
연산에서 HTML 또는 XML이 아닌 문서를 구문 분석하는 데 관련된 문제점을 방지하기 위해 항상 검증하도록 지정합니다.
<text column\>
의 값에 마크업이 포함되지 않은 경우 시스템은 현재 문서에 대한 분리를 건너뜁니다. -
never
태그 해제 연산을 시도하기 전에 검증을 수행하지 않도록 지정합니다. 텍스트에 HTML 또는 XML 컨텐츠가 포함되어 있지 않아도 시스템에서 대상 텍스트의 태그를 해제하려고 합니다.
-
-
<element name\>
어노테이션을 작성할 HTML 또는 XML 요소의 이름을 지정합니다. 선택적
annotate
절에서 하나 이상의 뷰를 작성하여 제거된 태그에 관한 정보를 기억하도록 런타임 컴포넌트에 지시할 수 있습니다. -
<auxiliary view name\>
원래 태그와 해당 속성을 보유하도록 작성된 뷰의 이름을 지정합니다. 단순 ID이거나 큰따옴표로 묶은 ID일 수 있습니다.
-
<attribute name\>
HTML 또는 XML 요소의 속성 이름입니다.
-
<column name\>
<attribute name\>
의 값을 저장하는 데 사용되는<auxiliary view name\>
의 열 이름입니다. 단순 ID이거나 큰따옴표로 묶은 ID일 수 있습니다.
예
예제 1: 태그 해제 출력 뷰와 보조 뷰 지정
이 예에서는 DetaggedDoc
뷰의 text
속성에 원래 텍스트의 태그가 해제된 버전을 보유하도록 Document
뷰를 작성합니다. DetaggedDoc
뷰 작성 외에도 annotate 절을 통해 Anchor
라는 보조 뷰를 작성합니다. 이 보조 뷰에는 두 개의 열이 있습니다. match라는
한 열에는 앵커 텍스트가 포함되어 있습니다. linkTarget이라는 다른 열에는 링크의 실제 대상이 텍스트로 포함되어 있습니다. 일치 열의 범위가 DetaggedDoc
뷰의 텍스트 값을 초과합니다.
detag Document.text as DetaggedDoc
annotate
'a' as Anchor
with attribute 'href' as linkTarget;
예제 2: Remap
함수 사용
다음 예에서는 Remap
함수를 사용하여 태그가 해제된 텍스트의 범위를 다시 원래 소스의 해당 범위로 맵핑하는 방법을 보여줍니다.
-- 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;
AQL Doc로 detag
명령문 문서화
detag
명령문의 AQL Doc 주석에는 다음 정보가 포함되어 있습니다.
- 명령문의 함수에 대한 일반 설명.
- 태그 해제 프로세스를 수행하는 입력 뷰의 각 텍스트 필드용 @field.
- @auxView를 통해 뷰 이름을 지정합니다.
- @auxViewField를 통해 뷰의 완전한 열 이름을 지정합니다.
/**
* 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;
create dictionary
및 create external dictionary
명령문
create dictionary
및 create external dictionary
명령문은 extract 명령문 또는 predicate 함수를 통해 전체 입력 텍스트에서 일치하는 용어를 식별하는 단어 또는 문구 사전을 정의하는 데 사용합니다. create dictionary
명령문을 사용하면 소스 AQL 코드에서 사전 컨텐츠의 지정을 허용하며 사전 컨텐츠는
컴파일된 모듈(.tam 파일) 표시 내에서 직렬화됩니다. create external dictionary
명령문을 사용하면 소스 AQL 코드에서가 아니라 추출기를 인스턴스화할 때 사전 컨텐츠를 지정할 수 있으며 모듈을 다시 컴파일하지 않아도 됩니다. 따라서 외부 사전은 AQL 개발자가 컴파일된 모듈에 사용자 정의 지점을 노출하는 데 사용할 수 있는 강력한 구성(construct)입니다.
사전은 다음 세 개의 소스에서 작성할 수 있습니다.
- 사전 파일
- 인라인 사전 선언
create table
명령문과create external table
명령문으로 작성된 테이블
구문
internal create dictionary 명령문에는 세 가지 구문 양식, from file
, from table
및 인라인 형식이 있습니다.
-
Internal dictionary
원본 파일:
create dictionary <dictionary name> from file '<file name>' [with language as '<language code(s)>'] [and case (exact | insensitive)] [and lemma_match];
선택한 테이블:
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];
인라인 형식
create dictionary <dictionary name> [with language as '<language code(s)>'] [and case (exact | insensitive)] [and lemma_match] as ( '<entry 1>', '<entry 2>', ... , '<entry n>' ) ;
-
외부 사전
create external dictionary <dictionary-name> required [true|false] [with language as '<language codes\>'] [and case (exact | insensitive )] [and lemma_match];
설명
-
<dictionary name\>
새 내부 또는 외부 사전의 이름을 지정합니다. 단순 ID이거나 큰따옴표로 묶은 ID일 수 있습니다.
-
'<file name\>'
사전 항목을 포함하는 파일의 이름을 지정합니다. 사전 파일은 행당 하나의 사전 항목이 있는 캐리지 리턴으로 구분된 텍스트 파일입니다. 사전 파일의 항목은 여러 개의 토큰으로 구성될 수 있습니다.
-
<table name\>
사전 항목을 추가할 테이블의 이름을 지정합니다. 사전은 다른 모듈에서 가져온 테이블에서 작성할 수 없습니다.
-
<column name\>
사전 항목을 추가할 테이블에 열 이름을 지정합니다.
-
required [true|false]
모듈을 실행하는 데 외부 사전의 외부 컨텐츠가 필요한지 지정합니다.
-
true
절이
required true
이면 외부 컨텐츠를 포함하는 파일의 위치에 URI를 제공해야 합니다. 지정된 파일에는 컨텐츠가 포함되어있어야 합니다. URI가 제공되지 않거나 파일에 컨텐츠가 포함되어 있지 않으면 런타임 컴포넌트에서 예외가 발생합니다. -
false
절이
required false
이면 이 사전에 사용하도록 외부 컨텐츠의 URI를 제공하지 않아도 모듈을 실행할 수 있습니다. URI를 제공하지 않으면 런타임 컴포넌트에서 이 사전을 빈 사전으로 처리합니다.
이제
create external dictionary <dictionary-name\> allow_empty
사용이 더 이상 사용되지 않으며 컴파일러 경고가 발생합니다. -
-
'<language code(s)\>'
쉼표로 구분된 두 글자 언어 코드(예: en(영어) 또는 zh(중국어)) 목록을 사전을 평가하는 데 사용할 외부 사전의 문서 언어 또는 언어로 지정합니다. 이 사전에서는 이 문자열에 포함되어 있지 않은 언어 코드를 사용하는 문서에 결과를 생성하지 않습니다.
언어 매개변수를 생략하면 사전 언어가 기본적으로 다음 언어 세트 중 하나로 지정됩니다.
- 선언된 경우 포함 모듈의
set default language
명령문을 통해 지정된 언어 세트. - 독일어(de), 스페인어(es), 영어(en), 프랑스어(fr), 이탈리아어(it) 및 지정되지 않은 언어(x_unspecified)를 포함하는 언어 세트.
- 선언된 경우 포함 모듈의
-
lemma_match
문서에서 사전 용어와 동일한 단어의 일치를 찾는 데 표제어 추출(lemmatization)을 사용합니다.
표제어 추출은 지정된 단어의 기본형을 판별하는 프로세스입니다. 기본형은 지정된 단일 용어와 일치하는 항목으로 사용할 수 있는 단어입니다. 예를 들어 “go”라는 용어는 “goes”, “going”, “gone” 또는 “went”라는 용어와 일치될 수 있습니다. 이 프로세스에서는 문장에서 단어의 품사 판별 및 컨텍스트 이해와 같은 복잡한 태스크를 수행합니다. 표제어 추출은 IBM Multilingual 토크나이저에서 품사 지원을 제공하는 모든 언어에서 사용할 수 있습니다.
기본형 일치는
lemma match
절로 선언된 사전을 대상으로만 수행합니다.lemma_match
절을 사용한 사전 추출의 시맨틱은 다음과 같습니다.- 각 입력 문서 토큰의 표제어 추출된 양식을 계산합니다.
- 표제어 추출된 문서를 대상으로 사전을 평가합니다.
lemma_match
옵션과 함께case exact
옵션을 사용할 수 없습니다. 둘 다 사용하는 경우 컴파일 오류가 리턴됩니다.
-
case (exact | insensitive)
문서의 특정 영역이 일치하는지 판별할 때 사전이 수행하는 대소문자 폴딩 유형을 지정합니다.
-
exact
정확한 대소문자 구분 일치를 지정합니다.
-
insensitive
대소문자를 구분하지 않는 일치를 지정합니다. 이 옵션은 기본값입니다.
-
-
'<entry 1\>', '<entry 2\>', ... , '<entry n\>'
인라인 사전에 포함시킬 문자열을 지정합니다. 인라인 사전의 항목은 하나 이상의 토큰으로 구성될 수 있습니다.
사용법 참고
-
항목을 수정할 것으로 예상하거나 항목이 여러 개인 경우 특히
from file
및from table
형식을 사용하는 것이 좋습니다. 이 형식을 사용하면 코드를 수정하지 않고도 사전의 컨텐츠를 수정할 수 있습니다. -
모듈식 AQL 컴파일러에서
create dictionary
명령문을 처리할 때create dictionary ... from file
구문에 지정된 사전 파일 위치 참조는create dictionary
명령문이 실행된 모듈의 루트에 상대적이어야 합니다. -
주석 앞에
#
문자를 지정하여 사전 파일에 주석을 지정할 수 있습니다. 주석은 행의 임의의 위치에서 시작할 수 있습니다. -
여러 행에 걸친 주석을 지정하려면 각 행 앞에 주석 문자를 지정해야 합니다. 주석 문자가 사전 항목의 일부이면
\#
에서와 같이 백슬래시 문자(\)를 사용하여 이스케이프 처리해야 합니다. 백슬래시 문자가 사전 항목의 일부이면\\
에서와 같이 백슬래시 자체를 사용하여 이스케이프 처리해야 합니다. -
외부 사전의 경우, 모듈을 로드할 때 로드되는 모듈에 필요한 대로 외부 사전의 URI 목록을 지정해야 합니다.
-
사전 표제어 추출: 기존 사전 일치 시맨틱과 표제어 추출 시맨틱 사이의 주된 차이점은 문서의 원래 양식이 아니라 문서의 표제어가 추출된 양식을 대상으로 일치를 수행하는 것입니다.
기본형 일치를 사용하는 사전에 속한 사전 항목에는 다음 전제조건이 있습니다.
- 사전 항목에 하나 이상의 토큰이 포함될 수 있습니다. 여기서 각 항목 토큰은 기본형입니다. 기본형 사전을 작성하려면 [GetLemma 스칼라 함수를 사용할 수 있습니다.
- 사전 항목의 토큰은 공백으로 구분해야 합니다. 토큰이 공백으로 구성된 경우 백슬래시(\) 문자를 사용하여 공백을 이스케이프 처리해야 합니다.
-
다음 표에서는
create external dictionary
명령문과create dictionary
명령문 사이의 차이점을 보여줍니다.
create external dictionary |
create dictionary |
---|---|
|
|
예
예제 1: 외부 사전 작성
외부 사전인 PersonPositiveClues는 로드 시 외부 파일의 값으로 채워야 합니다. 또한 플래그를 통해 지정한 대로 서구권 언어를 대상으로 일치 여부를 확인해야 합니다.
module PersonModuleEnglish;
create external dictionary PersonPositiveClues
allow_empty false
with case exact;
export dictionary PersonPositiveClues;
예제 2: 표제어 추출
기본형 일치를 사용하고 go shop 및 went shopping이라는 두 항목을 포함하는 사전을 고려해 보겠습니다. 문서에는 Anna went shopping
이라는 텍스트가 포함되어 있습니다. 입력 문서의 표제어 추출된 양식은 Anna go shop
입니다. 기본형 일치에서는 go shop 항목의 일치로 went shopping을 리턴합니다. 원래 문서 텍스트는 사전 항목이 아니라
표제어 추출 문서 텍스트와만 비교합니다. 따라서 문서에서 went shopping
항목과 일치하는 사항이 없습니다.
AQL Doc로 create dictionary
및 create external dictionary
명령문 문서화
create dictionary
명령문의 AQL Doc 주석에는 다음 정보가 포함되어 있습니다.
사전에 관한 일반 설명
/**
* A dictionary of terms used to greet people.
*
*/
create dictionary GreetingDict as
(
'regards', 'regds', 'hello', 'hi', 'thanks', 'best', 'subj', 'to', 'from'
);
create external dictionary
명령문의 AQL Doc 주석에는 작성된 사전에 관한 일반 설명이 포함되어 있습니다. 다음 문자열은 형식을 보여줍니다.
/**
* Customizable dictionary of given names.
* Evaluated on English, French, Italian, German, Portuguese, Spanish text.
*/
create external dictionary CustomFirstNames_WesternEurope
allow_empty true;
create table
명령문
create table
명령문에서 AQL 테이블을 작성합니다.
AQL의 create table
명령문은 자세한 정보로 어노테이션을 보강하는 정적 검색 테이블을 정의하는 데 사용합니다.
구문
create table <table name> (
<colname> <type> [, <colname> <type>]* )
as values
( <value> [, <value>]*),
...
( <value> [, <value>]*);
설명
-
<table name\>
작성할 테이블의 이름을 지정합니다.
<table name\>
은(는) 단순 ID 또는 큰따옴표로 묶인 ID일 수 있습니다. -
<colname\>
작성할 열의 이름을 지정합니다.
-
<type\>
연관된 열의 AQL 데이터 유형을 지정합니다. 모든 열의 유형은 Text , Integer, Float 또는 Boolean이어야 합니다.
-
<value\>
작성된 테이블에서 채울 튜플을 지정합니다.
예
예제 1: 회사 이름 테이블 작성
이 예에서는 create table
명령문을 통해 회사 이름 어노테이션에 위치 메타데이트를 추가합니다.
-- 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;
AQL Doc로 create table
명령문 문서화
create table
명령문의 AQL Doc 주석에는 다음 정보가 포함되어 있습니다.
- 테이블에 관한 일반 설명.
- 이 테이블의 스키마에 있는 모든 열 이름의 @field.
/** 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');
create external table
명령문
컴파일된 모듈이 모든 입력 문서에서 실행될 때 설정된 컨텐츠가 있는 테이블을 지정하려면 create external table
명령문을 사용할 수 있습니다. 소스 AQL 코드에서가 아니라 로드 시 테이블 컨텐츠를 제공할 수 있으며 모듈을 다시 컴파일하지 않아도 됩니다.
외부 테이블은 AQL 개발자가 컴파일된 모듈에 사용자 정의 지점을 노출하는 데 사용할 수 있는 강력한 구성(construct)입니다.
구문
create external table <table-name\>
(<colname\> <type\>
[, <colname\> <type\>]* )
allow_empty <true|false>;
설명
-
<table-name\>
작성할 외부 테이블의 이름을 지정합니다.
<table-name\>
은(는) 단순 ID 또는 큰따옴표로 묶인 ID일 수 있습니다. -
<colname\>
작성할 열의 이름을 지정합니다.
-
<type\>
연관된 열의 AQL 데이터 유형을 지정합니다. 모든 열의 유형은 Text , Integer, Float 또는 Boolean이어야 합니다.
-
[, <colname\> <type\>]*
외부 테이블에서 사용할 추가 열 및 AQL 오브젝트를 지정합니다.
-
allow_empty [true|false]
allow_empty
절의 값을 지정합니다.-
true
절이
allow_empty true
이면 이 테이블에 사용하도록 외부 컨텐츠의 URI를 제공하지 않아도 모듈을 실행할 수 있습니다. URI를 제공하지 않으면 런타임 컴포넌트에서 이 테이블을 빈 테이블로 처리합니다. -
false
절이
allow_empty false
이면 외부 컨텐츠를 포함하는 파일의 위치에 URI를 제공해야 합니다. 지정된 파일에는 컨텐츠가 포함되어있어야 합니다. URI가 제공되지 않거나 파일에 컨텐츠가 포함되어 있지 않으면 런타임 컴포넌트에서 예외가 발생합니다.
-
사용법 참고
- 컴파일된 모듈 표시에는 모듈에서 정의하는 외부 오브젝트(뷰, 사전 및 테이블)에 관한 메타데이터가 포함되어 있습니다.
- 모듈을 로드할 때 로드되는 모듈에 필요한 대로 외부 테이블의 URI 목록을 지정해야 합니다.
- 외부 테이블의 컨텐츠에 지원되는 형식은 헤더가 있는 하나의 CSV(.csv) 파일입니다.
다음 표에서는 create external table
명령문과 create table
명령문 사이의 차이점을 보여줍니다.
create external table |
create table |
---|---|
|
|
예
예제 1: 로드 시 채우는 외부 테이블 작성
allow_empty false
플래그 때문에 외부 테이블인 PersonNegativeClues는 로드 시 채워야 합니다.
module PersonModuleFrench;
create external table PersonNegativeClues (name Text)
allow_empty false;
export table PersonNegativeClues;
예제 2: 외부 테이블을 사용하여 사전 작성
사전은 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;
AQL Doc로 create external table
명령문 문서화
create external table
명령문의 AQL Doc 주석에는 다음 정보가 포함되어 있습니다.
- 테이블에 관한 일반 설명.
- 이 테이블의 스키마에 있는 모든 열 이름의 @field.
/** 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;
create external view
명령문
AQL의 create external view
명령문을 사용하여 텍스트 및 레이블 컨텐츠를 보유하는 사전 정의된 Document
뷰 외의 새로운 뷰로 문서에 관한 추가 메타데이터를 지정할 수 있습니다.
구문
create external view <view_name> (
<colname> <type> [, <colname> <type>]*
)
external_name '<view_external_name>';
설명
-
<view_name\>
외부 뷰의 내부 이름을 지정합니다. 외부 뷰는 AQL 규칙에서 이 이름으로 참조됩니다.
<view_name\>
은(는) 단순 ID 또는 큰따옴표로 묶인 ID일 수 있습니다.<view_name\>
에는 마침표 문자가 포함될 수 없습니다. -
<colname\>
외부 뷰에 정의할 열의 이름을 지정합니다.
-
<type\>
연관된 열의 데이터 유형을 지정합니다. 외부 뷰 열에 지원되는 데이터 유형은 Text, Span, Integer 및 Float입니다.
-
'<view_external_name\>'
외부 뷰의 외부 이름을 지정합니다. 외부 뷰에 튜플을 채우는 외부 시스템에서 외부 이름을 사용하여 외부 뷰를 참조합니다.
'<view_external_name\>'
은(는) 작은따옴표로 묶은 문자열 상수여야 합니다('ExternalName').
예
외부 뷰를 설명하기 위해 이메일 메시지에서 사용자의 이름을 식별해야 하는 예제 애플리케이션을 살펴보십시오.
예제 1: 이메일 메시지에서 사용자 이름 식별
이메일 메시지의 텍스트가 "Ena, please send me the document ASAP"이라고 가정하십시오. 사람은 이메일 텍스트를 기반으로 Ena가 사람의 이름임을 파악할 수 있지만, 일반 텍스트에서 정밀도가 높은 사용자의 이름을 식별하도록 작성된 AQL 규칙은 매우 조심스러우므로 Ena가 대문자로 표시된 단어라는 점을 기반으로 확신을 갖고 동일한 결론을 내리지 못할 수 있습니다.
규칙의 적용 범위를 높이는 한 방법으로 이메일의 보내는 사람, 받는 사람 및 참조 필드의 단어를 추가 근거로 사용할 수 있습니다.
이메일이 "Ena Smith"로 발송되고 애플리케이션에서 이 정보를 추출기에서 사용할 수 있게 하면 추출기 개발자가 이메일은 대개 사람에게 발송된다는 특정 분야의 지식을 기반으로 추출기의 적용 범위를 높이도록 추가 AQL 규칙을 작성할 수 있습니다.
예를 들어 이메일 메타데이터 필드에서 사용자 토큰을 식별하는 AQL 규칙을 작성할 수 있습니다. 그런 다음 이메일 텍스트에서 대문자로 표시된 토큰이 사람의 이름인지 결정할 때 이 정보를 강력한 단서로 사용할 수 있습니다. 일반적으로 이메일 메타데이터는 실제 이메일 메시지의 일부가 아니지만, 애플리케이션에서 외부 뷰를 사용하여 추출기에서 이 메타데이터를 사용할 수 있게 만들 수 있습니다.
즉, 런타임 시 처리해야 하는 각 이메일에 대해 애플리케이션에서 이메일 텍스트를 문서 텍스트로 전달할 수 있습니다(Document
뷰를 채우기 위함). 또한 적절하게 정의된 외부 뷰를 사용하여 추가 메타데이터도 전달할 수 있습니다.
다음 명령문에서는 EmailMetadata
라는 외부 뷰를 정의합니다. 외부 뷰에는 Text 유형의 세 필드를 포함하는 스키마가 있습니다. 런타임 시 EmailMetadata
뷰는 EmailMetadataSrc
라는 외부 유형에서 자동으로 채웁니다. 그런 다음 다른 뷰를 참조하는 방식과 비슷하게 AQL 규칙에서 EmailMetadata
뷰를 참조할 수 있습니다.
create external view EmailMetadata
(fromAddress Text, toAddress Text, ccAddress Text)
external_name 'EmailMetadataSrc';
AQL Doc로 create external view
명령문 문서화
create external view
명령문의 AQL Doc 주석에는 다음 정보가 포함되어 있습니다.
- 뷰에 관한 일반 설명.
- 뷰에 있는 모든 열 이름의 @field.
/**
* 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';
외부 아티팩트의 파일 형식
외부 뷰, 외부 사전 및 외부 테이블과 같은 세 가지 유형의 외부 아티팩트가 지원됩니다.
외부 사전
외부 사전의 항목을 포함하는 파일의 형식이 다음과 같이 정의되어 있습니다.
- 캐리지 리턴 구분 텍스트 파일입니다.
- 행별 하나의 사전 항목.
- 권장되는 파일 확장자는 .dict이지만. 기타 파일 확장자도 지원할 수 있습니다.
- 사전의 항목은 여러 개의 토큰으로 구성될 수 있습니다.
- 주석은 주석의 컨텐츠 앞에
#
을 붙여 지정할 수 있습니다. - 주석은 행의 임의의 위치에서 시작할 수 있습니다.
- 다중 행 주석에서는 각 행의 시작 부분에
#
문자가 있어야 합니다. - 백슬래시 문자로 각 주석 문자를 이스케이프 처리하는 경우 사전 항목에 주석 문자가 포함될 수 있습니다. 예를 들어,
\#
입니다.
외부 테이블
외부 테이블의 컨텐츠에 지원되는 형식은 헤더가 있는 .csv 파일입니다.
다음 예에서는 이 외부 테이블의 컨텐츠를 지정하는 .csv 파일과 create external table
명령문을 보여줍니다.
create external table Company2Location
(name Text, location Text)
allow_empty false;
.csv 파일의 첫 번째 행에는 헤더가 포함되어 있습니다. 나머지 행에는 데이터가 포함되어 있습니다.
name,location
IBM,USA
Infosys,India
LG,Korea
Vodafone,UK
외부 뷰
외부 뷰의 컨텐츠는 다음 방법으로 지정할 수 있습니다.
- 추출기를 실행할 때 JSON 입력 형식을 사용하는 경우에만 데이터 콜렉션의 외부 뷰 컨텐츠를 지정할 수 있습니다.
기본 제공 함수
AQL에는 추출 규칙에 사용할 수 있는 기본 제공 함수 콜렉션이 있습니다.
- 집계 함수 집계 함수는 입력 값 세트 전체에서 연산(예: 계수, 수학 연산 및 기타 연산)을 구현하는 데 사용됩니다. 이 함수에서는 하나의 결과만 리턴합니다.
- 술어 함수 술어 함수에서는 입력 인수를 대상으로 특정 술어를 테스트하고 해당 부울 값을 리턴합니다.
- 스칼라 함수 스칼라 함수에서는 입력 튜플 세트 전체에서 필드 값을 대상으로 연산을 수행하며 Span, Text 또는 Integer와 같이 부울 값이 아닌 값을 리턴합니다. 이러한 함수는
select
명령문 또는select
명령문의extract
목록에서 사용할 수 있습니다. 술어 함수에 대한 입력으로 사용할 수도 있습니다.
집계 함수
집계 함수는 입력 값 세트 전체에서 연산(예: 계수, 수학 연산 및 기타 연산)을 구현하는 데 사용됩니다. 이 함수에서는 하나의 결과만 리턴합니다.
이러한 함수는 select
명령문이 아니라 select
명령문의 extract
목록에서 사용할 수 있습니다.
다음 예는 집계 함수 호출의 일반 양식입니다.
Aggregate_Function_Name(argument)
argument
는 다음이 될 수 있습니다.
-
from
절에서 뷰의 열로 구성된 표현식 또는from
절에서 뷰의 열과 관련된 스칼라 함수의 조합.대부분의 경우 명시된 경우를 제외하고는 인수의 널값이 무시됩니다.
-
*
집계 함수와 같은 특수한 경우의Count(*)
문자.이 경우 널 값을 포함하여 출력의 모든 행이 계산됩니다.
집계 함수 | 인수 유형 | 리턴 유형 | 리턴 값 |
---|---|---|---|
Avg(표현식) | Integer, Float | 부동 소수점 | 모든 입력 값의 평균 또는 행을 선택하지 않은 경우 널 |
계수(*) | 정수 | 모든 입력 행의 수 | |
Count(표현식) | 임의 | 정수 | 널이 아닌 모든 입력 값의 수 |
List(표현식) | Integer, Float, Text, Span | 입력 인수와 동일한 유형의 스칼라 값 목록 | 널이 아닌 입력 값 목록(순서가 지정되지 않음): 세트가 아니라 bag이므로 중복 사항이 포함될 수 있습니다. 널 값만 선택한 경우 빈 목록 |
Max(표현식) | Integer, Float, Text, Span | 인수 유형과 동일 | 모든 입력 값의 최대 요소 또는 행을 선택하지 않은 경우 널 |
Min(표현식) | Integer, Float, Text, Span | 인수 유형과 동일 | 모든 입력 값의 최소 요소 또는 행을 선택하지 않은 경우 널 |
Sum(표현식) | Integer, Float | 인수 유형과 동일 | 모든 입력 값의 합계 또는 행을 선택하지 않은 경우 널 |
현재 버전의 제한사항:
AQL의 현재 버전에서는 aggregate
함수 목록을 통해 스칼라 값을 작성하도록 지원합니다.
예
다음 예에서는 집계 함수를 통해 사용자 이름 어노테이션 수를 세거나 문서에서 식별된 각 성과 연관된 이름 세트를 계산하는 방법을 보여줍니다.
-- 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);
다음 예에서는 Min 및 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;
술어 함수
술어 함수에서는 입력 인수를 대상으로 특정 술어를 테스트하고 해당 Boolean 값을 리턴합니다.
술어 함수의 입력 인수에는 사전, 정규식 등 외에 기타 스칼라 또는 집계 함수의 리턴 값도 포함됩니다. 이러한 함수는 where
명령문의 select
절과 extract 명령문의 having
절에서 사용할 수 있습니다.
And
And
함수에서는 다양한 수의 Boolean 인수를 허용하고 모든 입력 인수에서 논리 AND
연산 결과를 리턴합니다.
AQL 최적화 프로그램에서는 논리 AND
연산의 일부로 이 함수에 대한 인수의 평가 순서를 최적화하지 않습니다. 입력이 null
이면 결과는 null
입니다.
다음 조회 형식을 고려하십시오.
select ...
from ...
where And(predicate1, predicate2);
결과적으로 AND
연산을 사용하는 조회 형식은 다음 양식의 동일한 조회보다 현저히 느리게 실행되는 경우가 많습니다.
select ...
from ...
where predicate1 and predicate2;
가능하면 이 함수 대신 SQL 스타일 및 키워드를 사용하십시오.
포함
Contains
함수에서는 다음 두 범위를 인수로 사용합니다.
Contains(<span1>, <span2>)
TRUE
에 span1
가 완전히 포함되면 이 함수에서 span2
를 리턴합니다. span2
가 span1
시작 시 또는 시작 이후에 시작되고 span1
종료 시 또는 종료 전에 끝나면 span2
가 완전히 포함됩니다. 인수 중 하나가 null
이면 함수에서
null
을 리턴합니다.
ContainsDict
ContainsDict
함수에서 범위 텍스트에 지정된 사전의 항목이 포함되는지 확인합니다. 이 함수에서는 사전, 선택적 플래그 스펙 및 평가할 범위를 인수로 허용합니다.
ContainsDict('<dictionary>', ['<flags>', ]<span>)
범위에 사전의 일치가 하나 이상 포함되어 있으면 ContainsDict
함수에서 TRUE
를 리턴합니다. 플래그는 Exact
또는 IgnoreCase
일 수 있습니다.
Exact
를 사용하면 사전의 각 용어를 대상으로 대소문자 구분 일치를 수행합니다.IgnoreCase
를 사용하면 사전의 각 용어를 대상으로 수행하는 일치에서 대소문자를 구분하지 않습니다.- 플래그가 지정되지 않은 경우 사전이 작성될 때 지정된 플래그를 기준으로 사전이 일치하는지 확인합니다. 작성 중에 플래그를 지정하지 않으면
IgnoreCase
플래그를 사용하여 일치하는지 확인합니다.
범위가 null
이면 함수에서 null
을 리턴합니다.
다음 예에서는 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);
사전은 항상 토큰 경계에서 평가됩니다. 예를 들어, 사전이 fish라는 용어로 구성되어 있으면 Let's go fishing! 텍스트에는 일치가 없습니다.
ContainsDicts
ContainsDicts
함수에서 범위 텍스트에 지정된 사전의 항목이 포함되는지 확인합니다. 이 함수에서는 두 개 이상의 사전, 선택적 플래그 스펙 및 평가할 범위를 인수로 허용합니다.
ContainsDicts('<dictionary>','<dictionary>','<dictionary>', ['<flags>', ]<span>)
지정된 사전 중 하나 이상의 일치가 범위에 하나 이상 포함되어 있으면 ContainsDicts
함수에서 TRUE
를 리턴합니다. 플래그는 Exact
또는 IgnoreCase
일 수 있습니다.
Exact
를 사용하면 사전의 각 용어를 대상으로 대소문자 구분 일치를 수행합니다.IgnoreCase
를 사용하면 사전의 각 용어를 대상으로 수행하는 일치에서 대소문자를 구분하지 않습니다.- 플래그가 지정되지 않은 경우 사전이 작성될 때 지정된 플래그를 기준으로 사전이 일치하는지 확인합니다. 작성 중에 플래그를 지정하지 않으면
IgnoreCase
플래그를 사용하여 일치하는지 확인합니다.
두 인수 모두가 널이면 함수에서 null
을 리턴합니다.
다음 예에서는 ContainsDicts
플래그를 포함한 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
ContainsRegex
함수에서는 범위의 텍스트가 지정된 정규식과 일치하는지 확인합니다. 이 함수에서는 일치시킬 정규식, 선택적 플래그 스펙 및 일치시킬 입력 범위를 허용합니다.
ContainsRegex(/<regular expression>/, ['<flags>', ]<span>)
개별 Java™ 문자열로 사용되는 범위의 텍스트에 하나 이상의 정규식 일치가 포함되어 있으면 이 함수에서 TRUE
를 리턴합니다. 범위가 null
이면 이 함수에서 null
을 리턴합니다. 선택적 플래그는 Java 정규식에서 사용하는 플래그와 비슷하게 일치하는 동작에 영향을 줍니다.
이 플래그 문자열은 |
를 구분 기호로 사용하고 하나 이상의 다음 플래그를 결합하여 형성됩니다.
- CANON_EQ
- CASE_INSENSITIVE
- DOTALL
- LITERAL
- MULTILINE
- UNICODE(CASE_INSENSITIVE가 없으면 의미 없음)
- UNIX_LINES
플래그 문자열의 예는 다음과 같습니다.
'UNICODE | CASE_INSENSITIVE'
ContainsRegex
를 통해 양측의 버전 번호 멘션과 함께 제품 이름을 식별하는 이 예제를 살펴보겠습니다. MatchesRegex
의 예와 달리, 버전 번호 일치는 regex
를 사용하여 엄격하게 식별되지 않지만 regex
와 비교하여 일치 여부를 확인하는 토큰이 포함된 제품 이름 멘션과 관련된 컨텍스트를 통해 식별됩니다.
-- dictionary of product names
create dictionary ProductNamesDict as
(
'IBM WebSphere Application Server',
'Microsoft Windows',
'Apple Mac OS',
'IBM Rational Application Developer',
'Apache HTTP Server',
'Eclipse',
'Google Android'
);
-- extract product names from input text
create view ProductNames as
extract
dictionary 'ProductNamesDict'
on D.text as name
from Document D;
-- gather context around product name mention
create view ProductNamesWithContext as
select
P.name as name,
LeftContext(P.name, 5) as leftctxt,
RightContext(P.name, 5) as rightctxt
from ProductNames P;
-- use a regex to identify products with version number mentions on either sides of the product mention
create view ProductsWithVersionNumbers as
(
select
P.name as productname,
P.leftctxt as productversion
from ProductNamesWithContext P
where ContainsRegex (/v\d((\.\d)+)?/, P.leftctxt)
)
union all
(
select
P.name as productname,
P.rightctxt as productversion
from ProductNamesWithContext P
where ContainsRegex (/v\d((\.\d)+)?/, P.rightctxt)
);
같음
Equals
함수에서는 다음과 같이 임의의 유형의 두 인수를 사용합니다.
Equals(<arg1>, <arg2>)
두 범위가 모두 동일한 오프셋에서 시작하고 끝나며 동일한 텍스트를 포함하면 동일한 것으로 간주됩니다. 두 인수 모두가 널이면 함수에서 null
을 리턴합니다.
다음 예에서는 Equals
함수의 사용을 보여줍니다.
-- Select phone number spans whose text is equal to 001-543-2217
create view PhoneNumber as
select P.number as number
from PhoneNum P
where Equals('001-543-2217',GetText(P.number));
Follows
Follows
술어 함수에서는 다음과 같이 두 개의 범위 인수와 두 개의 정수 인수를 사용합니다.
Follows(<span1>, <span2>, <minchar>, <maxchar>)
TRUE
의 끝과 span1
의 시작 사이에 있는 문자 수가 span2
와 minchar
(둘 다 포함) 사이에 있으면 이 함수에서 maxchar
를 리턴합니다. 임의의 인수가 null
이면 함수에서 null
을 리턴합니다.
FollowsTok
FollowsTok
술어 함수는 Follows
의 버전입니다. 그러나 FollowsTok
거리 인수는 문자가 아니라 토큰과 관련됩니다.
FollowsTok(<span1>, <span2>, <mintok>, <maxtok>)
FollowsTok
의 끝과 TRUE
의 시작 사이에 있는 토큰 수가 span1
와 span2
(둘 다 포함) 사이에 있으면 mintok
함수에서 maxtok
를 리턴합니다. 임의의 인수가 null
이면 함수에서 null
을 리턴합니다.
GreaterThan
GreaterThan
술어 함수에서는 다음과 같이 임의의 유형의 두 인수를 사용합니다.
GreaterThan(<arg1>, <arg2>)
<arg1>
이(가) <arg2>
보다 큰 경우 함수는 TRUE
을(를) 리턴합니다. 두 인수 중 하나가 FALSE
이면 함수에서 null
를 리턴합니다.
널임
IsNull
함수에서는 데이터가 널인지 아니면 널이 아닌지 테스트합니다. 임의의 유형의 단일 인수를 받아, 단일 인수가 TRUE
이면 null
를 리턴하고 그렇지 않으면 FALSE
를 리턴합니다. 이 술어의 동작과 이미 정의된 NotNull
술어의 동작은 널 입력 시 널을 리턴하는 다른 모든 술어와 다릅니다.
MatchesDict
MatchesDict
함수에서는 사전(사전 추출에 있는 그대로), 선택적 플래그 스펙 및 범위를 인수로 사용합니다.
MatchesDict('<dictionary>', ['<flags>', ]<span>)
범위가 사전에 있는 하나 이상의 용어와 정확히 일치하면 MatchesDict
함수에서 TRUE
를 리턴합니다. 플래그는 Exact
또는 IgnoreCase
일 수 있습니다.
Exact
를 사용하면 사전의 각 용어를 대상으로 대소문자 구분 일치를 수행합니다.IgnoreCase
를 사용하면 사전의 각 용어를 대상으로 수행하는 일치에서 대소문자를 구분하지 않습니다.- 플래그가 지정되지 않은 경우 사전이 작성될 때 지정된 플래그를 기준으로 사전이 일치하는지 확인합니다. 작성 중에 플래그를 지정하지 않으면
IgnoreCase
플래그를 사용하여 일치하는지 확인합니다.
임의의 인수가 null
이면 함수에서 null
을 리턴합니다.
사전은 항상 토큰 경계에서 평가됩니다. 예를 들어, 사전이 fish라는 용어로 구성되어 있으면 Let's go fishing! 텍스트에는 일치가 없습니다.
MatchesRegex
MatchesRegex
함수에는 ContainsRegex
와 유사한 구문이 있습니다. ContainsRegex
함수와 달리 MatchesRegex
함수에서는 개별 java 문자열로 사용되는 범위의 전체 텍스트가 정규식과 일치하는 경우에만 TRUE
를 리턴합니다. 임의의 인수가 null
이면 함수에서
null
을 리턴합니다. 선택적 플래그는 Java 정규식에서 사용하는 플래그와 비슷하게 일치하는 동작에 영향을 줍니다.
MatchesRegex(/<regular expression>/, ['<flags>', ]<span>)
이 플래그 문자열은 |
를 구분 기호로 사용하고 해당 플래그의 서브세트를 결합하여 형성됩니다.
- CANON_EQ
- CASE_INSENSITIVE
- DOTALL
- LITERAL
- MULTILINE
- UNICODE(CASE_INSENSITIVE가 없으면 의미 없음)
- UNIX_LINES
플래그 문자열의 예는 다음과 같습니다.
'UNICODE | CASE_INSENSITIVE'
MatchesRegex
를 사용하여 오른쪽의 버전 번호 멘션과 함께 제품 이름을 식별하는 이 예제를 살펴보겠습니다. ContainsRegex
섹션의 예와 달리 제품 이름 멘션 바로 다음에 토큰으로 정확한 버전 번호가 식별됩니다.
-- 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
함수에서는 단일 Boolean 인수를 받고 보수를 리턴합니다. 인수가 null
이면 함수에서 null
을 리턴합니다.
널(Null)값이 아님
NotNull
함수에서는 임의의 유형의 단일 인수를 사용합니다.
이름에서 알 수 있듯이 NotNull
함수에서는 인수 값이 널이 아니면 TRUE
를 리턴하고 인수가 FALSE
이면 null
를 리턴합니다.
Or
Or
함수에서는 다양한 수의 널이 아닌 Boolean 인수를 사용합니다. 임의의 인수가 null
이면 함수에서 null
을 리턴합니다.
Or
함수에서는 인수가 TRUE
로 평가되면 TRUE
를 리턴합니다.
겹침
Overlaps
함수에서는 다음 두 범위 인수를 사용합니다.
Overlaps(<span1>, <span2>)
두 입력 범위가 문서 텍스트에서 겹치면 이 함수에서 TRUE
를 리턴합니다. 두 인수 중 하나가 null
이면 함수에서 null
을 리턴합니다.
스칼라 함수
스칼라 함수에서는 입력 튜플 세트 전체에서 필드 값을 대상으로 연산을 수행하며 Span, Text 또는 Integer와 같은 Boolean이 아닌 값을 리턴합니다. 이러한 함수는 select
명령문 또는 select
명령문의 extract
목록에서 사용할 수 있습니다. 술어 함수에 대한 입력으로 사용할 수도 있습니다.
Span 오브젝트가 필요한 상황에서 Text 오브젝트를 제공하면 Text 오브젝트의 전체 길이를 포함하는 시작 및 종료 오프셋을 사용하여 이 Text 오브젝트를 기반으로 변환된 Span 오브젝트가 자동으로 생성됩니다.
Text 오브젝트가 필요한 상황에서 Span 오브젝트가 제공되면 Span 오브젝트의 텍스트 값에서 변환된 Text 오브젝트가 자동으로 생성됩니다.
Chomp
Chomp
함수는 Perl의 Chomp
연산자와 비슷합니다. 단, Chomp
는 문자열이 아니라 범위를 대상으로 연산합니다.
Chomp(<span1>)
다음 예에서는 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;
입력 범위의 시작 또는 끝에 공백이 포함되어 있으면 Chomp
함수에서 공백을 제거할 정도로 충분히 범위를 줄입니다. 그런 다음 이 함수에서 선행 또는 후행 공백이 없는 새 범위를 리턴합니다. 입력 범위에 선행 또는 후행 공백이 없으면 Chomp
함수에서 동일한 범위를 리턴합니다. 입력 범위가 null
이면 Chomp에서 null
을 리턴합니다.
CombineSpans
CombineSpans
함수에서는 두 개의 범위를 입력으로 받아 범위가 동일한 텍스트 오브젝트를 기반으로 하는 경우 두 입력 범위를 완전히 포함하는 가장 짧은 범위를 리턴합니다.
CombineSpans(['IgnoreOrder',] <span1>, <span2>)
IgnoreOrder 매개변수를 사용하지 않으면 CombineSpans
함수에서 입력 범위 순서가 중요합니다. 선택적 IgnoreOrder 매개변수를 사용하면 두 범위의 순서를 무시합니다.
다음 예에서는 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);
함수의 시맨틱은 다음과 같습니다.
span1
또는span2
가null
이거나 두 범위가 서로 다른 Text 오브젝트에 걸쳐 있으면 함수에서null
을 리턴합니다.- 또는,
span1
이span2
보다 작거나IgnoreOrder
매개변수를 사용하는 경우 함수에서 두span1
및span2
를 모두 포함하는 가장 짧은 범위를 리턴합니다. - 또는, (
span1
이span2
보다 크고IgnoreOrder
를 사용하지 않으면), 함수에서 런타임 오류를 리턴합니다.
Span의 정의를 기반으로 CombineSpans
함수의 인수에 관한 다양한 시나리오가 있습니다.
-
Span 2는 항상 span 1 이후입니다. 즉, 왼쪽에서 오른쪽 순서가 유지됩니다.
CombineSpans([0,7], [3,7]) returns the span [0,7] CombineSpans([0,7], [8,10]) returns the span [0,10] CombineSpans([0,7], [3,6]) returns the span [0,7] CombineSpans([0,7], [0,7]) returns the span [0,7]
-
Span 2는 span 1 이후가 아닙니다. 즉, 왼쪽에서 오른쪽 순서는 유지되지 않습니다.
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 및 GetEnd
GetBegin
함수에서는 단일 범위 인수를 받아 출력 범위의 시작 오프셋을 리턴합니다.
예를 들면 다음과 같습니다.
GetBegin([5, 10])
5
값을 리턴합니다.
마찬가지로 GetEnd
함수에서는 출력 범위의 종료 오프셋을 리턴합니다.
다음 예에서는 GetBegin
및 GetEnd
함수의 사용을 보여줍니다.
create view PersonOffsets as
select GetBegin(P.name) as offsetBegin, GetEnd(P.name) as offsetEnd
from Person P;
이 두 함수 모두에서 인수가 null
이면 함수에서 null
을 리턴합니다.
GetLanguage
GetLanguage
함수에서는 단일 범위 인수를 받아 범위 소스 텍스트의 두 자로 된 언어 코드를 리턴합니다. 인수가 null
이면 함수에서 null
을 리턴합니다.
이 명령문에서는 데이터 소스가 적절한 언어로 텍스트 필드에 태그를 지정하는 경우에만 의미있는 결과를 생성합니다.
GetLemma
GetLemma
함수에서는 단일 Span 또는 Text 오브젝트를 인수로 받아 표제어 추출된 양식의 입력 범위를 포함하는 문자열을 리턴합니다. 인수가 null
이면 함수에서 null
을 리턴합니다. 기본형 일치를 위한 사전 항목의 경우 이 함수를 통해 토크나이저에서 리턴하는 다양한 토큰의 표제어 추출 양식을 판별할 수 있습니다. 예를 들어 went shopping
GetLemma 범위에서는 기본형 문자열 go shop
을 리턴합니다.
이 함수의 결과는 다음 규칙을 따릅니다.
- 입력 범위가 토큰의 시작 부분에서 시작하고 토큰의 끝에서 끝나는 경우 결과에는 첫 번째 토큰의 보조정리로 시작하여 공백이 오고 두 번째 토큰의 보조정리가 오고 뒤에 공백이 오는 식의 보조정리 시퀀스가 포함됩니다(예: dog cat fish bird ...). 토큰의 기본형이 공백으로 구성되면 백슬래시 문자(\)를 사용하여 공백을 이스케이프 처리하십시오.
- 입력 범위가 공백으로 시작되거나 끝나면(예: 두 토큰 사이에서 시작하고 두 토큰 사이에서 끝남) 함수에서 선행 및 후행 공백을 무시합니다.
- 입력 범위가 토큰의 중간에서 시작되거나 토큰의 중간에서 끝나면 출력은 다음 컨텐츠를 순서대로 공백으로 구분하여 구성됩니다.
- 첫 번째 부분 토큰의 표층형(있는 경우)
- 첫 번째부터 마지막까지 완전한 토큰에 해당하는 일련의 기본형. 전체 토큰의 기본형이 공백으로 구성되면 백슬래시 문자(\)를 사용하여 공백을 이스케이프 처리하십시오.
- 마지막 부분 토큰의 표층형(있는 경우)
사용 중인 토크나이저에서 기본형을 생성할 수 없으면 이 함수에서 오류를 리턴합니다.
GetLemma()
함수를 사용하여 표제어 추출된 양식의 사전을 작성할 수 있습니다. 사전에 포함할 표제어 추출 양식이 있는 용어를 포함하는 입력에서 GetLemma()
를 호출하십시오.
GetLength
GetLength
함수에서는 단일 범위 인수를 받아 입력 범위의 길이를 리턴합니다. 인수가 null
이면 함수에서 null
을 리턴합니다.
예를 들면 다음과 같습니다.
GetLength([5, 12])
값 7을 리턴합니다.
GetLengthTok
GetLengthTok
함수에서는 단일 범위 인수를 받아 토큰에 있는 입력 범위의 길이를 리턴합니다. 입력 인수가 null
이면 함수에서 null
을 리턴합니다.
GetString
GetString
함수에서 단일 AQL 오브젝트를 인수로 사용하여 오브젝트의 문자열 표시에서 형성된 Text 오브젝트를 리턴합니다.
범위 및 텍스트 인수의 경우 리턴되는 값은 GetText()
에서 리턴하는 값과 다릅니다. Text 오브젝트의 경우 리턴된 값에는 텍스트 문자열을 둘러싼 작은따옴표가 포함됩니다. Span 오브젝트의 경우 리턴된 값에는 대괄호로 묶은 오프셋도 포함됩니다.
스칼라 목록의 경우 이 함수에서는 세미콜론으로 연결된 목록 요소의 GetString()
값을 리턴합니다. Integer, Float, Boolean 및 String 인수의 경우 이 함수에서는 인수 값을 문자열로 리턴합니다. null
인수의 경우 이 함수에서는 null
을 리턴합니다.
GetText
GetText
함수에서는 단일 범위 또는 텍스트를 인수로 사용합니다. 범위 입력의 경우 범위가 표시하는 실제 텍스트 문자열을 기반으로 텍스트 오브젝트를 리턴합니다. 텍스트 입력의 경우 입력 텍스트 오브젝트를 리턴합니다. 입력이 null
이면 이 함수에서 null
을 리턴합니다. 예를 들면 다음과 같습니다.
GetText([5, 12])
범위에서 5 - 12 문자 위치에서 문서의 하위 문자열을 리턴합니다.
GetText
함수의 주된 용도는 두 가지가 있습니다.
두 범위로 표시된 텍스트 사이의 문자열 동일성 테스트
-- 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;
문서를 작은 하위 문서로 분할.
예를 들어 기본 문서가 여러 블로그 항목으로 구성된 블로그이면 GetText를 사용하여 각 블로그 항목의 하위 문서를 작성할 수 있습니다.
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 및 RightContext
LeftContext
함수에서는 Span과 Integer를 입력으로 사용합니다.
LeftContext(<input span>, <nchars>)
LeftContext(<input span\>, <nchars\>)
함수는 <input span\>
의 왼쪽에 있는 문서의 nchars 문자를 포함하는 새 범위를 리턴합니다. 입력 범위가 문서 처음부터 <nchars\>
문자 미만으로 시작하는 경우, LeftContext()
은(는) 문서의 시작
부분에서 시작하여 입력 범위의 시작까지 계속되는 범위를 리턴합니다.
예를 들어, LeftContext([20, 30], 10)은 [10, 20] 범위를 리턴합니다. LeftContext([5, 10], 10) 범위는 [0, 5]를 리턴합니다.
입력이 문서의 첫 번째 문자에서 시작되면 LeftContext()
가 길이가 0인 범위를 리턴합니다. 마찬가지로 RightContext
함수에서는 입력 범위 오른쪽에 있는 텍스트를 리턴합니다. 두 함수 모두에서 인수 중 하나가 null
이면 함수에서 null
을 리턴합니다.
LeftContextTok 및 RightContextTok
LeftContextTok
및 RightContextTok
함수는 토큰과의 거리를 사용하는 LeftContext
및 RightContext
의 버전입니다.
LeftContextTok(<input span>, <num tokens>)
RightContextTok(<input span>, <num tokens>)
다음 예에서는 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;
두 함수 모두에서 인수 중 하나가 null
이면 함수에서 null
을 리턴합니다.
재맵핑
Remap
함수에서는 단일 범위 인수를 사용합니다.
Remap(<span>)
입력 범위가 다른 텍스트 오브젝트를 변환하여 생성된 텍스트 오브젝트를 포함하면 Remap
함수에서 범위를 원래 "source" 텍스트를 초과하여 포함하는 범위로 변환합니다.
예를 들어 N.name
범위가 detag
명령문을 통해 HTML을 실행하여 생성된 태그 해제된 문서를 포함하는 경우
Remap(<N.name>)
원래 HTML을 초과하여 포함하는 해당 범위를 리턴합니다.
비어 있는 문서를 대상으로 detag
명령문을 실행하여 범위 인수를 생성한 경우 함수에서 범위를 문서의 시작 부분(즉, Document.text[0-0])으로 다시 맵핑합니다. 또한 detag
명령문에서 비어 있는 문자열을 생성하는 경우 함수에서 범위를 문서의 시작 부분에 다시 맵핑합니다. 이러한 파생 텍스트 오브젝트를 생성하는 AQL의 부분은 detag
명령문뿐입니다.
다음 예에서는 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;
Remap의 인수가 파생된 텍스트 오브젝트 또는 파생된 텍스트 오브젝트를 초과하여 포함하는 범위가 아니면 함수에서 오류를 생성합니다. 인수가 null
이면 함수에서 null
을 리턴합니다.
SpanBetween
SpanBetween
함수에서는 두 범위를 입력으로 받아, 범위가 동일한 텍스트 오브젝트를 기반으로 하는 경우 두 범위 사이의 텍스트를 정확히 포함하는 범위를 리턴하고 다른 텍스트 오브젝트를 기반으로 하는 경우 null
을 리턴합니다.
SpanBetween(['IgnoreOrder',] <span1>, <span2>)
선택적 IgnoreOrder
매개변수를 사용하면 AQL 컴파일러에서 두 범위의 순서를 무시합니다.
두 개의 범위 사이에 텍스트가 없는 경우, SpanBetween
은(는) <span1>
의 끝에서 시작하는 빈 범위를 리턴합니다.
CombineSpans
과(와) 같이 IgnoreOrder
매개변수를 사용하지 않는 한 SpanBetween
에서는 입력 순서에 민감합니다. 따라서
SpanBetween([5, 10], [50, 60])
[10, 50]
범위를 리턴하는 반면
SpanBetween([50, 60], [5, 10])
[60, 60]
범위를 리턴합니다.
SpanBetween
의 인수가 null
이면 함수에서 null
을 리턴합니다.
SpanIntersection
SpanIntersection
함수에서는 두 범위를 입력으로 받아, 범위가 동일한 텍스트 오브젝트를 기반으로 하는 경우 두 입력 모두에 있는 텍스트를 포함하는 범위를 리턴하고 다른 텍스트 오브젝트를 기반으로 하는 경우 null
을 리턴합니다.
SpanIntersection(<span1>, <span2>)
예를 들면 다음과 같습니다.
SpanIntersection([5, 20], [10, 60])
[10, 20]
범위를 리턴하는 반면
SpanIntersection([5, 20], [7, 10])
[7, 10]
범위를 리턴합니다.
두 범위가 겹치지 않으면 SpanIntersection에서 null
을 리턴합니다. 범위 입력 중 하나가 null
이면 함수에서 null
을 리턴합니다.
SubSpanTok
SubSpanTok
함수에서 범위와 범위의 오프셋 쌍을 입력으로 사용합니다.
SubSpanTok(<span>, <first_tok>, <last_tok>)
함수의 이름이 제안하는 대로, <first_tok>
및 <last_tok>
인수는 시스템이 사용하도록 구성된 토큰화에 따라 토큰의 거리입니다.
SubSpanTok
함수에서는 입력 범위에서 표시된 범위(포함)의 토큰을 포함하는 새 범위를 리턴합니다. 지정된 영역이 범위 내에서 시작하고 범위 끝을 넘어 이어지면 포함된 영역 부분이 리턴됩니다. <first_tok>
이(가) 목표 범위를 벗어난 거리를 나타내는 경우, SubSpanTok은 입력 범위의 시작 부분에서 시작하는 길이가 0인 범위를 리턴합니다.
임의의 입력이 null
이면 함수에서 null
을 리턴합니다.
ToLowerCase
ToLowerCase
함수에서 단일 오브젝트를 인수로 받아 오브젝트의 소문자 문자열을 리턴합니다. 문자열로 변환은 GetString()
함수가 변환을 수행하는 것과 동일한 방식으로 수행됩니다.
이 함수는 대소문자를 구분하지 않는 동등 조인을 수행하는 데 주로 사용합니다.
where Equals(ToLowerCase(C.company), ToLowerCase(N2C.name))
입력 오브젝트가 null
이면 함수에서 null
을 리턴합니다.
create function
명령문
AQL에서 지원하지 않는 추출된 값에 대해 연산을 수행하기 위해 사용자 정의 함수(UDF)라는 추출 규칙에서 사용할 사용자 정의 함수를 정의할 수 있습니다.
AQL에서는 사용자 정의 스칼라 함수 및 사용자 정의 테이블 함수를 지원합니다. Java™ 및 PMML이 UDF에 지원되는 유일한 구현 언어입니다. 스칼라 함수에서는 단일 스칼라 값을 리턴하며, 테이블 함수에서 하나 이상의 튜플, 즉 테이블을 리턴합니다.
다음 네 단계를 수행하여 사용자 정의 함수(UDF)를 구현합니다.
-
함수 구현
AQL에서는 Java 또는 PMML로 구현되는 사용자 정의 함수(UDF)를 지원합니다.
-
AQL에서 선언.
create function
명령문을 사용하여 PMML 파일의 사용자 정의 스칼라 함수 및 기계 학습 모델을 AQL에서 사용할 수 있게 할 수 있습니다. -
AQL에서 사용.
사용자 정의 함수는 AQL 명령문 및 절과 함께 작동합니다.
-
UDF 디버깅.
Java 기반 사용자 정의 함수(UDF)는 Java 클래스의 public 메소드로 구현되므로 Java 프로그램을 디버깅할 때와 동일한 방식으로 UDF를 디버깅합니다.
사용자 정의 함수 구현
AQL에서는 Java™ 또는 PMML로 구현되는 사용자 정의 함수(UDF)를 지원합니다.
이 섹션에서는 특히 Java로 구현된 UDF에 중점을 둡니다. PMML로 구현된 UDF의 경우, 기계 학습 모델이 PMML XML 파일에 저장됩니다. 다음 모델을 작성하는 방법은 PMML 문서를 참조하십시오. [http://dmg.org/pmml/v4-1/GeneralStructure.html]
Java 클래스의 public 메소드로 스칼라 UDF를 구현할 수 있습니다. API com.ibm.avatar.api.udf.TableUDFBase를 확장하는 Java 클래스의 public 메소드로 테이블 UDF를 구현할 수 있습니다. 또한 테이블 UDF는 수퍼클래스 com.ibm.avatar.api.udf.TableUDFBase의 initState()
메소드를 선택적으로 대체할 수 있습니다.
UDF에 Span, Text 또는 ScalarList 유형의 입력 매개변수가 있거나 UDF의 리턴 유형이 Span, Text 또는 ScalarList이면 Java 클래스에서 컴파일하기 위해 com.ibm.avatar.algebra.datamodel.Span, com.ibm.avatar.algebra.datamodel.Text 또는 com.ibm.avatar.algebra.datamodel.ScalarList 클래스를 가져와야 합니다.
출력 스키마 정보를 제공하려면 테이블 함수에 추가 API가 필요합니다. 이 API는 기본 클래스 com.ibm.systemt.api.udf.TableUDFbase에 속합니다. 서브클래스에 두 개 이상의 테이블 함수가 포함되어 있으면 인스턴스마다 개별 Java 오브젝트가 작성됩니다.
JAR 파일에서 비클래스 리소스를 검색하는 UDF 코드의 경우 getResourceAsStream()
메소드만 지원됩니다. 리소스(예: getResource()
, getResources()
, getSystemResource()
)에 액세스하는 데 필요한 다른 메소드는 지원되지 않습니다. 예를 들어 package com.ibm.myproject.udfs
패키지의 my.properties 특성 파일을 포함하는 UDF JAR 파일은 다음 Java 명령문으로 액세스할 수 있습니다.
InputStream in = this.getClass().getClassLoader().
getResourceAsStream(“com/ibm/myproject/udfs/my.properties”);
Java로 구현된 UDF의 라이프사이클
AQL에서 create function 명령문마다 정확히 한 번만 추출기가 컴파일(CompileAQL.compile()
API), 인스턴스화(OperatorGraph.createOG()
API) 및 유효성 검증(OperatorGraph.validateOG()
API)되면 다음 오퍼레이션이 수행됩니다.
- 완전히 새로운 클래스 로더를 사용하여 UDF 메소드를 포함하는 Java 클래스를 로드하십시오. 해당 create function 명령문에 지정된 UDF JAR에서 이 클래스를 검색합니다. 이 클래스를 로드할 때 필요한 다른 모든 클래스도 동일한 UDF JAR에서 검색합니다. 발견하지 않으면 런타임을 인스턴스화한 클래스 로더로 검색이 위임됩니다.
- 해당 클래스의 인스턴스를 작성하십시오.
- 테이블 UDF의 경우 메소드
initState()
를 호출하십시오.
create function 명령문마다 이러한 단계를 수행하므로, Java 클래스에 여러 UDF 메소드가 포함되어 있으면(그리고 모든 메소드가 다른 create function 명령문의 AQL에서 사용되면) 클래스가 여러 번 로드되며, 매번 다른 클래스 로더에서 로드됩니다(1단계). 또한 클래스의 여러 인스턴스가 작성되며(2단계) 인스턴스마다 initState()
메소드가 한 번 호출됩니다(3단계).
모든 UDF에서 개별 클래스 로더를 생성하는 이유는 서로 다른 UDF에서 동일한 클래스(또는 라이브러리)의 여러 다른 버전을 사용하도록 허용하기 위해서입니다.
런타임 시(OperatorGraph.execute()
API), 클래스가 추출기 인스턴스화 중에 로드되었으므로 UDF 클래스가 다시 로드되지 않습니다. UDF를 구현하는 Java 메소드는 출력을 계산하기 위해 필요할 때 호출됩니다. 추출기가 단일 스레드 내에서 사용되면, 각 입력 문서에 대해 0개부터 많은 수까지 임의의 수의 호출이 있을 수 있습니다(또한 연산자 그래프 오브젝트의 수명 전체에서 다중 호출이
있을 가능성이 큼). 추출기가 여러 스레드에서 공유되면 이 서로 다른 스레드가 거의 동일한 시간에(서로 다른 입력을 사용하여) 메소드를 사용할 수 있습니다.
예를 들어, 호출 전체에서 UDF 메소드에 필요한 데이터 구조를 초기화하기 위해 UDF 코드의 특정 부분을 한 번만 평가해야 하는 경우, 해당 메소드는 추출기의 수명 전체에서 여러 번 실행될 가능성이 크며(예: OperatorGraph 오브젝트) 추출기를 여러 스레드에서 공유하면 거의 동시에 사용할 수 있으므로 해당 코드를 UDF 평가 메소드에 두지 않아야 합니다. 대신 다음을 수행하십시오.
- 스칼라 UDF의 경우 표준 Java 프로그래밍 원칙을 따르십시오. 예를 들어 정적 블록에 코드를 두십시오.
- 테이블 UDF의 경우 코드를
initState()
메소드에 두거나 표준 Java 프로그래밍 원칙을 따르십시오. 예를 들어 정적 블록에 코드를 두십시오.
이 작업을 수행할 때 위의 1 - 3단계에 설명된 대로 추출기 컴파일, 인스턴스화 및 유효성 검증 중에 클래스를 여러 번 로드할 수 있다는 점을 기억하십시오. UDF를 초기화하는 코드를 정적 블록에 두면 클래스를 로드할 때마다 코드가 실행되므로(잠재적으로 여러 번) 컴파일 및 연산자 그래프 인스턴스화 중에 오버헤드가 발생할 수 있습니다. 오버헤드가 크면 다음 우수 사례를 따르십시오.
- 컴파일 중에 오버헤드를 최소화하려면 초기화 시간이 긴 UDF나 대규모 사전과 같이 컴파일 시간이 오래 걸리는 리소스를 별도의 AQL 모듈에 두고 내보내는 것이 좋습니다. 변경된 AQL 모듈과 이 모듈에 종속된 기타 모듈만 컴파일하십시오.
- 연산자 그래프 인스턴스화 및 유효성 검증 중에 오버헤드를 최소화하려면 다음을 수행하십시오.
- 단일 UDF 메소드에 초기화 코드가 필요하면 UDF 메소드를 개별 Java 클래스에 두십시오(또한 이전과 같이 대규모 인스턴스화 코드를 정적 초기자에 두거나 코드를 한 번만 실행하는 기타 메커니즘 사용).
- 여러 UDF 메소드에서 초기화 코드를 공유하면 런타임 및 AQL에서 초기화 코드를 한 번만 실행하도록 하는 명시적 메커니즘을 제공하지 않습니다. 이러한 경우 초기화 시간이 엄청나게 많이 소요되므로 시스템 클래스 경로에 공유 리소스와 초기화 코드를 두는 것이 유일한 솔루션입니다. 즉, 초기화 코드는 새 클래스 MySeparateClass.java에 두고 초기화 결과는 이 클래스의 정적 변수(예: MySeparateClass.myVar)에 저장합니다. 초기화하는 동안 필요한 모든 리소스와 함께 MySeparateClass.java를 JAR 파일로 패키징하고 이 JAR을 시스템 클래스 경로에 두십시오. UDF 메소드에서는 MySeparateClass.myVar 정적 변수를 사용하여 초기화된 모델을 참조할 수 있습니다. 이제 초기화 코드는 시스템 클래스 로더에서 MySeparateClass.java 클래스를 로드할 때 정확히 한 번 실행됩니다.
팁:
모듈의 컴파일된 표시.tam
파일)에는 UDF의 직렬화된 2진 코드가 포함되어 있습니다. 따라서 서로 다른 두 모듈에서 create function
명령문을 통해 동일한 UDF 코드를 참조하는 경우 UDF 코드가 두 모듈의 컴파일된 표시에서 직렬화됩니다. 즉, UDF 코드가 두 번 직렬화됩니다. 이 경우 UDF의 라이브러리 역할을 하는 개별 모듈을 작성하여 중복을 피하고 해당 라이브러리를
다른 모듈에서 재사용할 수 있습니다. UDF 라이브러리를 작성하려면 다음 단계를 따르십시오.
- 한 모듈을 작성하십시오.
- 해당 모듈에 모든 UDF JAR 파일을 두십시오.
create function
명령문을 사용하여 필요한 모든 함수를 정의하십시오.- 가져온 후 다른 모듈에서 사용할 수 있도록
export function
명령문을 사용하여 모두 내보내십시오.
예
예제 1: 스칼라 UDF 구현
이 예에서는 toUpperCase라는 스칼라 UDF의 구현을 보여줍니다. 이 UDF에서는 Span 유형의 값을 입력으로 받아서 Span 입력의 텍스트 컨텐츠로 구성된 문자열 값을 대문자로 변환하여 출력합니다.
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();
}
예제 2: 테이블을 입력으로 사용하는 스칼라 UDF 구현
이 예에서는 TableConsumingScalarFunc라는 스칼라 UDF의 구현을 보여줍니다. 이 UDF에서는 두 튜플 목록을 입력으로 받아서 두 입력 튜플 목록의 컨텐츠를 연결하는 문자열 값을 출력합니다.
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 ();
}
}
예제 3: 테이블을 입력으로 사용하는 테이블 UDF 구현
이 예에서는 TableConsumingTableFunc라는 테이블 UDF의 구현을 보여줍니다. 이 UDF에서는 두 개의 튜플 목록을 입력으로 받아 두 번째 입력의 튜플과 함께 배치된 첫 번째 입력의 튜플을 포함하는 단일 튜플 목록을 출력합니다. 입력과 출력 스키마를 확보하는 API를 제공하는 기본 클래스 com.ibm.avatar.api.udf.TableUDFBase에서 구현이 확장됩니다.
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)); }
}
}
}
사용자 정의 함수 선언
create function
명령문을 사용하여 PMML 파일의 사용자 정의 스칼라 함수 및 기계 학습 모델을 AQL에서 사용할 수 있게 할 수 있습니다.
구문
create function
명령문의 일반 구문은 다음과 같습니다.
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>]*
설명
-
<function-name\>
<function-name\>
은(는) UDF의 AQL 이름을 선언합니다. UDF는 이 이름으로 AQL 코드에서 참조됩니다. -
<input-schema-definition\>
UDF의 입력 매개변수를 지정합니다. 입력 매개변수에는
<column-name\>
(으)로 지정된 이름이 있으며 스칼라 유형 또는 테이블 로케이터일 수 있습니다. 언어가 PMML이면 함수는params
라는 단일 테이블을 인수로 사용해야 합니다. -
<column-name\>
UDF의 입력 또는 출력에 열의 이름을 지정합니다.
-
<data-type\>
UDF의 입력 스칼라 매개변수 유형, UDF 입력 테이블의 스키마에 있는 열 유형 또는 UDF 출력 테이블의 스키마에 있는 열 유형.
<data-type\>
의 가능한 값은 정수, Float, String, Text, Span, Boolean 또는 ScalarList입니다. -
table (<output-schema-definition\>) as locator
이 입력 유형을 사용하면 현재 문서에서 계산된 대로 지정된 AQL 뷰의 전체 컨텐츠를 입력으로 사용합니다. 위치 지정자 매개변수 참조 뷰 또는 테이블을 인수로 사용합니다.
-
<return-type\>
스칼라 UDF의 경우,
<return-type\>
은(는) UDF에서 리턴하는 스칼라 값의 유형을 지정합니다. 리턴 유형으로 가능한 값은 Integer, Float, String, Text, Span, Boolean 또는 ScalarList입니다. 리턴 유형이 Integer이면 UDF를 구현하는 Java™ 함수에서 Integer 유형의 오브젝트를 리턴합니다. UDF 구현에서는 원시 int 유형을 리턴하지 않습니다. 리턴 유형이 Text 또는 Span이면 리턴 유형이 파생되는 입력 매개변수를 지정하십시오. 범위는 항상 기본 열에서 시작되므로 스펙과 같은 선택사항을 사용하여 입력 매개변수를 지정할 수 있습니다. 리턴 유형이 ScalarList이면 ScalarList의 스칼라 유형을 추론할 입력 매개변수를 지정하십시오. 언어가 PMML이면 함수에서 테이블을 리턴해야 합니다. -
<output-schema-definition\>
테이블 UDF의 경우,
<output-schema-definition\>
은(는) 열 이름 및 해당 유형을 포함하여 UDF가 리턴하는 테이블의 출력 스키마를 지정합니다. -
<ext-name\>
external_name에서는 UDF의 구현을 찾을 위치를 지정합니다. 언어가 Java인 경우, 다음 세 부분으로 구성되는
'<jar-file-name\>:<fully-qualified-class-name\>!<method-name\>'
양식의 문자열입니다.- JAR 파일 이름: 모듈식 AQL을 컴파일할 때 UDF JAR 파일의 위치 참조는 참조가 작성되는 모듈의 루트에 상대적이어야 합니다.
- 클래스 이름: UDF 구현을 포함하는 완전한 클래스 이름
- 메소드 이름: 메소드는 클래스의 public 메소드여야 합니다. 메소드 서명은
create function
명령문에 지정된 매개변수 유형과 일치해야 합니다. 자동 유형 변환은 런타임 컴포넌트에서 수행하지 않습니다. 언어가 PMML이면 external_name 절을 통해 모듈의 루트 디렉토리에 상대적인 PMML 파일의 위치가 될 문자열을 지정합니다. 현재 구현에서는 PMML 표준 버전 4.1을 사용하여 표현된 모델을 지원하고 버전 1.0.22 org.jpmml 라이브러리를 사용하여 평가합니다.
-
language
언어 스펙은 UDF의 구현 언어를 나타냅니다. 런타임 컴포넌트에서는 Java™로 구현된 UDF만 지원합니다.
-
deterministic/not deterministic
선택적 deterministic/not deterministic에서는 함수의 stateless 여부를 지정합니다. deterministic 함수에서는 항상 동일한 입력 값 세트에 대해 동일한 값을 리턴합니다.
-
return null on null input
선택적 return null on null input에서는 하나 이상의 입력 값이 널일 경우 함수 동작을 지정합니다. return null on null input이 지정되면 시스템이 UDF를 호출하지 않고 널 입력 시
null
을 리턴합니다. called on null input이 지정되면 널 입력 값에도 UDF가 호출됩니다.
PMML에서 구현된 UDF의 사용법 참고사항
PMML 파일에서 작성된 함수는 params
라는 단일 테이블을 인수로 사용하여 테이블을 출력합니다. 함수 구현에서는 create function 명령문에 선언된 입력 및 출력 스키마와 PMML 파일에 지정된 스키마 사이의 입력 필드를 맵핑합니다. 즉, 모델에서 생성하고 사용하는 입력 및 출력 레코드에 표시할 수 있는 필드의 이름과 유형을 설명하는 DataDictionary 섹션, DataDictionary 섹션에 정의된 이름 지정된 파일 중 기능 벡터를 나타내는 각 튜플에 있는 파일을 나타내는 MiningSchema 섹션 및 DataDictionary 섹션에 정의된 이름 지정된 필드 중 모델 출력의 외부 표시를 나타내는 각 튜플에 있는 필드를 나타내는 Output 섹션입니다. 이 함수는 테이블 함수여야
합니다. 즉, 테이블의 각 행이 PMML 모델에 전달되고 출력 행을 생성합니다.
이 스키마 정보는 PMML및 AQL 유형 시스템이 완벽하게 일치하지 않기 때문에 필요합니다. 예를 들어, PMML에는 타임스탬프를 나타내는 여러 유형이 있는 반면, AQL에서는 현재 사용자가 타임스탬프를 문자열 값으로 인코딩해야 합니다. 스키마 정보가 있으면 AQL은 알지만 PMML은 모르는 개발자가 AQL 규칙 세트를 이해할 수 있습니다.
AQL 컴파일러는 두 스키마가 호환 가능한지 확인하기 위해 PMML 파일의 입력 스키마와 비교하여 입력 스키마를 검사합니다. 두 스키마에 이름은 같지만 유형은 호환되지 않는 필드가 있으면 컴파일에 실패하고 적절한 오류 메시지가 표시됩니다. 함수의 입력 또는 출력 스키마에 추가 또는 누락된 열이 포함되어 있으면 resulting
함수에서 이 열을 무시하고 오류를 생성하지 않습니다. 열 이름의 순서는 AQL
정의와 PMML 파일 간에 다를 수 있습니다. 열 이름이 입력과 출력 스키마에 모두 표시되지만 PMML 스키마에는 표시되지 않으면 해당 열의 값이 함수의 출력에 전달됩니다.
예
예제 1: Java를 사용하여 스칼라 값이 있는 스칼라 UDF를 입력으로 선언
다음 예에서는 create function
라는 함수를 선언하는 udfCombineSpans
명령문을 보여줍니다. 사용자 정의 함수에서는 두 범위를 입력으로 받아 첫 번째 입력 범위와 비슷한 병합된 범위를 리턴합니다. 실제 UDF Java™ 함수는 udfs.jar
디렉토리에 udfjars
라는 JAR 파일로 패키징됩니다. 함수를 구현하는
메소드는 combineSpans
클래스의 com.ibm.test.udfs.MiscScalarFunc
입니다. 이 메소드는 범위가 지정된 크기보다 큰 경우 udfSpanGreaterThan
를 리턴하는 true
함수도 선언합니다.
/**
* 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;
다음 예에서는 이름 목록인 nameList와 단일 이름인 myName이 제공된 udfCompareNames라는 함수를 선언하는 방법을 보여줍니다. 출력은 입력 목록과 비슷한 목록으로, 여기에는 myName과 비슷한 nameList의 항목만 포함됩니다.
/**
* 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;
예제 2: Java를 사용하여 테이블이 있는 스칼라 UDF를 입력으로 선언
다음 예에서는 table as locator
입력 유형의 사용을 보여줍니다. MyScalarFunc라는 함수를 선언하는 create function
명령문을 보여줍니다. UDF의 Java™ 구현은 com.ibm.test.udfs.TableConsumingScalarFunc 클래스에 패키징됩니다.
이 UDF에서는 두 튜플 목록을 입력으로 받아서 두 입력 튜플 목록의 컨텐츠를 연결하는 문자열 값을 출력합니다. UDF의 Java™ 구현은 사용자 정의 함수 구현에 포함되어 있습니다.
-- 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;
예제 3: Java를 사용하여 테이블 UDF 선언
다음 예에서는 return table
클래스의 사용을 보여줍니다. 이 예제에서는 MyScalarFunc라는 테이블 함수를 선언하는 create function
명령문을 보여줍니다. UDF의 Java™ 구현은 com.ibm.test.udfs.TableConsumingTableFunc 클래스에 패키징됩니다. 이 UDF에서는 두 개의 튜플 목록을 입력으로 받아 입력 목록을 하나로 병합하는
튜플 목록을 출력합니다. UDF의 Java™ 구현은 사용자 정의 함수 구현에 포함되어 있습니다.
-- 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;
예제 4: PMML에서 구현된 테이블 UDF 선언
다음 예에서는 PMML 언어를 사용하여 IrisDecisionTree라는 테이블 함수를 선언하는 create function
명령문을 보여줍니다. UDF의 PMML 구현은 IrisTree.xml 파일에 지정되며 다음 예에 표시되어 있습니다. IrisTree.xml에 저장된 모델은 의사결정 트리 모델입니다.
-- 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>
주석을 사용하여 create function
명령문 문서화
create function 명령문의 AQL Doc 주석에는 다음 정보가 포함되어 있습니다.
- 함수에 관한 일반적인 설명입니다.
- 함수에서 사용되는 각 매개변수 이름을 지정하는 @param 설명입니다. 스칼라 유형인지 아니면 테이블인지에 관계없이 매개변수의 유형을 표시합니다. 매개변수가 테이블이면 입력될 것으로 예상되는 테이블의 스키마에 표시되는 순서대로 정렬된 열 이름과 유형을 포함하여 테이블의 스키마를 설명하십시오.
- 함수에서 리턴한 정보를 지정하는 @return 설명입니다. 함수에서 테이블을 리턴하는 경우 출력 테이블의 스키마에 표시되는 순서대로 정렬된 열 이름과 유형을 포함하여 테이블의 출력 스키마를 지정하십시오.
/**
* 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;
사용자 정의 함수 사용
사용자 정의 함수는 AQL 명령문 및 절과 함께 작동합니다.
사용자 정의 함수는 기본 제공 함수와 비슷하게 AQL 명령문 및 절과 함께 작동합니다. 특히 스칼라 UDF는 select
및 where
와 같은 기본 제공 스칼라 함수와 동일한 방식으로 having
, group by
, order by
, GetBegin
및 LeftContext
절에서 사용할 수 있습니다. Boolean 유형을 리턴하는 사용자 정의 스칼라 함수는 where
및 having
절에서 술어로 사용할 수 있습니다.
사용자 정의 테이블 함수(테이블 UDF)는 from
명령문 또는 select
명령문의 extract
절에서 사용할 수 있습니다.
예
예제 1: 스칼라 값을 입력으로 사용하여 Java로 구현된 스칼라 UDF 사용
이 예제에서는 udfCombineSpans
사용자 정의 함수 선언udfSpanGreaterThan
에 선언된 및 함수 사용 방법을 보여줍니다.
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);
예제 2: 입력으로 테이블을 사용하여 Java로 구현된 스칼라 UDF 사용
다음 예에서는 테이블을 입력으로 사용하는 스칼라 함수 사용 방법을 보여줍니다. 이 예에서는 Java™ 구현이 사용자 정의 함수 구현에 포함되어 있는 MyScalarFunc 테이블 UDF 함수 사용을 보여줍니다. 열 유형은 같지만 열 이름은 다릅니다.
-- 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;
예제 3: Java로 구현된 테이블 UDF 사용
이 예에서는 Java™ 구현이 사용자 정의 함수 구현에 포함되어 있는 MyTableFunc 테이블 UDF 함수 사용을 보여줍니다.
-- 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;
예제 2에서와 같이 이 예에서는 다음 두 뷰를 정의합니다. FirstInputView
) 스키마가 있는 (match Span)
및 SecondInputView
스키마가 있는 (spanCol Span, textCol Text)
. 이 예제의 마지막 뷰인 TabFuncOutput
에서는 두 개의 입력 뷰를 사용하여 table
절에서 from
함수 MyTableFunc를 호출합니다. 예제 2에 설명된 대로, 테이블 위치 지정자와 입력 뷰의 스키마에 있는 열 수와 열 유형이 일치하는 경우에 한해 뷰는 함수의 테이블 위치 지정자 인수와 호환됩니다. 그러나 열 이름은 일치하지 않아도 됩니다.
마지막으로 select
절에서는 MyTableFunc의 출력 테이블에서 outStr
열을 버리고 처음 두 열 outSpan1
및 outSpan2
만 유지합니다.
예제 4: PMML에서 구현된 테이블 UDF 사용
이 예에서는 사용자 정의 함수 선언의 예제 4에 선언된 IrisDecisionTree 테이블 UDF 함수의 사용을 보여줍니다.
-- 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;