설명
이전 단계의 필드 또는 표현식의 고유 값을 알아냅니다.
구문
distinct 단계는 select와 구문이 비슷합니다. 선택 가능한 하나 이상의 표현식을 사용하여 고유한 값을 선택하고 찾습니다. 표현식이 필드 참조인 경우 문자열을 사용할 수 있습니다.
Node.js
const cities = await db.pipeline()
.collection('/cities')
.distinct("country")
.execute();
const cities = await db.pipeline()
.collection('/cities')
.distinct(
field("state").toLower().as("normalized_state"),
field("country"))
.execute();
클라이언트 예시
Node.js
let cities = await db.pipeline() .collection("cities") .distinct("country") .execute(); cities = await db.pipeline() .collection("cities") .distinct( field("state").toLower().as("normalizedState"), field("country")) .execute();
Web
let cities = await execute(db.pipeline() .collection("cities") .distinct("country")); cities = await execute(db.pipeline() .collection("cities") .distinct( field("state").toLower().as("normalizedState"), field("country")));
Swift
let results = try await db.pipeline() .collection("books") .distinct([ Field("author").toUpper().as("author"), Field("genre") ]) .execute()
Kotlin
var cities = db.pipeline() .collection("cities") .distinct("country") .execute() cities = db.pipeline() .collection("cities") .distinct( field("state").toLower().alias("normalizedState"), field("country") ) .execute()
Java
Task<Pipeline.Snapshot> cities; cities = db.pipeline() .collection("cities") .distinct("country") .execute(); cities = db.pipeline() .collection("cities") .distinct( field("state").toLower().alias("normalizedState"), field("country")) .execute();
Python
from google.cloud.firestore_v1.pipeline_expressions import Field cities = client.pipeline().collection("cities").distinct("country").execute() cities = ( client.pipeline() .collection("cities") .distinct(Field.of("state").to_lower().as_("normalizedState"), "country") .execute() )
자바
Pipeline.Snapshot cities1 = firestore.pipeline().collection("cities").distinct("country").execute().get(); Pipeline.Snapshot cities2 = firestore .pipeline() .collection("cities") .distinct(toLower(field("state")).as("normalizedState"), field("country")) .execute() .get();
동작
예측 동작 측면에서 distinct는 중복 삭제가 적용된 select와 유사하므로 select에서 사용할 수 있는 선택 가능한 표현식은 distinct에서도 사용할 수 있습니다.
distinct 단계는 그룹이 없는 집계 단계와 유사하게 작동합니다.
고유한 필드 값 찾기
예를 들어 다음 cities 컬렉션의 모든 국가 목록을 가져오려면 다음을 실행합니다.
Node.js
await db.collection('cities').doc('SF').set({name: 'San Francisco', state: 'CA', country: 'USA'});
await db.collection('cities').doc('LA').set({name: 'Los Angeles', state: 'CA', country: 'USA'});
await db.collection('cities').doc('NY').set({name: 'New York', state: 'NY', country: 'USA'});
await db.collection('cities').doc('TOR').set({name: 'Toronto', state: null, country: 'Canada'});
await db.collection('cities').doc('MEX').set({name: 'Mexico City', state: null, country: 'Mexico'});
다음을 사용하여 고유한 국가를 찾을 수 있습니다.
Node.js
const cities = await db.pipeline()
.collection('/cities')
.distinct("country")
.execute();
그러면 다음과 같은 결과가 생성됩니다.
{country: "USA"}
{country: "Canada"}
{country: "Mexico"}
표현식의 고유한 출력
여러 필드의 고유한 조합이나 더 복잡한 표현식을 찾을 수도 있습니다. 예를 들면 다음과 같습니다.
Node.js
const cities = await db.pipeline()
.collection('/cities')
.distinct(
field("state").toLower().as("normalized_state"),
field("country"))
.execute();
다음을 가져옵니다.
{country: "USA", normalized_state: "ca"}
{country: "USA", normalized_state: "ny"}
{country: "Canada", normalized_state: null}
{country: "Mexico", normalized_state: null}
등가성 동작
고유 값의 등가성 동작은 등식과 동일한 시맨틱스를 따릅니다.
즉, 원래 유형(32비트 정수, 64비트 정수, 부동 소수점 숫자, 십진수 등)에 관계없이 수학적으로 동등한 숫자 값과 같은 동등한 값은 동일한 고유 값으로 간주됩니다.
예를 들어 32비트 정수 1, 64비트 정수 1L, 부동 소수점 1.0의 foo 값이 각각 포함된 여러 문서가 있는 컬렉션 numerics에서 distinct는 하나의 결과만 반환합니다.
데이터 세트에 서로 다른 동등한 값이 있는 경우 그룹의 출력 값은 이러한 동등한 값 중 하나가 될 수 있습니다.
이 예시에서 foo 값은 1, 1L 또는 1.0으로 반환될 수 있습니다.
결정적인 것처럼 보이더라도 특정 값이 선택되는 동작에 의존하려고 하면 안 됩니다.
메모리 사용량
distinct 단계가 실행되는 방식은 사용 가능한 색인에 따라 다릅니다. 쿼리 최적화 도구에서 적절한 색인을 선택하지 않으면 distinct는 메모리에 모든 고유 값을 버퍼링해야 합니다.
고유한 값이 매우 많거나 값이 매우 큰 경우(예: 큰 값에 대한 고유한 값) 이 단계에서 메모리가 부족할 수 있습니다.
이 경우 데이터 세트를 제한하는 필터를 적용하여 distinct를 실행하거나 권장되는 대로 색인을 만들어 메모리 사용량이 많아지지 않도록 해야 합니다.
쿼리 설명은 디버깅에 도움이 되는 실제 쿼리 실행 계획 및 프로파일링 데이터에 대한 정보를 제공합니다.