k-NN API

k-NN API (gRPC)

3.2에서 도입되었어요. gRPC k-NN API는 OpenSearch 3.2부터 일반 공개 상태예요. 다만 기능이 다음 버전에서 성숙해짐에 따라 protobuf 구조의 업데이트가 예상돼요.

gRPC k-NN API는 gRPC 위의 프로토콜 버퍼를 사용해 k-최근접 이웃(k-nearest neighbor) 검색을 수행하는 효율적인 이진 인코딩 인터페이스를 제공해요. k-NN plugin은 벡터 유사도 검색을 위한 특정 검색 쿼리 유형을 제공해요. 이 API는 전통적인 HTTP 기반 방식보다 우수한 성능을 제공해서 대규모 머신러닝과 벡터 데이터베이스 애플리케이션에 이상적이에요.

HTTP 기반 k-NN 쿼리에 대한 정보는 k-NN query를 참고하세요.

출처: 문서

본문

사전 요구 사항 (Prerequisite)

gRPC 요청을 제출하려면 클라이언트 쪽에 protobuf 세트가 있어야 해요. protobuf를 얻는 방법은 Using gRPC APIs를 참고하세요.

gRPC 서비스와 메서드 (gRPC service and method)

gRPC k-NN API는 일반 검색 작업에 사용되는 동일한 서비스인 SearchService에 있어요.

SearchService 안의 Search gRPC 메서드를 호출하고 검색 요청 안에 KnnQuery를 사용해서 k-NN 검색 요청을 제출할 수 있어요. 이 메서드는 SearchRequest를 받아 SearchResponse를 반환해요.

gRPC 구현은 HTTP API와 같은 기본 k-NN 기능을 사용하면서 프로토콜 버퍼 직렬화를 통해 개선된 성능을 제공해요.

KnnQuery 필드 (KnnQuery fields)

gRPC k-NN API는 QueryContainer 안의 KnnQuery 메시지를 k-NN 검색에 사용해요. KnnQuery 메시지는 다음 필드를 받아요.

필드 Protobuf 타입 설명
field string 검색 쿼리를 실행할 벡터 필드예요. 필수예요.
vector repeated float 쿼리 벡터예요. 벡터 필드와 같은 차원 수를 가져야 해요. 선택 사항이에요.
k int32 상위 hits로 반환할 최근접 이웃 수예요. 선택 사항이에요.
min_score float 이웃이 hit로 간주되기 위해 필요한 최소 유사도 점수예요. 선택 사항이에요.
max_distance float 이웃이 hit로 간주되기 위해 필요한 벡터 공간상의 최대 물리적 거리예요. 선택 사항이에요.
filter QueryContainer k-NN 검색 쿼리의 필터예요. 필터 제한 사항을 참고하세요. 선택 사항이에요.
boost float 관련성 점수를 높이거나 낮추는 데 사용하는 부스트 값이예요. 기본값은 1.0이에요. 선택 사항이에요.
underscore_name string 쿼리 태깅용 쿼리 이름이에요(JSON 키: _name). 선택 사항이에요.
method_parameters ObjectMap 알고리즘별 파라미터(예: ef_search 또는 nprobes)예요. 선택 사항이에요.
rescore KnnQueryRescore 정확도 개선을 위한 리스코어링(rescoring) 구성이에요. 2.17 이후 버전에서 사용할 수 있어요. 선택 사항이에요.
expand_nested_docs bool true이면 각 부모 문서 안의 모든 중첩 필드 문서에 대해 점수를 가져와요. 중첩 쿼리와 함께 사용돼요. 선택 사항이에요.

예제 요청 (Example request)

다음 예제는 k-NN 쿼리가 있는 gRPC 검색 요청을 보여줘요. vector_index 인덱스의 my_vector 필드에서 쿼리 벡터 [0.1, 0.2, 0.3, 0.4]에 가장 유사한 10개 벡터를 검색해요.

{
  "index": ["vector_index"],
  "search_request_body": {
    "query": {
      "knn": {
        "field": "my_vector",
        "vector": [0.1, 0.2, 0.3, 0.4],
        "k": 10
      }
    },
    "size": 10
  }
}

Java gRPC 클라이언트 예제 (Java gRPC client example)

다음은 gRPC k-NN API를 사용하는 기본 예제예요(실제 구현은 gRPC 클라이언트 설정에 따라 달라져요).

import org.opensearch.protobufs.*;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;

public class KnnGrpcClient {
    public static void main(String[] args) {
        ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 9400)
                .usePlaintext()
                .build();

        // Create a gRPC stub for search operations
        SearchServiceGrpc.SearchServiceBlockingStub searchStub =
            SearchServiceGrpc.newBlockingStub(channel);

        // Build a k-NN query using protocol buffers
        QueryContainer knnQuery = QueryContainer.newBuilder()
            .setKnn(KnnQuery.newBuilder()
                .setField("my_vector")
                .addAllVector(Arrays.asList(0.1f, 0.2f, 0.3f, 0.4f))
                .setK(10)
                .build())
            .build();

        // Create the search request
        SearchRequest request = SearchRequest.newBuilder()
            .addIndex("vector_index")
            .setSearchRequestBody(SearchRequestBody.newBuilder()
                .setQuery(knnQuery)
                .setSize(10)
                .build())
            .build();

        // Execute the search
        try {
            SearchResponse response = searchStub.search(request);

            // Handle the response
            System.out.println("Search took: " + response.getTook() + " ms");

            HitsMetadata hits = response.getHits();
            if (hits.hasTotal()) {
                System.out.println("Found " + hits.getTotal().getTotalHits().getValue() + " results");
            }

            // Process k-NN results with similarity scores
            for (HitsMetadataHitsInner hit : hits.getHitsList()) {
                System.out.println("Document ID: " + hit.getXId());
                if (hit.hasXScore()) {
                    System.out.println("Similarity score: " + hit.getXScore().getDouble());
                }
            }
        } catch (io.grpc.StatusRuntimeException e) {
            System.err.println("gRPC k-NN search request failed with status: " + e.getStatus());
            System.err.println("Error message: " + e.getMessage());
        }

        channel.shutdown();
    }
}

응답 필드 (Response fields)

k-NN 검색 요청은 일반 검색 작업과 같은 SearchResponse 구조를 반환해요. 응답 필드에 대한 정보는 Search (gRPC) 응답 필드를 참고하세요.

응답에는 표준 검색 메타데이터(took, timed_out, shards)와 유사도 점수가 포함된 k-NN 문서를 담은 hits 배열이 포함돼요.

필터 제한 사항 (Filter limitations)

gRPC k-NN API는 HTTP API에 비해 filter 절에 대한 지원이 제한적이에요. gRPC에서 지원되는 쿼리 유형의 현재 목록은 Search API QueryContainer 문서와 Supported queries를 참고하세요.

복잡한 필터링 요구 사항이 있다면 HTTP k-NN API를 사용하거나, 필터 로직을 단순화하거나, 다음 버전의 k-NN gRPC를 기다리는 것을 고려하세요.

  • Search (gRPC) — 일반 gRPC 검색 기능
  • Bulk (gRPC) — gRPC를 사용한 bulk 작업
  • k-NN queries — HTTP 기반 k-NN 쿼리 문서

다음 단계 (Next steps)

  • OpenSearch의 벡터 검색에 대해 자세히 알아보세요.
  • k-NN 인덱스 설정을 살펴보세요.
  • k-NN 성능 튜닝을 검토하세요.
  • gRPC 구성에 대해 읽어보세요.

더 알아보기 (Learn more)