JOIN 명령어
JOIN 명령어
join 명령어는 두 데이터셋을 결합해요. 왼쪽은 인덱스일 수도 있고 파이프라인된 명령어의 결과일 수도 있으며, 오른쪽은 인덱스 또는 서브서치(subsearch)가 될 수 있어요.
출처: 문서
본문
join 명령어는 두 데이터셋을 결합해요. 왼쪽은 인덱스일 수도 있고 파이프라인된 명령어의 결과일 수도 있으며, 오른쪽은 인덱스 또는 서브서치(subsearch)가 될 수 있어요.
구문 (Syntax)
join 명령어는 기본(basic) 구문과 확장(extended) 구문을 지원해요.
기본 구문
[joinType] join [left = <leftAlias>] [right = <rightAlias>] (on | where) <joinCriteria> <right-dataset>
별칭(alias)을 사용할 때는 left가 right보다 먼저 와야 해요.
다음은 join 명령어 기본 구문의 예시예요:
source = table1 | inner join left = l right = r on l.a = r.a table2 | fields l.a, r.a, b, c
source = table1 | inner join left = l right = r where l.a = r.a table2 | fields l.a, r.a, b, c
source = table1 | left join left = l right = r on l.a = r.a table2 | fields l.a, r.a, b, c
source = table1 | right join left = l right = r on l.a = r.a table2 | fields l.a, r.a, b, c
source = table1 | full left = l right = r on l.a = r.a table2 | fields l.a, r.a, b, c
source = table1 | cross join left = l right = r on 1=1 table2
source = table1 | left semi join left = l right = r on l.a = r.a table2
source = table1 | left anti join left = l right = r on l.a = r.a table2
source = table1 | join left = l right = r [ source = table2 | where d > 10 | head 5 ]
source = table1 | inner join on table1.a = table2.a table2 | fields table1.a, table2.a, table1.b, table1.c
source = table1 | inner join on a = c table2 | fields a, b, c, d
source = table1 as t1 | join left = l right = r on l.a = r.a table2 as t2 | fields l.a, r.a
source = table1 as t1 | join left = l right = r on l.a = r.a table2 as t2 | fields t1.a, t2.a
source = table1 | join left = l right = r on l.a = r.a [ source = table2 ] as s | fields l.a, s.a
기본 구문 매개변수
기본 join 구문은 다음 매개변수를 지원해요.
| 매개변수 | 필수/선택 | 설명 |
|---|---|---|
<joinCriteria> |
필수 | 데이터셋을 어떻게 결합할지 지정하는 비교 표현식이에요. 쿼리에서 on 또는 where 키워드 뒤에 위치해야 해요. |
<right-dataset> |
필수 | 오른쪽 데이터셋으로, 별칭이 있거나 없는 인덱스 또는 서브서치일 수 있어요. |
joinType |
선택 | 수행할 join 유형이에요. 유효한 값은 left, semi, anti와 성능에 민감한 유형(right, full, cross)이에요. 기본값은 inner예요. |
left |
선택 | 모호한 필드 이름을 피하기 위해 왼쪽 데이터셋(일반적으로 서브서치)에 사용하는 별칭이에요. left = <leftAlias>로 지정해요. |
right |
선택 | 모호한 필드 이름을 피하기 위해 오른쪽 데이터셋(일반적으로 서브서치)에 사용하는 별칭이에요. right = <rightAlias>로 지정해요. |
확장 구문
join [type=<joinType>] [overwrite=<bool>] [max=n] (<join-field-list> | [left = <leftAlias>] [right = <rightAlias>] (on | where) <joinCriteria>) <right-dataset>
다음은 join 명령어 확장 구문의 예시예요:
source = table1 | join type=outer left = l right = r on l.a = r.a table2 | fields l.a, r.a, b, c
source = table1 | join type=left left = l right = r where l.a = r.a table2 | fields l.a, r.a, b, c
source = table1 | join type=inner max=1 left = l right = r where l.a = r.a table2 | fields l.a, r.a, b, c
source = table1 | join a table2 | fields a, b, c
source = table1 | join a, b table2 | fields a, b, c
source = table1 | join type=outer a b table2 | fields a, b, c
source = table1 | join type=inner max=1 a, b table2 | fields a, b, c
source = table1 | join type=left overwrite=false max=0 a, b [source=table2 | rename d as b] | fields a, b, c
확장 구문 매개변수
확장 join 구문은 다음 매개변수를 지원해요.
| 매개변수 | 필수/선택 | 설명 |
|---|---|---|
<joinCriteria> |
필수 | 데이터셋을 어떻게 결합할지 지정하는 비교 표현식이에요. 쿼리에서 on 또는 where 키워드 뒤에 위치해야 해요. |
<right-dataset> |
필수 | 오른쪽 데이터셋으로, 별칭이 있거나 없는 인덱스 또는 서브서치일 수 있어요. |
type |
선택 | 확장 구문을 사용할 때의 join 유형이에요. 유효한 값은 left, outer(left와 동일), semi, anti와 성능에 민감한 유형(right, full, cross)이에요. 기본값은 inner예요. |
<join-field-list> |
선택 | join 기준을 만드는 데 사용되는 필드 목록이에요. 이 필드들은 두 데이터셋 모두에 존재해야 해요. 지정하지 않으면 두 데이터셋에 공통인 모든 필드가 join 키로 사용돼요. |
overwrite |
선택 | join-field-list가 지정된 경우에만 적용돼요. 이름이 중복된 오른쪽 데이터셋의 필드가 메인 검색 결과의 해당 필드를 대체할지 여부를 지정해요. 기본값은 true예요. |
max |
선택 | 메인 검색의 각 행에 결합할 서브서치 결과의 최대 수예요. plugins.ppl.syntax.legacy.preferred이 true일 때 기본값은 0(무제한)이에요. 설정이 false이면 기본값은 1이에요. |
left |
선택 | 모호한 필드 이름을 피하기 위해 왼쪽 데이터셋(일반적으로 서브서치)에 사용하는 별칭이에요. left = <leftAlias>로 지정해요. |
right |
선택 | 모호한 필드 이름을 피하기 위해 오른쪽 데이터셋(일반적으로 서브서치)에 사용하는 별칭이에요. right = <rightAlias>로 지정해요. |
구성 (Configuration)
join 명령어 동작은 plugins.ppl.join.subsearch_maxout 설정으로 구성되며, 이 설정은 join할 서브서치의 최대 행 수를 지정해요. 기본값은 50000이에요. 값이 0이면 제한이 없음을 나타내요.
설정을 업데이트하려면 다음 요청을 보내요:
PUT /_plugins/_query/settings
{
"persistent": {
"plugins.ppl.join.subsearch_maxout": "5000"
}
}
예제 1: 두 인덱스 결합하기
다음 쿼리는 기본 join 구문을 사용해 두 인덱스를 결합해요:
source = state_country
| inner join left=a right=b ON a.name = b.name occupation
| stats avg(salary) by span(age, 10) as age_span, b.country
쿼리는 다음과 같은 결과를 반환해요:
| avg(salary) | age_span | b.country |
|---|---|---|
| 120000.0 | 40 | USA |
| 105000.0 | 20 | Canada |
| 0.0 | 40 | Canada |
| 70000.0 | 30 | USA |
| 100000.0 | 70 | England |
예제 2: 서브서치와 결합하기
다음 쿼리는 기본 join 구문을 사용해 데이터셋을 서브서치와 결합해요:
source = state_country as a
| where country = 'USA' OR country = 'England'
| left join ON a.name = b.name [ source = occupation
| where salary > 0
| fields name, country, salary
| sort salary
| head 3 ] as b
| stats avg(salary) by span(age, 10) as age_span, b.country
쿼리는 다음과 같은 결과를 반환해요:
| avg(salary) | age_span | b.country |
|---|---|---|
| null | 40 | null |
| 70000.0 | 30 | USA |
| 100000.0 | 70 | England |
예제 3: 필드 목록을 사용해 결합하기
다음 쿼리는 확장 구문을 사용하고 join 기준에 필드 목록을 지정해요:
source = state_country
| where country = 'USA' OR country = 'England'
| join type=left overwrite=true name [ source = occupation
| where salary > 0
| fields name, country, salary
| sort salary
| head 3 ]
| stats avg(salary) by span(age, 10) as age_span, country
쿼리는 다음과 같은 결과를 반환해요:
| avg(salary) | age_span | country |
|---|---|---|
| null | 40 | null |
| 70000.0 | 30 | USA |
| 100000.0 | 70 | England |
예제 4: 추가 옵션과 함께 결합하기
다음 쿼리는 확장 구문과 선택적 매개변수를 사용해 join 작업을 더 세밀하게 제어해요:
source = state_country
| join type=inner overwrite=false max=1 name occupation
| stats avg(salary) by span(age, 10) as age_span, country
쿼리는 다음과 같은 결과를 반환해요:
| avg(salary) | age_span | country |
|---|---|---|
| 120000.0 | 40 | USA |
| 100000.0 | 70 | USA |
| 105000.0 | 20 | Canada |
| 70000.0 | 30 | USA |
제한 사항 (Limitations)
join 명령어는 다음과 같은 제한 사항이 있어요:
- 기본 구문의 필드 이름 모호성 – 왼쪽과 오른쪽 데이터셋의 필드가 같은 이름을 공유하면 출력의 필드 이름이 모호해져요. 이를 해결하기 위해 충돌하는 필드는
<alias>.id(별칭을 지정하지 않으면<tableName>.id)로 이름이 바뀌어요. 다음 표는table1과table2모두에id라는 필드가 있을 때 필드 이름 충돌이 해결되는 방식을 보여줘요:
| 쿼리 | 출력 |
|---|---|
source=table1 | join left=t1 right=t2 on t1.id=t2.id table2 | eval a = 1 |
t1.id, t2.id, a |
source=table1 | join on table1.id=table2.id table2 | eval a = 1 |
table1.id, table2.id, a |
source=table1 | join on table1.id=t2.id table2 as t2 | eval a = 1 |
table1.id, t2.id, a |
source=table1 | join right=tt on table1.id=t2.id [ source=table2 as t2 | eval b = id ] | eval a = 1 |
table1.id, tt.id, tt.b, a |
- 확장 구문의 필드 중복 제거 – 필드 목록과 함께 확장 구문을 사용하면 출력의 중복 필드 이름이
overwrite옵션에 따라 중복 제거돼요. - Join 유형 가용성 –
inner,left,outer(left의 별칭),semi,antijoin 유형은 기본적으로 활성화돼요. 성능에 민감한right,full,crossjoin 유형은 기본적으로 비활성화돼요. 이 유형들을 활성화하려면plugins.calcite.all_join_types.allowed를true로 설정해요.