LanceDBのRust APIで全文検索,ベクトル検索,ハイブリッド検索をする
LanceDBのRust APIを使って,全文検索,ベクトル検索,ハイブリッド検索を試します。
LanceDBのPythonSDKで全文検索,ベクトル検索,ハイブリッド検索をするのRust版です。
公式ドキュメントにRustのサンプルは少ないですが,GitHubリポジトリのexamplesがあります。
準備
Cargo.tomlに依存関係を追加します。arrow-array
のバージョンは,LanceDBが依存しているバージョンに合わせます。また,embeddingにSentence Transformersを使用するために,lancedb
のsentence-transformers
featureを有効にします。
[]
= "55.2.0"
= "55.2.0"
= "0.3.31"
= "0.32.0"
= { = "0.21.2", = ["sentence-transformers"] }
= { = "1", = ["full"] }
テーブルを作成して,初期データを投入します。テーブルスキーマは,Apache Arrow Schemaで定義します。
async
全文検索用のインデックス作成
Table.create_index
メソッドで,movie
カラムに対して全文検索インデックスを作成します。index
引数にIndex::FTS
を指定すると全文検索インデックスが作成されます。
table
.create_index
.execute
.await?;
(オプショナル) ANNインデックス作成
Table.create_index
メソッドで,embeddings
カラムに対してANNインデックスを作成します。index
引数にIndex::IvfFlat
を指定するとInverted File Flatインデックスが作成されます。ここでは,ドキュメント数が少ないのでコメントアウト。
// table
// .create_index(
// &["embeddings"],
// Index::IvfFlat(IvfFlatIndexBuilder::default()),
// )
// .execute()
// .await?;
検索する
Table.query
メソッドを使用して検索を行います。結果は,ArrowのRecordBatch
で返されます。
全文検索
Query.full_text_search
メソッドに全文検索クエリFullTextSearchQuery
を指定します。
println!;
let fts_query = new;
let results = table
.query
.full_text_search
.limit
.execute
.await?
.
.await?;
for batch in results
Full-text search results:
Parasite is Bong Joon-ho's satirical thriller that made history at the Academy Awards.
"history"という検索キーワードを含む映画だけがヒットする。
ベクトル検索
Query.nearest_to
メソッドにクエリembeddingを指定するとベクトル検索になります。Python版の場合,クエリembeddingは,カラムに紐づけたembedding functionで暗黙的に計算されますが,Rust版だと自分で計算する必要があります。
println!;
// クエリembeddingの計算
let vector_query = embedding
.compute_query_embeddings?;
let results = table
.query
.nearest_to?
.limit
.execute
.await?
.
.await?;
for batch in results
Vector search results:
Casablanca is a timeless romantic drama known for its iconic lines and performances.
The Dark Knight, directed by Christopher Nolan, is hailed for its dark themes and iconic villain.
Parasite is Bong Joon-ho's satirical thriller that made history at the Academy Awards.
ふんわり,"history"に関連しそうな映画がヒットする。なぜか,Python版と検索結果が違う・・・。
ハイブリッド検索
ハイブリッド検索のサンプルはドキュメントにもAPIリファレンスにも見つからなかったので,ソースコードを見ながら実装してみました。
Query.nearest_to
メソッドとQuery.full_text_search
メソッドでそれぞれクエリembeddingと全文検索クエリを渡して,execute
の代わりにexecute_hybrid
メソッドを呼び出すことでハイブリッド検索ができるようです。APIが少し落ち着かない感じ。
println!;
let results = table
.query
.nearest_to?
.full_text_search
.limit
.execute_hybrid
.await?
.
.await?;
for batch in results
Hybrid search results:
Parasite is Bong Joon-ho's satirical thriller that made history at the Academy Awards.
Casablanca is a timeless romantic drama known for its iconic lines and performances.
The Dark Knight, directed by Christopher Nolan, is hailed for its dark themes and iconic villain.
返ってくる結果セットはベクトル検索と一緒だけど,"history"という検索キーワードを含む映画が1位にヒットしている。