다음을 통해 공유


.NET의 NoSQL용 Azure Cosmos DB의 인덱스 및 쿼리 벡터

적용 대상: NoSQL

벡터 인덱싱 및 검색을 사용하려면 먼저 기능을 사용하도록 설정해야 합니다. 이 문서에서는 다음 단계를 다룹니다.

  1. Azure Cosmos DB for NoSQL 기능에서 벡터 검색을 사용하도록 설정합니다.
  2. 벡터 검색을 위한 Azure Cosmos DB 컨테이너 설정
  3. 벡터 임베딩 정책 작성
  4. 컨테이너 인덱싱 정책에 벡터 인덱스 추가
  5. 벡터 인덱스 정책과 벡터 임베딩 정책을 사용하여 컨테이너 만들기
  6. 저장된 데이터에 대한 벡터 검색 수행

이 가이드에서는 벡터 데이터를 만들고, 데이터를 인덱싱하고, 컨테이너에서 데이터를 쿼리하는 과정을 안내합니다.

필수 조건

기능 활성화

NoSQL용 Azure Cosmos DB에 대한 벡터 검색을 수행하려면 다음 단계를 완료하여 기능을 사용하도록 설정해야 합니다.

  1. Azure Cosmos DB for NoSQL 리소스 페이지로 이동합니다.
  2. "설정" 메뉴 항목 아래에서 "기능" 창을 선택합니다.
  3. "NoSQL용 Azure Cosmos DB의 벡터 검색"을 선택합니다.
  4. 기능에 대한 설명을 읽어 사용하도록 설정할지 확인합니다.
  5. "사용"을 선택하여 Azure Cosmos DB for NoSQL에서 벡터 검색을 켭니다.

또는 Azure CLI를 사용하여 계정의 기능을 업데이트하여 NoSQL 벡터 검색을 지원합니다.

az cosmosdb update \
     --resource-group <resource-group-name> \
     --name <account-name> \
     --capabilities EnableNoSQLVectorSearch

참고 항목

등록 요청은 자동 승인됩니다. 그러나 적용하는 데 15분이 걸릴 수 있습니다.

인터넷 기반 서점을 위한 데이터베이스를 만들고 각 책에 대한 제목, 작성자, ISBN 및 설명을 저장하는 예를 들어 보겠습니다. 또한 벡터 임베딩을 포함하는 두 가지 속성을 정의해 봅니다. 첫 번째 속성은 책의 텍스트 콘텐츠에서 만들어진 텍스트 임베딩을 포함하는 "contentVector"입니다(예: 임베딩을 만들기 전에 "title" "author" "isbn" 및 "description" 속성 연결). 두 번째 속성은 책 표지 이미지에서 생성된 "coverImageVector"입니다.

  1. 벡터 검색을 수행하려는 필드에 대한 벡터 임베딩을 만들고 저장합니다.
  2. 벡터 임베딩 정책에서 벡터 임베딩 경로를 지정합니다.
  3. 컨테이너의 인덱싱 정책에 원하는 벡터 인덱스를 포함합니다.

이 문서의 후속 섹션을 위해 컨테이너에 저장된 항목에 대해 아래 구조를 고려합니다.

{
"title": "book-title", 
"author": "book-author", 
"isbn": "book-isbn", 
"description": "book-description", 
"contentVector": [2, -1, 4, 3, 5, -2, 5, -7, 3, 1], 
"coverImageVector": [0.33, -0.52, 0.45, -0.67, 0.89, -0.34, 0.86, -0.78] 
} 

컨테이너에 대한 벡터 임베딩 정책 만들기.

다음으로 컨테이너 벡터 정책을 정의해야 합니다. 이 정책은 VectorDistance 시스템 함수에서 벡터 속성을 처리하는 방법을 Azure Cosmos DB 쿼리 엔진에 알리는 데 사용되는 정보를 제공합니다. 또한 이 정책은 사용자가 지정하도록 선택한 경우 벡터 인덱싱 정책에 필요한 정보를 알려 줍니다. 포함된 벡터 정책에는 다음 정보가 포함됩니다.

  • "path": 벡터가 포함된 속성 경로
  • "datatype": 벡터 요소의 형식(기본값 Float32)
  • "dimensions": 경로에 있는 각 벡터의 길이(기본값 1536)
  • "distanceFunction": 거리/유사성을 계산하는 데 사용되는 메트릭(기본값 코사인)입니다.

도서 세부 정보가 포함된 예의 경우 벡터 정책은 아래 JSON 예와 유사할 수 있습니다.

  Database db = await client.CreateDatabaseIfNotExistsAsync("vector-benchmarking");
  List<Embedding> embeddings = new List<Embedding>()
  {
      new Embedding()
      {
          Path = "/coverImageVector",
          DataType = VectorDataType.Float32,
          DistanceFunction = DistanceFunction.Cosine,
          Dimensions = 8,
      },
      new Embedding()
      {
          Path = "/contentVector",
          DataType = VectorDataType.Float32,
          DistanceFunction = DistanceFunction.Cosine,
          Dimensions = 10,
      }
  };

인덱싱 정책에서 벡터 인덱스 만들기

벡터 임베딩 경로가 결정되면 벡터 인덱스를 인덱싱 정책에 추가해야 합니다. 현재 Azure Cosmos DB for NoSQL의 벡터 검색 기능은 새 컨테이너에서만 지원되므로 컨테이너 만들 때 벡터 정책을 적용해야 하며 나중에 수정할 수 없습니다. 이 예에서 인덱싱 정책은 다음과 같습니다.

    Collection<Embedding> collection = new Collection<Embedding>(embeddings);
    ContainerProperties properties = new ContainerProperties(id: "vector-container", partitionKeyPath: "/id")
    {   
        VectorEmbeddingPolicy = new(collection),
        IndexingPolicy = new IndexingPolicy()
        {
            VectorIndexes = new()
            {
                new VectorIndexPath()
                {
                    Path = "/vector",
                    Type = VectorIndexType.QuantizedFlat,
                }
            }
        },
    };
    properties.IndexingPolicy.IncludedPaths.Add(new IncludedPath { Path = "/*" });    
    properties.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath { Path = "/vector/*" });

Important

삽입 성능을 최적화하기 위해 인덱싱 정책의 "excludedPaths" 섹션에 벡터 패스가 추가되었습니다. "excludedPaths"에 벡터 패스를 추가하지 않으면 RU 요금이 높아지고 벡터 삽입 대기 시간이 길어집니다.

벡터 유사성 검색 쿼리 실행

원하는 벡터 정책으로 컨테이너를 만들고 컨테이너에 벡터 데이터를 삽입한 후에는 쿼리에서 벡터 거리 시스템 함수를 사용하여 벡터 검색을 수행할 수 있습니다. 설명을 보면서 음식 조리법에 관한 책을 검색하려 한다고 가정하면 먼저 쿼리 텍스트에 대한 임베딩을 가져와야 합니다. 이 경우 쿼리 텍스트("음식 조리법")에 대한 임베딩을 생성할 수 있습니다. 검색 쿼리에 대한 임베딩이 있으면 벡터 검색 쿼리의 VectorDistance 함수에서 이를 사용하고 다음과 같이 쿼리와 유사한 모든 항목을 가져올 수 있습니다.

SELECT TOP 10 c.title, VectorDistance(c.contentVector, [1,2,3,4,5,6,7,8,9,10]) AS SimilarityScore   
FROM c  
ORDER BY VectorDistance(c.contentVector, [1,2,3,4,5,6,7,8,9,10])   

이 쿼리는 사용자의 쿼리에 대한 유사성 점수와 함께 책 제목을 쿼리합니다. 다음은 .NET의 예입니다.

  float[] embedding = {1f,2f,3f,4f,5f,6f,7f,8f,9f,10f};
  var queryDef = new QueryDefinition(
      query: $"SELECT c.title, VectorDistance(c.contentVector,@embedding) AS SimilarityScore FROM c ORDER BY VectorDistance(c.contentVector,@embedding)"
      ).WithParameter("@embedding", embedding);
  using FeedIterator<Object> feed = container.GetItemQueryIterator<Object>(
      queryDefinition: queryDef
  );
  while (feed.HasMoreResults) 
  {
      FeedResponse<Object> response = await feed.ReadNextAsync();
      foreach ( Object item in response)
      {
          Console.WriteLine($"Found item:\t{item}");
      }
  }

다음 단계