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, anti join 유형은 기본적으로 활성화돼요. 성능에 민감한 right, full, cross join 유형은 기본적으로 비활성화돼요. 이 유형들을 활성화하려면 plugins.calcite.all_join_types.allowed를 true로 설정해요.

더 알아보기 (Learn more)