????????鑒于Milvus仍在不停的迭代新版本,推出新功能,其SDK目前并不穩定。目前其2.4版本的SDK接口已與之前的2.2版本有了較大的差別,功能上也有了一定的調整。為此,我們重新提供了針對[Milvus2.4](https://github.com/colorknight/moql-transx/tree/master/moql-querier-milvus2.4)版本的語法轉換功能。由于Milvus文檔有些內容寫的不是特別詳實,亦或時間倉促,我們沒有正確理解其功能含義,轉換工作可能存在一些問題,還請發現問題的朋友多多指出。
? ? ? ?我們選擇Milvus2.4版本進行語法支持的主要原因是,2.4版本是Milvus目前最新的版本,該版本引入了可以建立多個向量索引的能力。在微軟推出的GraphRAG技術中,用到了多向量檢索的技術,而Milvus2.2版只支持單向量,無法復刻GraphRAG的技術理念。為此,我們選中了2.4版本進行語法支持。對于未來Milvus版本發生改變,我們是否能及時支持,主要取決于我們在HuggingFists項目中是否會用到這樣的技術特性。本次升級的主要動力來自于我們希望使用HuggingFists采用低代碼方式來實踐GraphRAG項目中的技術理念。當然,如果有朋友對未來某個版本有語法轉換需求也可以給我們提出需求,我們會盡量滿足。?
????????言歸正傳,為了能讓使用者以類似訪問關系數據庫的交互體驗訪問Milvus向量數據庫。MOQL Transx繼續秉承能SQL化檢索數據庫就SQL化檢索數據庫的宗旨。為用戶提供了一套可以檢索Milvus2.4向量數據庫的SQL語法,并提供了檢索接口。使用者可通過該接口輸入SQL語句,獲得結構化的數據結果,如下列代碼示例:
// 構建Milvus客戶端
String url = String.format("%s://%s:%d", "http" ,"datayoo05", 19530);
ConnectConfig connectConfig = ConnectConfig.builder().uri(url).build();
milvusClient = new MilvusClientV2(connectConfig);
// 裝載Collection
LoadCollectionReq loadCollectionReq = LoadCollectionReq.builder().collectionName("hybrid_search_collection").build();
milvusClient.loadCollection(loadCollectionReq);
// 使用Milvus客戶端創建Milvus查詢器
MilvusQuerier milvusQuerier = new MilvusQuerier(milvusClient);
String sql = "select * from hybrid_search_collection a, "
// 用子檢索語句檢索向量字段
+ "(select * from hybrid_search_collection where vmatch(dense, 'L2', '[[1.0, 2.0, 3.0],[1.1,2.1,3.1]]')) b, "
// 用子檢索語句檢索稀疏向量
+ "(select * from hybrid_search_collection where vmatch(sparse, 'IP', '[{\"2\":0.1764169}, {\"5\":0.1764169}]')) c limit 5";
// 檢索Collection
RecordSet recordSet = milvusQuerier.query(sql);
????????Milvus2.4的SDK相較Milvus2.2有了不少改變,主要是方法參數上的變動比較大。比如Milvus2.2中SearchParam在Milvus2.4中變成了SearchReq。但SDK的整體思路沒有太大的變化,我們在這里就不再贅述了。下表將給出Milvus2.4查詢接口的參數與SQL語法的對照關系,其中的粗體為Milvus2.4新增的檢索能力,刪除線標記的語法部分在Milvus2.2中有效,由于未在2.4的文檔中找到相應的說明,故標為刪除:
Milvus查詢參數接口 | SQL語法 |
---|---|
collectionName(table) | from table |
outFields(outFields) | select outFields |
filter(expr) | where expr |
annsField, params:metric_type, data | vMatch(fieldName, metricType, vectors) |
consistencyLevel | consistencyLevel(['STRONG'|'BOUNDED'|'Eventually']) |
topK(k) | limit offset, k |
offset(o) | limit offset, k |
params:nProbe | nProbe(long) |
params:ef | ef(long) |
params:search_k | searchK(long) |
partitionNames | partitionBy(String[]) |
roundDecimal | roundDecimal(int) |
travelTimestamp | travelTimestamp(long) |
guaranteeTimestamp | guaranteeTimestamp(long) |
range | searchRange(metricType, radius, rangeFilter) |
group | group by fieldName |
dropRatio | dropRatioSearch(dropRatio) |
searchRequests | from table, [queryExpression]{0,10} |
ranker | rrfRanker(k), weightedRanker(float[]) |
( 注:queryExpression是一個表示向量檢索的子SQL語句)