mirror of
https://github.com/lancedb/lancedb.git
synced 2025-12-26 22:59:57 +00:00
docs: add links to rust SDK docs, remove references to rust SDK being unstable / experimental (#1131)
This commit is contained in:
@@ -27,7 +27,6 @@ theme:
|
||||
- content.tabs.link
|
||||
- content.action.edit
|
||||
- toc.follow
|
||||
# - toc.integrate
|
||||
- navigation.top
|
||||
- navigation.tabs
|
||||
- navigation.tabs.sticky
|
||||
@@ -64,7 +63,7 @@ plugins:
|
||||
add_image: True # Automatically add meta image
|
||||
add_keywords: True # Add page keywords in the header tag
|
||||
add_share_buttons: True # Add social share buttons
|
||||
add_authors: False # Display page authors
|
||||
add_authors: False # Display page authors
|
||||
add_desc: False
|
||||
add_dates: False
|
||||
|
||||
@@ -140,11 +139,13 @@ nav:
|
||||
- Serverless Website Chatbot: examples/serverless_website_chatbot.md
|
||||
- YouTube Transcript Search: examples/youtube_transcript_bot_with_nodejs.md
|
||||
- TransformersJS Embedding Search: examples/transformerjs_embedding_search_nodejs.md
|
||||
- 🦀 Rust:
|
||||
- Overview: examples/examples_rust.md
|
||||
- 💭 FAQs: faq.md
|
||||
- ⚙️ API reference:
|
||||
- 🐍 Python: python/python.md
|
||||
- 👾 JavaScript: javascript/modules.md
|
||||
- 🦀 Rust: https://docs.rs/vectordb/latest/vectordb/
|
||||
- 🦀 Rust: https://docs.rs/lancedb/latest/lancedb/
|
||||
- ☁️ LanceDB Cloud:
|
||||
- Overview: cloud/index.md
|
||||
- API reference:
|
||||
@@ -188,21 +189,21 @@ nav:
|
||||
- Pydantic: python/pydantic.md
|
||||
- Voxel51: integrations/voxel51.md
|
||||
- PromptTools: integrations/prompttools.md
|
||||
- Python examples:
|
||||
- Examples:
|
||||
- examples/index.md
|
||||
- YouTube Transcript Search: notebooks/youtube_transcript_search.ipynb
|
||||
- Documentation QA Bot using LangChain: notebooks/code_qa_bot.ipynb
|
||||
- Multimodal search using CLIP: notebooks/multimodal_search.ipynb
|
||||
- Serverless QA Bot with S3 and Lambda: examples/serverless_lancedb_with_s3_and_lambda.md
|
||||
- Serverless QA Bot with Modal: examples/serverless_qa_bot_with_modal_and_langchain.md
|
||||
- Javascript examples:
|
||||
- Overview: examples/examples_js.md
|
||||
- YouTube Transcript Search: examples/youtube_transcript_bot_with_nodejs.md
|
||||
- YouTube Transcript Search (JS): examples/youtube_transcript_bot_with_nodejs.md
|
||||
- Serverless Chatbot from any website: examples/serverless_website_chatbot.md
|
||||
- TransformersJS Embedding Search: examples/transformerjs_embedding_search_nodejs.md
|
||||
- API reference:
|
||||
- Overview: api_reference.md
|
||||
- Python: python/python.md
|
||||
- Javascript: javascript/modules.md
|
||||
- Rust: https://docs.rs/lancedb/latest/lancedb/index.html
|
||||
- LanceDB Cloud:
|
||||
- Overview: cloud/index.md
|
||||
- API reference:
|
||||
|
||||
@@ -19,39 +19,61 @@ Lance supports `IVF_PQ` index type by default.
|
||||
|
||||
=== "Python"
|
||||
|
||||
Creating indexes is done via the [create_index](https://lancedb.github.io/lancedb/python/#lancedb.table.LanceTable.create_index) method.
|
||||
Creating indexes is done via the [create_index](https://lancedb.github.io/lancedb/python/#lancedb.table.LanceTable.create_index) method.
|
||||
|
||||
```python
|
||||
import lancedb
|
||||
import numpy as np
|
||||
uri = "data/sample-lancedb"
|
||||
db = lancedb.connect(uri)
|
||||
```python
|
||||
import lancedb
|
||||
import numpy as np
|
||||
uri = "data/sample-lancedb"
|
||||
db = lancedb.connect(uri)
|
||||
|
||||
# Create 10,000 sample vectors
|
||||
data = [{"vector": row, "item": f"item {i}"}
|
||||
# Create 10,000 sample vectors
|
||||
data = [{"vector": row, "item": f"item {i}"}
|
||||
for i, row in enumerate(np.random.random((10_000, 1536)).astype('float32'))]
|
||||
|
||||
# Add the vectors to a table
|
||||
tbl = db.create_table("my_vectors", data=data)
|
||||
# Add the vectors to a table
|
||||
tbl = db.create_table("my_vectors", data=data)
|
||||
|
||||
# Create and train the index - you need to have enough data in the table for an effective training step
|
||||
tbl.create_index(num_partitions=256, num_sub_vectors=96)
|
||||
```
|
||||
# Create and train the index - you need to have enough data in the table for an effective training step
|
||||
tbl.create_index(num_partitions=256, num_sub_vectors=96)
|
||||
```
|
||||
|
||||
=== "Typescript"
|
||||
|
||||
```typescript
|
||||
--8<--- "docs/src/ann_indexes.ts:import"
|
||||
```typescript
|
||||
--8<--- "docs/src/ann_indexes.ts:import"
|
||||
|
||||
--8<-- "docs/src/ann_indexes.ts:ingest"
|
||||
```
|
||||
--8<-- "docs/src/ann_indexes.ts:ingest"
|
||||
```
|
||||
|
||||
- **metric** (default: "L2"): The distance metric to use. By default it uses euclidean distance "`L2`".
|
||||
=== "Rust"
|
||||
|
||||
```rust
|
||||
--8<-- "rust/lancedb/examples/ivf_pq.rs:create_index"
|
||||
```
|
||||
|
||||
IVF_PQ index parameters are more fully defined in the [crate docs](https://docs.rs/lancedb/latest/lancedb/index/vector/struct.IvfPqIndexBuilder.html).
|
||||
|
||||
The following IVF_PQ paramters can be specified:
|
||||
|
||||
- **distance_type**: The distance metric to use. By default it uses euclidean distance "`L2`".
|
||||
We also support "cosine" and "dot" distance as well.
|
||||
- **num_partitions** (default: 256): The number of partitions of the index.
|
||||
- **num_sub_vectors** (default: 96): The number of sub-vectors (M) that will be created during Product Quantization (PQ).
|
||||
For D dimensional vector, it will be divided into `M` of `D/M` sub-vectors, each of which is presented by
|
||||
a single PQ code.
|
||||
- **num_partitions**: The number of partitions in the index. The default is the square root
|
||||
of the number of rows.
|
||||
|
||||
!!! note
|
||||
|
||||
In the synchronous python SDK and node's `vectordb` the default is 256. This default has
|
||||
changed in the asynchronous python SDK and node's `lancedb`.
|
||||
|
||||
- **num_sub_vectors**: The number of sub-vectors (M) that will be created during Product Quantization (PQ).
|
||||
For D dimensional vector, it will be divided into `M` subvectors with dimension `D/M`, each of which is replaced by
|
||||
a single PQ code. The default is the dimension of the vector divided by 16.
|
||||
|
||||
!!! note
|
||||
|
||||
In the synchronous python SDK and node's `vectordb` the default is currently 96. This default has
|
||||
changed in the asynchronous python SDK and node's `lancedb`.
|
||||
|
||||
<figure markdown>
|
||||

|
||||
@@ -114,25 +136,33 @@ There are a couple of parameters that can be used to fine-tune the search:
|
||||
|
||||
=== "Python"
|
||||
|
||||
```python
|
||||
tbl.search(np.random.random((1536))) \
|
||||
.limit(2) \
|
||||
.nprobes(20) \
|
||||
.refine_factor(10) \
|
||||
.to_pandas()
|
||||
```
|
||||
```python
|
||||
tbl.search(np.random.random((1536))) \
|
||||
.limit(2) \
|
||||
.nprobes(20) \
|
||||
.refine_factor(10) \
|
||||
.to_pandas()
|
||||
```
|
||||
|
||||
```text
|
||||
```text
|
||||
vector item _distance
|
||||
0 [0.44949695, 0.8444449, 0.06281311, 0.23338133... item 1141 103.575333
|
||||
1 [0.48587373, 0.269207, 0.15095535, 0.65531915,... item 3953 108.393867
|
||||
```
|
||||
0 [0.44949695, 0.8444449, 0.06281311, 0.23338133... item 1141 103.575333
|
||||
1 [0.48587373, 0.269207, 0.15095535, 0.65531915,... item 3953 108.393867
|
||||
```
|
||||
|
||||
=== "Typescript"
|
||||
|
||||
```typescript
|
||||
--8<-- "docs/src/ann_indexes.ts:search1"
|
||||
```
|
||||
```typescript
|
||||
--8<-- "docs/src/ann_indexes.ts:search1"
|
||||
```
|
||||
|
||||
=== "Rust"
|
||||
|
||||
```rust
|
||||
--8<-- "rust/lancedb/examples/ivf_pq.rs:search1"
|
||||
```
|
||||
|
||||
Vector search options are more fully defined in the [crate docs](https://docs.rs/lancedb/latest/lancedb/query/struct.Query.html#method.nearest_to).
|
||||
|
||||
The search will return the data requested in addition to the distance of each item.
|
||||
|
||||
@@ -181,7 +211,7 @@ You can select the columns returned by the query using a select clause.
|
||||
### Why do I need to manually create an index?
|
||||
|
||||
Currently, LanceDB does _not_ automatically create the ANN index.
|
||||
LanceDB is well-optimized for kNN (exhaustive search) via a disk-based index. For many use-cases,
|
||||
LanceDB is well-optimized for kNN (exhaustive search) via a disk-based index. For many use-cases,
|
||||
datasets of the order of ~100K vectors don't require index creation. If you can live with up to
|
||||
100ms latency, skipping index creation is a simpler workflow while guaranteeing 100% recall.
|
||||
|
||||
|
||||
7
docs/src/api_reference.md
Normal file
7
docs/src/api_reference.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# API Reference
|
||||
|
||||
The API reference for the LanceDB client SDKs are available at the following locations:
|
||||
|
||||
- [Python](python/python.md)
|
||||
- [JavaScript](javascript/modules.md)
|
||||
- [Rust](https://docs.rs/lancedb/latest/lancedb/index.html)
|
||||
@@ -3,7 +3,7 @@
|
||||
!!! info "LanceDB can be run in a number of ways:"
|
||||
|
||||
* Embedded within an existing backend (like your Django, Flask, Node.js or FastAPI application)
|
||||
* Connected to directly from a client application like a Jupyter notebook for analytical workloads
|
||||
* Directly from a client application like a Jupyter notebook for analytical workloads
|
||||
* Deployed as a remote serverless database
|
||||
|
||||

|
||||
@@ -24,13 +24,11 @@
|
||||
|
||||
=== "Rust"
|
||||
|
||||
!!! warning "Rust SDK is experimental, might introduce breaking changes in the near future"
|
||||
|
||||
```shell
|
||||
cargo add vectordb
|
||||
cargo add lancedb
|
||||
```
|
||||
|
||||
!!! info "To use the vectordb create, you first need to install protobuf."
|
||||
!!! info "To use the lancedb create, you first need to install protobuf."
|
||||
|
||||
=== "macOS"
|
||||
|
||||
@@ -44,7 +42,7 @@
|
||||
sudo apt install -y protobuf-compiler libssl-dev
|
||||
```
|
||||
|
||||
!!! info "Please also make sure you're using the same version of Arrow as in the [vectordb crate](https://github.com/lancedb/lancedb/blob/main/Cargo.toml)"
|
||||
!!! info "Please also make sure you're using the same version of Arrow as in the [lancedb crate](https://github.com/lancedb/lancedb/blob/main/Cargo.toml)"
|
||||
|
||||
## Connect to a database
|
||||
|
||||
@@ -81,10 +79,11 @@ If you need a reminder of the uri, you can call `db.uri()`.
|
||||
|
||||
## Create a table
|
||||
|
||||
### Directly insert data to a new table
|
||||
### Create a table from initial data
|
||||
|
||||
If you have data to insert into the table at creation time, you can simultaneously create a
|
||||
table and insert the data to it.
|
||||
If you have data to insert into the table at creation time, you can simultaneously create a
|
||||
table and insert the data into it. The schema of the data will be used as the schema of the
|
||||
table.
|
||||
|
||||
=== "Python"
|
||||
|
||||
@@ -120,21 +119,27 @@ table and insert the data to it.
|
||||
=== "Rust"
|
||||
|
||||
```rust
|
||||
use arrow_schema::{DataType, Schema, Field};
|
||||
use arrow_array::{RecordBatch, RecordBatchIterator};
|
||||
|
||||
--8<-- "rust/lancedb/examples/simple.rs:create_table"
|
||||
```
|
||||
|
||||
If the table already exists, LanceDB will raise an error by default.
|
||||
If the table already exists, LanceDB will raise an error by default. See
|
||||
[the mode option](https://docs.rs/lancedb/latest/lancedb/connection/struct.CreateTableBuilder.html#method.mode)
|
||||
for details on how to overwrite (or open) existing tables instead.
|
||||
|
||||
!!! info "Under the hood, LanceDB converts the input data into an Apache Arrow table and persists it to disk using the [Lance format](https://www.github.com/lancedb/lance)."
|
||||
!!! Providing table records in Rust
|
||||
|
||||
The Rust SDK currently expects data to be provided as an Arrow
|
||||
[RecordBatchReader](https://docs.rs/arrow-array/latest/arrow_array/trait.RecordBatchReader.html)
|
||||
Support for additional formats (such as serde or polars) is on the roadmap.
|
||||
|
||||
!!! info "Under the hood, LanceDB reads in the Apache Arrow data and persists it to disk using the [Lance format](https://www.github.com/lancedb/lance)."
|
||||
|
||||
### Create an empty table
|
||||
|
||||
Sometimes you may not have the data to insert into the table at creation time.
|
||||
In this case, you can create an empty table and specify the schema, so that you can add
|
||||
data to the table at a later time (such that it conforms to the schema).
|
||||
data to the table at a later time (as long as it conforms to the schema). This is
|
||||
similar to a `CREATE TABLE` statement in SQL.
|
||||
|
||||
=== "Python"
|
||||
|
||||
@@ -175,7 +180,7 @@ Once created, you can open a table as follows:
|
||||
=== "Rust"
|
||||
|
||||
```rust
|
||||
--8<-- "rust/lancedb/examples/simple.rs:open_with_existing_file"
|
||||
--8<-- "rust/lancedb/examples/simple.rs:open_existing_tbl"
|
||||
```
|
||||
|
||||
If you forget the name of your table, you can always get a listing of all table names:
|
||||
@@ -254,6 +259,14 @@ Once you've embedded the query, you can find its nearest neighbors as follows:
|
||||
--8<-- "rust/lancedb/examples/simple.rs:search"
|
||||
```
|
||||
|
||||
!!! Query vectors in Rust
|
||||
Rust does not yet support automatic execution of embedding functions. You will need to
|
||||
calculate embeddings yourself. Support for this is on the roadmap and can be tracked at
|
||||
https://github.com/lancedb/lancedb/issues/994
|
||||
|
||||
Query vectors can be provided as Arrow arrays or a Vec/slice of Rust floats.
|
||||
Support for additional formats (e.g. `polars::series::Series`) is on the roadmap.
|
||||
|
||||
By default, LanceDB runs a brute-force scan over dataset to find the K nearest neighbours (KNN).
|
||||
For tables with more than 50K vectors, creating an ANN index is recommended to speed up search performance.
|
||||
LanceDB allows you to create an ANN index on a table as follows:
|
||||
@@ -277,7 +290,7 @@ LanceDB allows you to create an ANN index on a table as follows:
|
||||
```
|
||||
|
||||
!!! note "Why do I need to create an index manually?"
|
||||
LanceDB does not automatically create the ANN index, for two reasons. The first is that it's optimized
|
||||
LanceDB does not automatically create the ANN index for two reasons. The first is that it's optimized
|
||||
for really fast retrievals via a disk-based index, and the second is that data and query workloads can
|
||||
be very diverse, so there's no one-size-fits-all index configuration. LanceDB provides many parameters
|
||||
to fine-tune index size, query latency and accuracy. See the section on
|
||||
@@ -308,8 +321,9 @@ This can delete any number of rows that match the filter.
|
||||
```
|
||||
|
||||
The deletion predicate is a SQL expression that supports the same expressions
|
||||
as the `where()` clause on a search. They can be as simple or complex as needed.
|
||||
To see what expressions are supported, see the [SQL filters](sql.md) section.
|
||||
as the `where()` clause (`only_if()` in Rust) on a search. They can be as
|
||||
simple or complex as needed. To see what expressions are supported, see the
|
||||
[SQL filters](sql.md) section.
|
||||
|
||||
=== "Python"
|
||||
|
||||
@@ -319,6 +333,10 @@ To see what expressions are supported, see the [SQL filters](sql.md) section.
|
||||
|
||||
Read more: [vectordb.Table.delete](javascript/interfaces/Table.md#delete)
|
||||
|
||||
=== "Rust"
|
||||
|
||||
Read more: [lancedb::Table::delete](https://docs.rs/lancedb/latest/lancedb/table/struct.Table.html#method.delete)
|
||||
|
||||
## Drop a table
|
||||
|
||||
Use the `drop_table()` method on the database to remove a table.
|
||||
|
||||
3
docs/src/examples/examples_rust.md
Normal file
3
docs/src/examples/examples_rust.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Examples: Rust
|
||||
|
||||
Our Rust SDK is now stable. Examples are coming soon.
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
## Recipes and example code
|
||||
|
||||
LanceDB provides language APIs, allowing you to embed a database in your language of choice. We currently provide Python and Javascript APIs, with the Rust API and examples actively being worked on and will be available soon.
|
||||
LanceDB provides language APIs, allowing you to embed a database in your language of choice.
|
||||
|
||||
* 🐍 [Python](examples_python.md) examples
|
||||
* 👾 [JavaScript](exampled_js.md) examples
|
||||
* 👾 [JavaScript](examples_js.md) examples
|
||||
* 🦀 Rust examples (coming soon)
|
||||
|
||||
## Applications powered by LanceDB
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ As we mention in our talk titled “[Lance, a modern columnar data format](https
|
||||
|
||||
### Why build in Rust? 🦀
|
||||
|
||||
We believe that the Rust ecosystem has attained mainstream maturity and that Rust will form the underpinnings of large parts of the data and ML landscape in a few years. Performance, latency and reliability are paramount to a vector DB, and building in Rust allows us to iterate and release updates more rapidly due to Rust’s safety guarantees. Both Lance (the data format) and LanceDB (the database) are written entirely in Rust. We also provide Python and JavaScript client libraries to interact with the database. Our Rust API is a little rough around the edges right now, but is fast becoming on par with the Python and JS APIs.
|
||||
We believe that the Rust ecosystem has attained mainstream maturity and that Rust will form the underpinnings of large parts of the data and ML landscape in a few years. Performance, latency and reliability are paramount to a vector DB, and building in Rust allows us to iterate and release updates more rapidly due to Rust’s safety guarantees. Both Lance (the data format) and LanceDB (the database) are written entirely in Rust. We also provide Python, JavaScript, and Rust client libraries to interact with the database.
|
||||
|
||||
### What is the difference between LanceDB OSS and LanceDB Cloud?
|
||||
|
||||
@@ -44,7 +44,7 @@ For large-scale (>1M) or higher dimension vectors, it is beneficial to create an
|
||||
|
||||
### Does LanceDB support full-text search?
|
||||
|
||||
Yes, LanceDB supports full-text search (FTS) via [Tantivy](https://github.com/quickwit-oss/tantivy). Our current FTS integration is Python-only, and our goal is to push it down to the Rust level in future versions to enable much more powerful search capabilities available to our Python, JavaScript and Rust clients.
|
||||
Yes, LanceDB supports full-text search (FTS) via [Tantivy](https://github.com/quickwit-oss/tantivy). Our current FTS integration is Python-only, and our goal is to push it down to the Rust level in future versions to enable much more powerful search capabilities available to our Python, JavaScript and Rust clients. Follow along in the [Github issue](https://github.com/lancedb/lance/issues/1195)
|
||||
|
||||
### How can I speed up data inserts?
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Full-text search
|
||||
|
||||
LanceDB provides support for full-text search via [Tantivy](https://github.com/quickwit-oss/tantivy) (currently Python only), allowing you to incorporate keyword-based search (based on BM25) in your retrieval solutions. Our goal is to push the FTS integration down to the Rust level in the future, so that it's available for JavaScript users as well.
|
||||
LanceDB provides support for full-text search via [Tantivy](https://github.com/quickwit-oss/tantivy) (currently Python only), allowing you to incorporate keyword-based search (based on BM25) in your retrieval solutions. Our goal is to push the FTS integration down to the Rust level in the future, so that it's available for Rust and JavaScript users as well. Follow along at [this Github issue](https://github.com/lancedb/lance/issues/1195)
|
||||
|
||||
A hybrid search solution combining vector and full-text search is also on the way.
|
||||
|
||||
@@ -77,7 +77,7 @@ table.search("puppy").limit(10).where("meta='foo'").to_list()
|
||||
|
||||
## Phrase queries vs. terms queries
|
||||
|
||||
For full-text search you can specify either a **phrase** query like `"the old man and the sea"`,
|
||||
For full-text search you can specify either a **phrase** query like `"the old man and the sea"`,
|
||||
or a **terms** search query like `"(Old AND Man) AND Sea"`. For more details on the terms
|
||||
query syntax, see Tantivy's [query parser rules](https://docs.rs/tantivy/latest/tantivy/query/struct.QueryParser.html).
|
||||
|
||||
@@ -112,7 +112,7 @@ double quotes replaced by single quotes.
|
||||
|
||||
## Configurations
|
||||
|
||||
By default, LanceDB configures a 1GB heap size limit for creating the index. You can
|
||||
By default, LanceDB configures a 1GB heap size limit for creating the index. You can
|
||||
reduce this if running on a smaller node, or increase this for faster performance while
|
||||
indexing a larger corpus.
|
||||
|
||||
@@ -128,7 +128,6 @@ table.create_fts_index(["text1", "text2"], writer_heap_size=heap, replace=True)
|
||||
If you add data after FTS index creation, it won't be reflected
|
||||
in search results until you do a full reindex.
|
||||
|
||||
2. We currently only support local filesystem paths for the FTS index.
|
||||
2. We currently only support local filesystem paths for the FTS index.
|
||||
This is a tantivy limitation. We've implemented an object store plugin
|
||||
but there's no way in tantivy-py to specify to use it.
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ LanceDB **Cloud** is a SaaS (software-as-a-service) solution that runs serverles
|
||||
|
||||
* Fast production-scale vector similarity, full-text & hybrid search and a SQL query interface (via [DataFusion](https://github.com/apache/arrow-datafusion))
|
||||
|
||||
* Native Python and Javascript/Typescript support
|
||||
* Python, Javascript/Typescript, and Rust support
|
||||
|
||||
* Store, query & manage multi-modal data (text, images, videos, point clouds, etc.), not just the embeddings and metadata
|
||||
|
||||
@@ -54,3 +54,4 @@ The following pages go deeper into the internal of LanceDB and how to use it.
|
||||
* [Ecosystem Integrations](integrations/index.md): Integrate LanceDB with other tools in the data ecosystem
|
||||
* [Python API Reference](python/python.md): Python OSS and Cloud API references
|
||||
* [JavaScript API Reference](javascript/modules.md): JavaScript OSS and Cloud API references
|
||||
* [Rust API Reference](https://docs.rs/lancedb/latest/lancedb/index.html): Rust API reference
|
||||
|
||||
@@ -22,7 +22,7 @@ Currently, LanceDB supports the following metrics:
|
||||
## Exhaustive search (kNN)
|
||||
|
||||
If you do not create a vector index, LanceDB exhaustively scans the _entire_ vector space
|
||||
and compute the distance to every vector in order to find the exact nearest neighbors. This is effectively a kNN search.
|
||||
and computes the distance to every vector in order to find the exact nearest neighbors. This is effectively a kNN search.
|
||||
|
||||
<!-- Setup Code
|
||||
```python
|
||||
@@ -85,7 +85,7 @@ To perform scalable vector retrieval with acceptable latencies, it's common to b
|
||||
While the exhaustive search is guaranteed to always return 100% recall, the approximate nature of
|
||||
an ANN search means that using an index often involves a trade-off between recall and latency.
|
||||
|
||||
See the [IVF_PQ index](./concepts/index_ivfpq.md.md) for a deeper description of how `IVF_PQ`
|
||||
See the [IVF_PQ index](./concepts/index_ivfpq.md) for a deeper description of how `IVF_PQ`
|
||||
indexes work in LanceDB.
|
||||
|
||||
## Output search results
|
||||
@@ -184,4 +184,3 @@ Let's create a LanceDB table with a nested schema:
|
||||
|
||||
Note that in this case the extra `_distance` field is discarded since
|
||||
it's not part of the LanceSchema.
|
||||
|
||||
|
||||
165
rust/lancedb/examples/ivf_pq.rs
Normal file
165
rust/lancedb/examples/ivf_pq.rs
Normal file
@@ -0,0 +1,165 @@
|
||||
// Copyright 2024 Lance Developers.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! This example demonstrates setting advanced parameters when building an IVF PQ index
|
||||
//!
|
||||
//! Snippets from this example are used in the documentation on ANN indices.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use arrow_array::types::Float32Type;
|
||||
use arrow_array::{
|
||||
FixedSizeListArray, Int32Array, RecordBatch, RecordBatchIterator, RecordBatchReader,
|
||||
};
|
||||
use arrow_schema::{DataType, Field, Schema};
|
||||
|
||||
use futures::TryStreamExt;
|
||||
use lancedb::connection::Connection;
|
||||
use lancedb::index::vector::IvfPqIndexBuilder;
|
||||
use lancedb::index::Index;
|
||||
use lancedb::query::{ExecutableQuery, QueryBase};
|
||||
use lancedb::{connect, DistanceType, Result, Table};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
if std::path::Path::new("data").exists() {
|
||||
std::fs::remove_dir_all("data").unwrap();
|
||||
}
|
||||
let uri = "data/sample-lancedb";
|
||||
let db = connect(uri).execute().await?;
|
||||
let tbl = create_table(&db).await?;
|
||||
|
||||
create_index(&tbl).await?;
|
||||
search_index(&tbl).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_some_records() -> Result<Box<dyn RecordBatchReader + Send>> {
|
||||
const TOTAL: usize = 1000;
|
||||
const DIM: usize = 128;
|
||||
|
||||
let schema = Arc::new(Schema::new(vec![
|
||||
Field::new("id", DataType::Int32, false),
|
||||
Field::new(
|
||||
"vector",
|
||||
DataType::FixedSizeList(
|
||||
Arc::new(Field::new("item", DataType::Float32, true)),
|
||||
DIM as i32,
|
||||
),
|
||||
true,
|
||||
),
|
||||
]));
|
||||
|
||||
// Create a RecordBatch stream.
|
||||
let batches = RecordBatchIterator::new(
|
||||
vec![RecordBatch::try_new(
|
||||
schema.clone(),
|
||||
vec![
|
||||
Arc::new(Int32Array::from_iter_values(0..TOTAL as i32)),
|
||||
Arc::new(
|
||||
FixedSizeListArray::from_iter_primitive::<Float32Type, _, _>(
|
||||
(0..TOTAL).map(|_| Some(vec![Some(1.0); DIM])),
|
||||
DIM as i32,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
.unwrap()]
|
||||
.into_iter()
|
||||
.map(Ok),
|
||||
schema.clone(),
|
||||
);
|
||||
Ok(Box::new(batches))
|
||||
}
|
||||
|
||||
async fn create_table(db: &Connection) -> Result<Table> {
|
||||
let initial_data: Box<dyn RecordBatchReader + Send> = create_some_records()?;
|
||||
let tbl = db
|
||||
.create_table("my_table", Box::new(initial_data))
|
||||
.execute()
|
||||
.await
|
||||
.unwrap();
|
||||
Ok(tbl)
|
||||
}
|
||||
|
||||
async fn create_index(table: &Table) -> Result<()> {
|
||||
// --8<-- [start:create_index]
|
||||
// For this example, `table` is a lancedb::Table with a column named
|
||||
// "vector" that is a vector column with dimension 128.
|
||||
|
||||
// By default, if the column "vector" appears to be a vector column,
|
||||
// then an IVF_PQ index with reasonable defaults is created.
|
||||
table
|
||||
.create_index(&["vector"], Index::Auto)
|
||||
.execute()
|
||||
.await?;
|
||||
// For advanced cases, it is also possible to specifically request an
|
||||
// IVF_PQ index and provide custom parameters.
|
||||
table
|
||||
.create_index(
|
||||
&["vector"],
|
||||
Index::IvfPq(
|
||||
// Here we specify advanced indexing parameters. In this case
|
||||
// we are creating an index that my have better recall than the
|
||||
// default but is also larger and slower.
|
||||
IvfPqIndexBuilder::default()
|
||||
// This overrides the default distance type of L2
|
||||
.distance_type(DistanceType::Cosine)
|
||||
// With 1000 rows this have been ~31 by default
|
||||
.num_partitions(50)
|
||||
// With dimension 128 this would have been 8 by default
|
||||
.num_sub_vectors(16),
|
||||
),
|
||||
)
|
||||
.execute()
|
||||
.await?;
|
||||
// --8<-- [end:create_index]
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn search_index(table: &Table) -> Result<()> {
|
||||
// --8<-- [start:search1]
|
||||
let query_vector = [1.0; 128];
|
||||
// By default the index will find the 10 closest results using default
|
||||
// search parameters that give a reasonable tradeoff between accuracy
|
||||
// and search latency
|
||||
let mut results = table
|
||||
.vector_search(&query_vector)?
|
||||
// Note: you should always set the distance_type to match the value used
|
||||
// to train the index
|
||||
.distance_type(DistanceType::Cosine)
|
||||
.execute()
|
||||
.await?;
|
||||
while let Some(batch) = results.try_next().await? {
|
||||
println!("{:?}", batch);
|
||||
}
|
||||
// We can also provide custom search parameters. Here we perform a
|
||||
// slower but more accurate search
|
||||
let mut results = table
|
||||
.vector_search(&query_vector)?
|
||||
.distance_type(DistanceType::Cosine)
|
||||
// Override the default of 10 to get more rows
|
||||
.limit(15)
|
||||
// Override the default of 20 to search more partitions
|
||||
.nprobes(30)
|
||||
// Override the default of None to apply a refine step
|
||||
.refine_factor(1)
|
||||
.execute()
|
||||
.await?;
|
||||
while let Some(batch) = results.try_next().await? {
|
||||
println!("{:?}", batch);
|
||||
}
|
||||
Ok(())
|
||||
// --8<-- [end:search1]
|
||||
}
|
||||
@@ -12,10 +12,16 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! This example demonstrates basic usage of LanceDb.
|
||||
//!
|
||||
//! Snippets from this example are used in the quickstart documentation.
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use arrow_array::types::Float32Type;
|
||||
use arrow_array::{FixedSizeListArray, Int32Array, RecordBatch, RecordBatchIterator};
|
||||
use arrow_array::{
|
||||
FixedSizeListArray, Int32Array, RecordBatch, RecordBatchIterator, RecordBatchReader,
|
||||
};
|
||||
use arrow_schema::{DataType, Field, Schema};
|
||||
use futures::TryStreamExt;
|
||||
|
||||
@@ -58,14 +64,14 @@ async fn main() -> Result<()> {
|
||||
async fn open_with_existing_tbl() -> Result<()> {
|
||||
let uri = "data/sample-lancedb";
|
||||
let db = connect(uri).execute().await?;
|
||||
// --8<-- [start:open_with_existing_file]
|
||||
let _ = db.open_table("my_table").execute().await.unwrap();
|
||||
// --8<-- [end:open_with_existing_file]
|
||||
#[allow(unused_variables)]
|
||||
// --8<-- [start:open_existing_tbl]
|
||||
let table = db.open_table("my_table").execute().await.unwrap();
|
||||
// --8<-- [end:open_existing_tbl]
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn create_table(db: &Connection) -> Result<LanceDbTable> {
|
||||
// --8<-- [start:create_table]
|
||||
fn create_some_records() -> Result<Box<dyn RecordBatchReader + Send>> {
|
||||
const TOTAL: usize = 1000;
|
||||
const DIM: usize = 128;
|
||||
|
||||
@@ -100,33 +106,22 @@ async fn create_table(db: &Connection) -> Result<LanceDbTable> {
|
||||
.map(Ok),
|
||||
schema.clone(),
|
||||
);
|
||||
Ok(Box::new(batches))
|
||||
}
|
||||
|
||||
async fn create_table(db: &Connection) -> Result<LanceDbTable> {
|
||||
// --8<-- [start:create_table]
|
||||
let initial_data: Box<dyn RecordBatchReader + Send> = create_some_records()?;
|
||||
let tbl = db
|
||||
.create_table("my_table", Box::new(batches))
|
||||
.create_table("my_table", Box::new(initial_data))
|
||||
.execute()
|
||||
.await
|
||||
.unwrap();
|
||||
// --8<-- [end:create_table]
|
||||
|
||||
let new_batches = RecordBatchIterator::new(
|
||||
vec![RecordBatch::try_new(
|
||||
schema.clone(),
|
||||
vec![
|
||||
Arc::new(Int32Array::from_iter_values(0..TOTAL as i32)),
|
||||
Arc::new(
|
||||
FixedSizeListArray::from_iter_primitive::<Float32Type, _, _>(
|
||||
(0..TOTAL).map(|_| Some(vec![Some(1.0); DIM])),
|
||||
DIM as i32,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
.unwrap()]
|
||||
.into_iter()
|
||||
.map(Ok),
|
||||
schema.clone(),
|
||||
);
|
||||
// --8<-- [start:add]
|
||||
tbl.add(Box::new(new_batches)).execute().await.unwrap();
|
||||
let new_data = create_some_records()?;
|
||||
tbl.add(new_data).execute().await.unwrap();
|
||||
// --8<-- [end:add]
|
||||
|
||||
Ok(tbl)
|
||||
|
||||
@@ -36,8 +36,6 @@
|
||||
//!
|
||||
//! ### Quick Start
|
||||
//!
|
||||
//! <div class="warning">Rust API is not stable yet, please expect breaking changes.</div>
|
||||
//!
|
||||
//! #### Connect to a database.
|
||||
//!
|
||||
//! ```rust
|
||||
|
||||
Reference in New Issue
Block a user