Udostępnij przez


Indeksowanie i wektory zapytań w usłudze Azure Cosmos DB for NoSQL w języku Java

W tym artykule wyjaśniono, jak tworzyć dane wektorowe, indeksować dane, a następnie wykonywać zapytania dotyczące danych w kontenerze.

Przed rozpoczęciem korzystania z indeksowania wektorów i wyszukiwania należy najpierw włączyć wyszukiwanie wektorów w usłudze Azure Cosmos DB for NoSQL. Po skonfigurowaniu kontenera usługi Azure Cosmos DB na potrzeby wyszukiwania wektorowego należy utworzyć zasady osadzania wektorów. Następnie do zasad indeksowania kontenerów zostaną dodane indeksy wektorowe. Następnie utworzysz kontener z indeksami wektorowymi i zasadami osadzania wektorów. Na koniec przeprowadzasz wyszukiwanie wektorowe na przechowywanych danych.

Wymagania wstępne

  • Istniejące konto usługi Azure Cosmos DB for NoSQL.
    • Jeśli nie masz subskrypcji platformy Azure, możesz go utworzyć bezpłatnie.
    • Jeśli masz istniejącą subskrypcję platformy Azure, utwórz nowe konto usługi Azure Cosmos DB for NoSQL.
  • Najnowsza wersja zestawu Java SDK usługi Azure Cosmos DB.

Włączanie funkcji

Aby włączyć wyszukiwanie wektorów dla usługi Azure Cosmos DB dla NoSQL, wykonaj następujące kroki:

  1. Przejdź do strony zasobów usługi Azure Cosmos DB for NoSQL.
  2. W okienku po lewej stronie w obszarze Ustawienia wybierz pozycję Funkcje.
  3. Wybierz Vector Search for NoSQL API.
  4. Przeczytaj opis funkcji, aby potwierdzić, że chcesz ją włączyć.
  5. Wybierz pozycję Włącz , aby włączyć wyszukiwanie wektorów w usłudze Azure Cosmos DB for NoSQL.

Wskazówka

Możesz też użyć interfejsu wiersza polecenia platformy Azure, aby zaktualizować możliwości twojego konta w celu obsługi wyszukiwania wektorowego usługi Azure Cosmos DB for NoSQL.

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

Żądanie rejestracji zostanie automatycznie zatwierdzone, ale może upłynąć 15 minut.

W poniższych krokach założono, że wiesz, jak skonfigurować konto usługi Azure Cosmos DB dla noSQL i utworzyć bazę danych. Funkcja wyszukiwania wektorowego nie jest obecnie obsługiwana w istniejących kontenerach. Musisz utworzyć nowy kontener. Podczas tworzenia kontenera należy określić zasady osadzania wektora na poziomie kontenera i zasady indeksowania wektorów.

Przyjrzyjmy się przykładowi tworzenia bazy danych dla internetowej księgarni. Chcesz przechowywać informacje o tytułach, autorach, ISBN i opisach dla każdej książki. Należy również zdefiniować następujące dwie właściwości, aby zawierały osadzanie wektorów:

  • Właściwość contentVector zawiera osadzanie tekstu generowane na podstawie zawartości tekstowej książki. Na przykład łączysz właściwości title, author, isbn i description przed utworzeniem osadzenia.
  • Właściwość coverImageVector jest generowana z obrazów okładki książki.

Aby przeprowadzić wyszukiwanie wektorowe, należy wykonać następujące czynności:

  1. Twórz i przechowuj wektorowe osadzania dla pól, na których chcesz przeprowadzić wyszukiwanie wektorów.
  2. Określ ścieżki osadzania wektorów w zasadach osadzania wektorów.
  3. Uwzględnij wszystkie indeksy wektorów, które mają zostać uwzględnione w zasadach indeksowania dla kontenera.

W kolejnych sekcjach tego artykułu rozważ następującą strukturę elementów przechowywanych w kontenerze:

{
  "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] 
} 

Najpierw utwórz CosmosContainerProperties obiekt.

CosmosContainerProperties collectionDefinition = new CosmosContainerProperties(UUID.randomUUID().toString(), "Partition_Key_Def");

Tworzenie zasad osadzania wektorów dla kontenera

Teraz należy zdefiniować zasady wektora kontenera. Te zasady zawierają informacje, które informują aparat zapytań usługi Azure Cosmos DB o sposobie obsługi właściwości wektorów w funkcjach VectorDistance systemowych. Te zasady zawierają również niezbędne informacje dotyczące zasad indeksowania wektorów, jeśli zdecydujesz się je określić.

Następujące informacje są zawarte w zasadach wektora kontenera:

Parameter Description
path Ścieżka właściwości zawierająca wektory.
datatype Typ elementów wektora. Wartość domyślna to Float32.
dimensions Długość każdego wektora w ścieżce. Wartość domyślna to 1536.
distanceFunction Metryka używana do obliczania odległości/podobieństwa. Wartość domyślna to Cosine.

W przykładzie ze szczegółami książki zasady wektorów mogą wyglądać jak poniższy przykład.

// Creating vector embedding policy
CosmosVectorEmbeddingPolicy cosmosVectorEmbeddingPolicy = new CosmosVectorEmbeddingPolicy();

CosmosVectorEmbedding embedding1 = new CosmosVectorEmbedding();
embedding1.setPath("/coverImageVector");
embedding1.setDataType(CosmosVectorDataType.FLOAT32);
embedding1.setDimensions(8L);
embedding1.setDistanceFunction(CosmosVectorDistanceFunction.COSINE);

CosmosVectorEmbedding embedding2 = new CosmosVectorEmbedding();
embedding2.setPath("/contentVector");
embedding2.setDataType(CosmosVectorDataType.FLOAT32);
embedding2.setDimensions(10L);
embedding2.setDistanceFunction(CosmosVectorDistanceFunction.DOT_PRODUCT);

cosmosVectorEmbeddingPolicy.setCosmosVectorEmbeddings(Arrays.asList(embedding1, embedding2, embedding3));

collectionDefinition.setVectorEmbeddingPolicy(cosmosVectorEmbeddingPolicy);

Tworzenie indeksu wektorowego w zasadach indeksowania

Po podjęciu decyzji o ścieżkach osadzania wektorów należy dodać indeksy wektorów do zasad indeksowania. Obecnie funkcja wyszukiwania wektorowego dla usługi Azure Cosmos DB for NoSQL jest obsługiwana tylko w nowych kontenerach. Podczas tworzenia kontenera stosuje się zasady wektorów. Nie można później modyfikować zasad. Zasady indeksowania wyglądają podobnie do następującego przykładu:

IndexingPolicy indexingPolicy = new IndexingPolicy();
indexingPolicy.setIndexingMode(IndexingMode.CONSISTENT);
ExcludedPath excludedPath1 = new ExcludedPath("/coverImageVector/*");
ExcludedPath excludedPath2 = new ExcludedPath("/contentVector/*");
indexingPolicy.setExcludedPaths(ImmutableList.of(excludedPath1, excludedPath2));

IncludedPath includedPath1 = new IncludedPath("/*");
indexingPolicy.setIncludedPaths(Collections.singletonList(includedPath1));

// Creating vector indexes
CosmosVectorIndexSpec cosmosVectorIndexSpec1 = new CosmosVectorIndexSpec();
cosmosVectorIndexSpec1.setPath("/coverImageVector");
cosmosVectorIndexSpec1.setType(CosmosVectorIndexType.QUANTIZED_FLAT.toString());

CosmosVectorIndexSpec cosmosVectorIndexSpec2 = new CosmosVectorIndexSpec();
cosmosVectorIndexSpec2.setPath("/contentVector");
cosmosVectorIndexSpec2.setType(CosmosVectorIndexType.DISK_ANN.toString());

indexingPolicy.setVectorIndexes(Arrays.asList(cosmosVectorIndexSpec1, cosmosVectorIndexSpec2, cosmosVectorIndexSpec3));

collectionDefinition.setIndexingPolicy(indexingPolicy);

Na koniec utwórz kontener za pomocą zasad indeksu kontenera i zasad indeksu wektora.

database.createContainer(collectionDefinition).block();

Ważne

Ścieżka wektora jest dodawana do excludedPaths sekcji zasad indeksowania w celu zapewnienia zoptymalizowanej wydajności wstawiania. Niedodanie ścieżki wektora do excludedPaths skutkuje wyższym obciążeniem jednostek żądania i opóźnieniem podczas wstawiania wektorów.

Uruchamianie zapytania wyszukiwania podobieństwa wektorów

Po utworzeniu kontenera z żądaną polityką wektorów i wstawieniu danych wektorowych do kontenera, użyj funkcji systemowej VectorDistance w zapytaniu, aby przeprowadzić wyszukiwanie wektorowe.

Załóżmy, że chcesz wyszukać książki o przepisach spożywczych, patrząc na opis. Najpierw musisz pobrać osadzanie dla tekstu zapytania. W takim przypadku możesz wygenerować osadzanie dla zapytania tekstu food recipe. Po uzyskaniu zakodowania zapytania wyszukiwania, możesz je wykorzystać w funkcji VectorDistance w zapytaniu wyszukiwania wektorowego, aby pobrać wszystkie elementy podobne do zapytania.

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])   

To zapytanie pobiera tytuły książki wraz z wynikami podobieństwa w odniesieniu do zapytania. Oto przykład w języku Java:

float[] embedding = new float[10];
for (int i = 0; i < 10; i++) {
    array[i] = i + 1;
}
ArrayList<SqlParameter> paramList = new ArrayList<SqlParameter>();
  paramList.add(new SqlParameter("@embedding", embedding));
  SqlQuerySpec querySpec = new SqlQuerySpec("SELECT c.title, VectorDistance(c.contentVector,@embedding) AS SimilarityScore  FROM c ORDER BY VectorDistance(c.contentVector,@embedding)", paramList);
  CosmosPagedIterable<Family> filteredFamilies = container.queryItems(querySpec, new CosmosQueryRequestOptions(), Family.class);

  if (filteredFamilies.iterator().hasNext()) {
      Family family = filteredFamilies.iterator().next();
      logger.info(String.format("First query result: Family with (/id, partition key) = (%s,%s)",family.getId(),family.getLastName()));
  }