Apache Cassandra
本節將引導您設定 CassandraVectorStore
,以儲存文件嵌入並執行相似性搜尋。
什麼是 Apache Cassandra ?
Apache Cassandra® 是一個真正的開放原始碼分散式資料庫,以其線性擴展性、經驗證的容錯能力和低延遲而聞名,使其成為任務關鍵型交易資料的完美平台。
其向量相似性搜尋 (VSS) 基於 JVector 函式庫,確保一流的效能和相關性。
在 Apache Cassandra 中執行向量搜尋非常簡單,如下所示:
SELECT content FROM table ORDER BY content_vector ANN OF query_embedding ;
更多相關文件請參閱此處。
此 Spring AI 向量儲存區旨在適用於全新的 RAG 應用程式,並且能夠追溯調整到現有的資料和表格之上。
此儲存區也可用於現有資料庫中非 RAG 的使用案例,例如語意搜尋、地理鄰近度搜尋等。
儲存區將根據其配置自動建立或增強架構。如果您不希望進行架構修改,請將儲存區配置為 disallowSchemaChanges
。
當使用 spring-boot-autoconfigure 時,根據 Spring Boot 標準,disallowSchemaChanges
預設為 true,您必須透過在適當的建構函式中指定 initializeSchema
布林值,或在 application.properties
檔案中設定 …initialize-schema=true
來選擇加入架構建立/修改。
什麼是 JVector ?
JVector 是一個純 Java 嵌入式向量搜尋引擎。
它在其他 HNSW 向量相似性搜尋實作中脫穎而出,因為它具有:
-
演算法快速。JVector 使用受 DiskANN 和相關研究啟發的最先進圖形演算法,提供高召回率和低延遲。
-
實作快速。JVector 使用 Panama SIMD API 加速索引建立和查詢。
-
記憶體效率高。JVector 使用產品量化壓縮向量,以便它們在搜尋期間可以保留在記憶體中。(作為我們 PQ 實作的一部分,我們的 SIMD 加速 kmeans 類別比 Apache Commons Math 中的快 5 倍。)
-
磁碟感知。JVector 的磁碟佈局旨在在查詢時執行最少必要的 iops。
-
並行。索引建立線性擴展到至少 32 個執行緒。執行緒數量加倍,建置時間減半。
-
增量。在建置索引時查詢您的索引。在新增向量和能夠在搜尋結果中找到它之間沒有延遲。
-
易於嵌入。API 設計旨在方便嵌入,供在生產環境中使用它的人員使用。
依賴關係
將這些依賴項新增至您的專案
-
僅適用於 Cassandra 向量儲存區
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-cassandra-store</artifactId>
</dependency>
-
或者,對於 RAG 應用程式中所需的一切(使用預設 ONNX 嵌入模型)
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-cassandra-store-spring-boot-starter</artifactId>
</dependency>
請參閱依賴項管理章節,將 Spring AI BOM 新增至您的建置檔案。 |
配置屬性
您可以使用 Spring Boot 配置中的以下屬性來自訂 Apache Cassandra 向量儲存區。
屬性 | 預設值 |
---|---|
|
springframework |
|
ai_vector_store |
|
false |
|
|
|
content |
|
embedding |
|
false |
|
16 |
用法
建立連線到您的 Apache Cassandra 資料庫的 CassandraVectorStore 實例
@Bean
public VectorStore vectorStore(EmbeddingModel embeddingModel) {
CassandraVectorStoreConfig config = CassandraVectorStoreConfig.builder().build();
return new CassandraVectorStore(config, embeddingModel);
}
預設配置連線到 |
Cassandra Java Driver 最容易透過類別路徑上的 |
然後在您的主要程式碼中,建立一些文件
List<Document> documents = List.of(
new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", Map.of("country", "UK", "year", 2020)),
new Document("The World is Big and Salvation Lurks Around the Corner", Map.of()),
new Document("You walk forward facing the past and you turn back toward the future.", Map.of("country", "NL", "year", 2023)));
現在將文件新增至您的向量儲存區
vectorStore.add(documents);
最後,檢索與查詢相似的文件
List<Document> results = vectorStore.similaritySearch(
SearchRequest.query("Spring").withTopK(5));
如果一切順利,您應該會檢索到包含文字 "Spring AI rocks!!" 的文件。
您也可以根據相似性閾值限制結果
List<Document> results = vectorStore.similaritySearch(
SearchRequest.query("Spring").withTopK(5)
.withSimilarityThreshold(0.5d));
中繼資料篩選
您也可以將通用的、可移植的 中繼資料篩選器 與 CassandraVectorStore 一起使用。中繼資料欄必須在 CassandraVectorStoreConfig
中配置。
例如,您可以使用文字表達式語言
vectorStore.similaritySearch(
SearchRequest.query("The World").withTopK(TOP_K)
.withFilterExpression("country in ['UK', 'NL'] && year >= 2020"));
或以程式設計方式使用表達式 DSL
Filter.Expression f = new FilterExpressionBuilder()
.and(f.in("country", "UK", "NL"), this.f.gte("year", 2020)).build();
vectorStore.similaritySearch(
SearchRequest.query("The World").withTopK(TOP_K)
.withFilterExpression(f));
可移植的篩選表達式會自動轉換為 CQL 查詢。
為了使中繼資料欄可搜尋,它們必須是主鍵或 SAI 索引。若要將非主鍵欄編製索引,請使用 SchemaColumnTags.INDEXED
配置中繼資料欄。
進階範例:基於完整 Wikipedia 資料集的向量儲存區
以下範例示範如何在現有架構上使用儲存區。在此範例中,我們使用 github.com/datastax-labs/colbert-wikipedia-data 專案中的架構,該架構隨附已為您向量化的完整 wikipedia 資料集。
用法
首先在 Cassandra 資料庫中建立架構
wget https://s.apache.org/colbert-wikipedia-schema-cql -O colbert-wikipedia-schema.cql
cqlsh -f colbert-wikipedia-schema.cql
然後像這樣配置儲存區
@Bean
public CassandraVectorStore store(EmbeddingModel embeddingModel) {
List<SchemaColumn> partitionColumns = List.of(new SchemaColumn("wiki", DataTypes.TEXT),
new SchemaColumn("language", DataTypes.TEXT), new SchemaColumn("title", DataTypes.TEXT));
List<SchemaColumn> clusteringColumns = List.of(new SchemaColumn("chunk_no", DataTypes.INT),
new SchemaColumn("bert_embedding_no", DataTypes.INT));
List<SchemaColumn> extraColumns = List.of(new SchemaColumn("revision", DataTypes.INT),
new SchemaColumn("id", DataTypes.INT));
CassandraVectorStoreConfig conf = CassandraVectorStoreConfig.builder()
.withKeyspaceName("wikidata")
.withTableName("articles")
.withPartitionKeys(partitionColumns)
.withClusteringKeys(clusteringColumns)
.withContentColumnName("body")
.withEmbeddingColumndName("all_minilm_l6_v2_embedding")
.withIndexName("all_minilm_l6_v2_ann")
.disallowSchemaChanges()
.addMetadataColumns(extraColumns)
.withPrimaryKeyTranslator((List<Object> primaryKeys) -> {
// the deliminator used to join fields together into the document's id is arbitary
// here "§¶" is used
if (primaryKeys.isEmpty()) {
return "test§¶0";
}
return format("%s§¶%s", primaryKeys.get(2), primaryKeys.get(3));
})
.withDocumentIdTranslator((id) -> {
String[] parts = id.split("§¶");
String title = parts[0];
int chunk_no = 0 < parts.length ? Integer.parseInt(parts[1]) : 0;
return List.of("simplewiki", "en", title, chunk_no, 0);
})
.build();
return new CassandraVectorStore(conf, embeddingModel());
}
@Bean
public EmbeddingModel embeddingModel() {
// default is ONNX all-MiniLM-L6-v2 which is what we want
return new TransformersEmbeddingModel();
}
完整 wikipedia 資料集
而且,如果您想要載入完整的 wikipedia 資料集。首先從此連結下載 simplewiki-sstable.tar
s.apache.org/simplewiki-sstable-tar 。這需要一些時間,檔案大小為數十 GB。
tar -xf simplewiki-sstable.tar -C ${CASSANDRA_DATA}/data/wikidata/articles-*/
nodetool import wikidata articles ${CASSANDRA_DATA}/data/wikidata/articles-*/
如果您的表格中已有現有資料,您會想要檢查 tarball 的檔案在執行 tar 時是否會覆蓋現有的 sstable。 |
nodetool import 的替代方法是重新啟動 Cassandra。 |
如果索引中有任何失敗,它們將會自動重建。 |