Indexování a dotazování vektorů ve službě Azure Cosmos DB for NoSQL v Javě

PLATÍ PRO: NoSQL

Vektorové vyhledávání ve službě Azure Cosmos DB for NoSQL je aktuálně funkce ve verzi Preview. Před použitím musíte zaregistrovat verzi Preview. Tento článek popisuje následující kroky:

  1. Registrace verze Preview služby Vector Search ve službě Azure Cosmos DB for NoSQL
  2. Nastavení kontejneru Azure Cosmos DB pro vektorové vyhledávání
  3. Zásady vkládání vektorů pro vytváření
  4. Přidání vektorových indexů do zásad indexování kontejnerů
  5. Vytvoření kontejneru s vektorovými indexy a zásadami vkládání vektorů
  6. Provádění vektorového vyhledávání uložených dat
  7. Tato příručka vás provede procesem vytváření vektorových dat, indexováním dat a dotazováním dat v kontejneru.

Požadavky

Registrace verze Preview

Vektorové vyhledávání služby Azure Cosmos DB for NoSQL vyžaduje registraci funkcí ve verzi Preview. Pokud se chcete zaregistrovat, postupujte následovně:

  1. Přejděte na stránku prostředku Azure Cosmos DB for NoSQL.

  2. V položce nabídky Nastavení vyberte podokno Funkce.

  3. Vyberte možnost Vektorové vyhledávání ve službě Azure Cosmos DB for NoSQL.

  4. Přečtěte si popis funkce a potvrďte, že se chcete zaregistrovat ve verzi Preview.

  5. Výběrem možnosti Povolit se zaregistrujte ve verzi Preview.

Poznámka:

Žádost o registraci bude automaticky schválena, ale může trvat několik minut, než se projeví.

Následující kroky předpokládají, že víte, jak nastavit účet NoSQL služby Cosmos DB a vytvořit databázi. Funkce vektorového vyhledávání se v současné době nepodporuje u existujících kontejnerů, takže je potřeba vytvořit nový kontejner a zadat zásadu vkládání vektorů na úrovni kontejneru a zásadu indexování vektorů při vytváření kontejneru.

Podívejme se na příklad vytvoření databáze pro internetový knihkupectví a pro každou knihu ukládáte název, autor, ISBN a popis. Definujeme také dvě vlastnosti, které mají obsahovat vektorové vkládání. První je vlastnost contentVector, která obsahuje vložené texty vygenerované z textového obsahu knihy (například zřetězení vlastnosti "title" "author" "isbn" a "description" před vytvořením vkládání). Druhá je "coverImageVector", která je generována z obrázků na titulní straně knihy.

  1. Vytvořte a uložte vkládání vektorů pro pole, na kterých chcete provádět vektorové vyhledávání.
  2. Zadejte cesty pro vkládání vektorů v zásadách vkládání vektorů.
  3. Do zásad indexování kontejneru zahrňte všechny indexy požadovaných vektorů.

V dalších částech tohoto článku se podíváme na následující strukturu položek uložených v našem kontejneru:

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

Nejprve vytvořte CosmosContainerProperties objekt.

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

Vytvoření zásady vkládání vektorů pro kontejner

Dále je potřeba definovat zásadu vektoru kontejneru. Tato zásada poskytuje informace, které slouží k informování dotazovacího stroje Azure Cosmos DB, jak zpracovávat vlastnosti vektoru v systémových funkcích VectorDistance. To také informuje zásadu indexování vektorů o nezbytných informacích, pokud se rozhodnete určit jednu. Do zásad obsažených vektorů jsou zahrnuty následující informace:

  • "path": Cesta vlastnosti, která obsahuje vektory
  • "datatype": Typ prvků vektoru (výchozí float32)
  • "dimenze": Délka každého vektoru v cestě (výchozí hodnota 1536)
  • "distanceFunction": Metrika použitá k výpočtu vzdálenosti/podobnosti (výchozí kosinus)

V našem příkladu s podrobnostmi o knize může zásada vektoru vypadat jako příklad JSON:

// 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);

Vytvoření vektorového indexu v zásadách indexování

Po rozhodnutí o cestách vkládání vektorů je potřeba do zásad indexování přidat vektorové indexy. Funkce vektorového vyhledávání pro Azure Cosmos DB for NoSQL se v současné době podporuje jenom u nových kontejnerů, takže během vytváření kontejneru je potřeba použít zásadu vektoru a později ji nejde upravit. V tomto příkladu by zásady indexování vypadaly přibližně takto:

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

Nakonec vytvořte kontejner se zásadami indexu kontejneru a zásadami indexu vektoru.

database.createContainer(collectionDefinition).block();

Důležité

Vektorová cesta přidaná do oddílu "excludedPaths" zásad indexování, aby se zajistil optimalizovaný výkon pro vložení. Přidáním vektorové cesty do vyloučených cest způsobíte vyšší poplatky za RU a latenci při vkládání vektorů.

Důležité

V současné době se vektorové vyhledávání ve službě Azure Cosmos DB for NoSQL podporuje pouze u nových kontejnerů. Během vytváření kontejneru je potřeba nastavit zásady vektoru kontejneru i všechny zásady indexování vektorů, protože je nelze později upravovat. Obě zásady budou možné upravit v budoucím vylepšení funkce Preview.

Spuštění vyhledávacího dotazu vektorové podobnosti

Po vytvoření kontejneru s požadovanými zásadami vektoru a vložením vektorových dat do kontejneru můžete provést vektorové vyhledávání pomocí systémové funkce Vektorová vzdálenost v dotazu. Předpokládejme, že chcete hledat knihy o receptech na jídlo tak, že se podíváte na popis, musíte nejdřív získat vkládání textu dotazu. V tomto případě můžete chtít vygenerovat vkládání textu dotazu – "recept na jídlo". Jakmile budete mít vložený vyhledávací dotaz, můžete ho použít ve funkci VectorDistance ve vektorovém vyhledávacím dotazu a získat všechny položky, které jsou podobné vašemu dotazu, jak je znázorněno tady:

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

Tento dotaz načte názvy knih spolu se skóre podobnosti vzhledem k vašemu dotazu. Tady je příklad v Javě:

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()));
  }

Další kroky