가장 가까운 위치 찾기

설명

요청된 distance_measure를 사용하여 지정된 embedding 필드에서 최근접 이웃 벡터 검색을 수행합니다.

구문

Node.js

const results = await db.pipeline()
  .collection("cities")
  .findNearest({
      field: 'embedding',
      vectorValue: vector([1.5, 2.345]),
      distanceMeasure: 'euclidean',
  })
  .execute();

클라이언트 예시

Node.js
const results = await db.pipeline()
  .collection("cities")
  .findNearest({
      field: "embedding",
      vectorValue: [1.5, 2.345],
      distanceMeasure: "euclidean"
  })
  .execute();

Web

const results = await execute(db.pipeline()
  .collection("cities")
  .findNearest({
      field: "embedding",
      vectorValue: [1.5, 2.345],
      distanceMeasure: "euclidean"
  }));
Swift
let results = try await db.pipeline()
  .collection("cities")
  .findNearest(
    field: Field("embedding"),
    vectorValue: VectorValue([1.5, 2.345]),
    distanceMeasure: .euclidean
  )
  .execute()

Kotlin

val results = db.pipeline()
    .collection("cities")
    .findNearest(
        "embedding",
        FieldValue.vector(doubleArrayOf(1.5, 2.345)),
        FindNearestStage.DistanceMeasure.EUCLIDEAN
    )
    .execute()

Java

Task<Pipeline.Snapshot> results = db.pipeline()
        .collection("cities")
        .findNearest(
            "embedding",
            new double[] {1.5, 2.345},
            FindNearestStage.DistanceMeasure.EUCLIDEAN
        )
        .execute();
Python
from google.cloud.firestore_v1.vector import Vector
from google.cloud.firestore_v1.base_vector_query import DistanceMeasure

results = (
    client.pipeline()
    .collection("cities")
    .find_nearest(
        field="embedding",
        vector_value=Vector([1.5, 2.345]),
        distance_measure=DistanceMeasure.EUCLIDEAN,
    )
    .execute()
)
자바
Pipeline.Snapshot results =
    firestore
        .pipeline()
        .collection("cities")
        .findNearest(
            "embedding",
            new double[] {1.5, 2.345},
            FindNearest.DistanceMeasure.EUCLIDEAN,
            new FindNearestOptions())
        .execute()
        .get();

동작

거리 측정

find_nearest 단계는 벡터 거리에 대해 다음 옵션을 지원합니다.

  • euclidean: 벡터 사이의 euclidean 거리를 측정합니다. 자세한 내용은 유클리드를 참조하세요.
  • cosine: 벡터 크기를 기반으로 하지 않는 유사성을 측정할 수 있도록 벡터 사이의 각도를 기준으로 벡터를 비교합니다. COSINE 거리 대신 dot_product를 단위 정규화된 벡터와 함께 사용하는 것이 좋습니다. 이는 수학적으로 동일하며 성능이 더 우수합니다. 자세한 내용은 코사인 유사성을 참고하세요.
  • dot_product: cosine과 유사하지만 벡터의 크기에 영향을 받습니다. 자세한 내용은 내적을 참조하세요.

거리 측정 선택

모든 벡터 임베딩이 정규화되었는지 여부에 따라 거리 측정을 찾는 데 사용할 거리 측정을 결정할 수 있습니다. 정규화된 벡터 임베딩의 크기(길이)는 정확히 1.0입니다.

또한 모델이 어떤 거리 측정으로 학습되었는지 알고 있다면 해당 거리 측정을 사용하여 벡터 임베딩 간의 거리를 계산할 수 있습니다.

정규화된 데이터

모든 벡터 임베딩이 정규화된 데이터 세트가 있다면, 세 거리 측정 모두 동일한 시맨틱 검색 결과를 제공합니다. 기본적으로 각 거리 측정은 서로 다른 값을 반환하지만 해당 값은 동일한 방식으로 정렬됩니다. 임베딩이 정규화될 때는 일반적으로 dot_product가 가장 계산 효율적이지만 대부분의 경우 그 차이는 무시할 수 있을 정도입니다. 하지만 애플리케이션이 성능에 매우 민감한 경우 dot_product가 성능 조정에 도움이 될 수 있습니다.

비정규화된 데이터

벡터 임베딩이 정규화되지 않은 데이터 세트가 있는 경우 내적에서 거리를 측정하지 않기 때문에 dot_product를 거리 측정으로 사용하는 것은 수학적으로 올바르지 않습니다. 임베딩이 생성된 방법과 원하는 검색 유형에 따라 cosine 또는 euclidean 거리 측정에서 다른 거리 측정보다 주관적으로 더 나은 검색 결과를 생성할 수 있습니다. 사용 사례에 가장 적합한 방식을 결정하려면 cosine 또는 euclidean를 실험해야 할 수 있습니다.

데이터가 정규화되었는지 또는 비정규화되었는지 확실하지 않음

데이터가 정규화되었는지 여부가 확실하지 않고 dot_product를 사용하려는 경우 대신 cosine를 사용하는 것이 좋습니다. cosine은 정규화가 내장된 dot_product와 같습니다. cosine을 사용하여 측정한 거리의 범위는 0~2입니다. 결과가 0에 가까우면 벡터가 매우 유사하다는 것을 나타냅니다.

결과 제한

limit 필드를 설정하여 쿼리에서 반환되는 문서 수를 제한할 수 있습니다.

Node.js

const results = await db.pipeline()
  .collection("cities")
  .findNearest({
      field: 'embedding',
      vectorValue: vector([1.5, 2.345]),
      distanceMeasure: 'euclidean',
      limit: 10,
  })
  .execute();

계산된 벡터 거리 검색

다음 예시와 같이 find_nearest 단계에 distance_field 출력 속성 이름을 할당하여 계산된 벡터 거리를 검색할 수 있습니다.

다음 컬렉션을 예로 들어보겠습니다.

Node.js

await db.collection('cities').doc('SF').set({name: 'San Francisco', embedding: vector([1.0, -1.0])});
await db.collection('cities').doc('TO').set({name: 'Toronto', embedding: vector([5.0, -10.0])});
await db.collection('cities').doc('AT').set({name: 'Atlantis', embedding: vector([2.0, -4.0])});

요청된 출력 distance_field로 벡터 검색을 수행합니다.

Node.js

const results = await db.pipeline()
  .collection("cities")
  .findNearest({
      field: 'embedding',
      vectorValue: vector([1.3, 2.345]),
      distanceMeasure: 'euclidean',
      distanceField: 'computedDistance',
  })
  .execute();

그러면 다음과 같은 문서가 생성됩니다.

{name: 'San Francisco', embedding: vector([1.0, -1.0]), computedDistance: 3.3584259705999178},
{name: 'Atlantis', embedding: vector([2.0, -4.0]), computedDistance: 6.383496299051172},
{name: 'Toronto', embedding: vector([5.0, -10.0]), computedDistance: 12.887553103673328}

제한사항

벡터 임베딩으로 작업할 때 다음 제한사항에 유의하세요.

  • 지원되는 최대 임베딩 차원은 2048입니다. 더 큰 색인을 저장하려면 차원 축소를 사용합니다.