벡터/유사도 함수

벡터/유사도 함수 (Vector / Similarity Functions)

Pinot은 float 배열 컬럼으로 작업하기 위한 내장 벡터 유사도 및 유틸리티 함수를 제공해요. 이 함수들은 최근접 이웃 검색, 추천 시스템, 검색 증강 생성(RAG), 그리고 임베딩 벡터를 포함한 모든 사용 사례를 지원합니다.

두 입력 벡터는 차원 수가 같아야 해요. null 또는 길이가 다른 벡터를 전달하면 오류가 발생합니다.

참고: 근사 최근접 이웃(ANN) 조회로 벡터 검색 쿼리를 가속화하려면 float 배열 컬럼에 벡터 인덱스를 구성하고 아래 설명된 VECTOR_SIMILARITY 술어를 사용하세요.

출처: 문서

본문

VECTOR_SIMILARITY

VECTOR_SIMILARITY는 벡터 인덱스를 사용해 근사 최근접 이웃(ANN) 검색을 수행하는 WHERE 절 술어예요. 독립 함수가 아니라, 주어진 쿼리 벡터에 가장 가까운 벡터를 가진 top-K 문서를 반환하는 필터 역할을 합니다.

문법

WHERE VECTOR_SIMILARITY(vectorColumn, queryVector, topK)
파라미터 타입 설명
vectorColumn identifier 벡터 인덱스가 구성된 다중 값 FLOAT 컬럼.
queryVector ARRAY[...] 쿼리 임베딩을 나타내는 float 배열 리터럴.
topK integer literal 검색할 최근접 이웃 수. 생략하면 기본값 10.

사전 요구사항

VECTOR_SIMILARITY는 대상 컬럼에 벡터 인덱스가 있으면 이를 사용합니다. Pinot은 HNSW, IVF_FLAT, IVF_PQ, IVF_ON_DISK 네 가지 백엔드를 지원해요. 세그먼트에 벡터 인덱스가 없으면(예: IVF_FLAT, IVF_PQ, IVF_ON_DISK의 실시간 세그먼트) Pinot은 해당 세그먼트에 대해 forward index에서 정확 스캔(exact scan)으로 폴백합니다. 정확 스캔은 ANN 조회보다 훨씬 느리므로, 프로덕션 워크로드에는 벡터 인덱스를 구성하세요. 설정 방법은 벡터 인덱스 문서를 참고하세요.

최소 필드 설정:

{
  "fieldConfigList": [
    {
      "name": "embedding",
      "encodingType": "RAW",
      "indexes": {
        "vector": {
          "vectorIndexType": "HNSW",
          "vectorDimension": 512,
          "vectorDistanceFunction": "COSINE",
          "version": 1
        }
      }
    }
  ]
}

예시

쿼리 임베딩에 가장 가까운 5개 상품을 찾아 코사인 거리로 순위 매기기:

SELECT ProductId,
       cosineDistance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.12, 0.34, 0.56, ...], 5)
ORDER BY dist ASC
LIMIT 5

메타데이터 필터와 결합 — ANN 후보 20개를 가져온 뒤 카테고리로 필터링:

SELECT ProductId, Summary,
       l2Distance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM fineFoodReviews
WHERE VECTOR_SIMILARITY(embedding, ARRAY[0.12, 0.34, 0.56, ...], 20)
  AND category = 'electronics'
ORDER BY dist ASC
LIMIT 10

경고: Pinot이 벡터 인덱스를 사용할 때 VECTOR_SIMILARITY는 근사 최근접 이웃 술어예요. vectorExactRerank=true는 인덱스가 반환한 ANN 후보를 재점수화하지만, ANN 검색을 완전한 정확 스캔으로 바꾸지는 않습니다. IVF_PQ는 PQ 거리가 본질적으로 근사이므로 vectorExactRerank=true를 기본값으로 합니다. 더 나은 recall을 얻으려면 최종 LIMIT보다 큰 topK를 요청하고 거리 함수의 ORDER BY와 결합하세요.

VECTOR_SIMILARITY_RADIUS

VECTOR_SIMILARITY_RADIUS는 고정된 top-K 없이 거리 임계값 안의 모든 벡터를 반환하는 WHERE 절 술어예요. 임의의 최근접 이웃 수보다 품질 임계값을 만족하는 모든 결과를 원할 때 유용합니다.

문법

WHERE VECTOR_SIMILARITY_RADIUS(vectorColumn, queryVector, distanceThreshold)
파라미터 타입 설명
vectorColumn identifier 벡터 인덱스가 구성된 다중 값 FLOAT 컬럼.
queryVector ARRAY[...] 쿼리 임베딩을 나타내는 float 배열 리터럴.
distanceThreshold float literal 벡터가 결과에 포함되기 위한 최대 거리.

동작 방식

벡터 인덱스가 있는 세그먼트에서 Pinot은 ANN 인덱스로 후보를 생성한 뒤 정확 거리로 필터링합니다. 벡터 인덱스가 없는 세그먼트에서는 brute-force 스캔으로 폴백해 임계값 안의 모든 벡터를 정확히 반환합니다.

예시

쿼리 임베딩에서 코사인 거리 0.3 이내의 모든 상품 찾기:

SELECT ProductId,
       cosineDistance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY_RADIUS(embedding, ARRAY[0.12, 0.34, 0.56, ...], 0.3)
ORDER BY dist ASC;

반경 검색과 메타데이터 필터 결합:

SELECT ProductId, Summary,
       l2Distance(embedding, ARRAY[0.12, 0.34, 0.56, ...]) AS dist
FROM products
WHERE VECTOR_SIMILARITY_RADIUS(embedding, ARRAY[0.12, 0.34, 0.56, ...], 5.0)
  AND category = 'electronics'
ORDER BY dist ASC;

거리 함수 (Distance Functions)

cosineDistance

cosineDistance(vector1, vector2)
cosineDistance(vector1, vector2, defaultValue)

두 벡터 사이의 코사인 거리를 1 - cosine_similarity로 정의해 반환해요. 결과 범위는 0(동일 방향)부터 2(반대 방향)까지입니다.

두 벡터 중 하나의 norm이 0이면 두 인자 형식은 NaN을, 세 인자 형식은 지정한 defaultValue를 반환합니다.

SELECT cosineDistance(
  embedding,
  ARRAY[0.1, 0.2, 0.3],
  0.0
) AS dist
FROM products
WHERE category = 'electronics'
ORDER BY dist ASC
LIMIT 10
-- Returns 0.0 for identical vectors, up to 2.0 for opposite vectors

innerProduct

innerProduct(vector1, vector2)

두 벡터의 내적(요소별 곱의 합)을 반환해요. 임베딩이 사전 정규화되어 있고 점수가 클수록 유사도가 높음을 나타낼 때 유용합니다.

SELECT ProductId,
       innerProduct(embedding, ARRAY[0.5, 0.5, 0.5]) AS score
FROM products
ORDER BY score DESC
LIMIT 10

l1Distance

l1Distance(vector1, vector2)

두 벡터 사이의 L1 거리(맨해튼 거리)를 구성 요소 절대 차이의 합으로 계산해 반환해요.

SELECT l1Distance(
  userEmbedding,
  ARRAY[1.0, 2.0, 3.0]
) AS manhattan_dist
FROM users
ORDER BY manhattan_dist ASC
LIMIT 10

l2Distance

l2Distance(vector1, vector2)

두 벡터 사이의 L2 거리(유클리드 거리)를 제곱 차이 합의 제곱근으로 계산해 반환해요.

SELECT l2Distance(
  embedding,
  ARRAY[0.1, 0.2, 0.3]
) AS dist
FROM products
ORDER BY dist ASC
LIMIT 5

euclideanDistance

euclideanDistance(vector1, vector2)

두 벡터 사이의 제곱 유클리드 거리(제곱근 없는 제곱 차이 합)를 반환해요. 상대 거리만 비교하면 될 때 l2Distance보다 계산 비용이 낮죠. 제곱근을 생략해도 순서가 보존되기 때문입니다.

SELECT euclideanDistance(
  embedding,
  ARRAY[0.1, 0.2, 0.3]
) AS squared_dist
FROM products
ORDER BY squared_dist ASC
LIMIT 5

dotProduct

dotProduct(vector1, vector2)

두 벡터의 내적을 반환해요. innerProduct와 기능적으로 동일합니다.

SELECT dotProduct(
  queryEmbedding,
  docEmbedding
) AS relevance
FROM documents
ORDER BY relevance DESC
LIMIT 10

유틸리티 함수 (Utility Functions)

vectorDims

vectorDims(vector)

벡터의 차원 수(길이)를 반환해요.

SELECT vectorDims(embedding) AS dims
FROM products
LIMIT 1
-- Returns 128 for a 128-dimensional embedding

vectorNorm

vectorNorm(vector)

벡터의 L2 norm(유클리드 길이)을 제곱 요소 합의 제곱근으로 계산해 반환해요.

SELECT vectorNorm(embedding) AS norm
FROM products
LIMIT 5
-- Returns the magnitude of each embedding vector

이 예시는 스키마 정의부터 쿼리까지, 상품 리뷰에 대한 시맨틱 검색 테이블 설정 과정을 안내해요.

1. 스키마 정의

임베딩 컬럼은 다중 값 FLOAT 필드여야 해요.

{
  "schemaName": "fineFoodReviews",
  "dimensionFieldSpecs": [
    { "name": "ProductId", "dataType": "STRING" },
    { "name": "UserId", "dataType": "STRING" },
    { "name": "Score", "dataType": "INT" },
    { "name": "Summary", "dataType": "STRING" },
    { "name": "Text", "dataType": "STRING" },
    {
      "name": "embedding",
      "dataType": "FLOAT",
      "singleValueField": false
    }
  ],
  "dateTimeFieldSpecs": [
    {
      "name": "ts",
      "dataType": "TIMESTAMP",
      "format": "1:MILLISECONDS:TIMESTAMP",
      "granularity": "1:SECONDS"
    }
  ]
}

2. 벡터 인덱스로 테이블 구성

embedding 컬럼에 HNSW 벡터 인덱스를 활성화해요. 임베딩이 생성된 방식과 일치하는 거리 함수를 선택하세요 — COSINE은 정규화된 텍스트 임베딩에 가장 흔한 선택입니다.

{
  "tableName": "fineFoodReviews_OFFLINE",
  "tableType": "OFFLINE",
  "fieldConfigList": [
    {
      "name": "embedding",
      "encodingType": "RAW",
      "indexes": {
        "vector": {
          "vectorIndexType": "HNSW",
          "vectorDimension": 1536,
          "vectorDistanceFunction": "COSINE",
          "version": 1,
          "properties": {
            "maxCon": "32",
            "beamWidth": "200"
          }
        }
      }
    }
  ]
}

3. 벡터 유사도로 쿼리

VECTOR_SIMILARITY로 최근접 이웃을 검색하고 거리 함수로 결과를 순위 매깁니다:

SELECT ProductId,
       UserId,
       Summary,
       cosineDistance(embedding, ARRAY[-0.0013, -0.0110, 0.0247, ...]) AS dist
FROM fineFoodReviews
WHERE VECTOR_SIMILARITY(embedding, ARRAY[-0.0013, -0.0110, 0.0247, ...], 10)
ORDER BY dist ASC
LIMIT 5

이 쿼리는 먼저 HNSW 인덱스로 10개의 근사 최근접 이웃을 검색한 뒤, 그 후보들을 정확한 코사인 거리로 정렬해 상위 5개를 반환합니다.

함수 요약

함수 반환 타입 설명
VECTOR_SIMILARITY(col, query, topK) predicate ANN 필터 — top-K 최근접 이웃 반환.
VECTOR_SIMILARITY_RADIUS(col, query, threshold) predicate 거리 기반 필터 — 임계값 안의 모든 벡터 반환.
cosineDistance(v1, v2 [, default]) DOUBLE 코사인 거리 (1 - cosine_similarity).
innerProduct(v1, v2) DOUBLE 내적 (요소별 곱의 합).
l1Distance(v1, v2) DOUBLE 맨해튼 거리.
l2Distance(v1, v2) DOUBLE 유클리드 거리 (제곱근 포함).
euclideanDistance(v1, v2) DOUBLE 제곱 유클리드 거리 (제곱근 없음).
dotProduct(v1, v2) DOUBLE 내적 (innerProduct와 동일).
vectorDims(v) INT 벡터 차원 수.
vectorNorm(v) DOUBLE 벡터의 L2 norm (크기).

더 알아보기 (Learn more)