Compare commits

...

4 Commits

Author SHA1 Message Date
qzhu
a503845c9f more edit 2024-11-14 13:33:25 -08:00
qzhu
955a295026 code for cloud doc 2024-11-13 22:05:09 -08:00
qzhu
b70fa3892e code for cloud doc 2024-11-13 22:03:53 -08:00
qzhu
31fb3b3b5c first edit 2024-11-13 21:57:05 -08:00
12 changed files with 784 additions and 9 deletions

View File

@@ -222,10 +222,12 @@ nav:
- 🦀 Rust: https://docs.rs/lancedb/latest/lancedb/
- ☁️ LanceDB Cloud:
- Overview: cloud/index.md
- API reference:
- 🐍 Python: python/saas-python.md
- 👾 JavaScript: javascript/modules.md
- REST API: cloud/rest.md
- Quickstart: cloud/quickstart.md
- Best Practices: cloud/best_practices.md
# - API reference:
# - 🐍 Python: python/saas-python.md
# - 👾 JavaScript: javascript/modules.md
# - REST API: cloud/rest.md
- Quick start: basic.md
- Concepts:
@@ -348,10 +350,17 @@ nav:
- Rust: https://docs.rs/lancedb/latest/lancedb/index.html
- LanceDB Cloud:
- Overview: cloud/index.md
- API reference:
- 🐍 Python: python/saas-python.md
- 👾 JavaScript: javascript/modules.md
- REST API: cloud/rest.md
- Quickstart: cloud/quickstart.md
- Work with data:
- Ingest data: cloud/ingest_data.md
- Update data: cloud/update_data.md
- Build an index: cloud/build_index.md
- Vector search: cloud/vector_search.md
- Full-text search: cloud/full_text_search.md
- Hybrid search: cloud/hybrid_search.md
- Metadata Filtering: cloud/metadata_filtering.md
- Best Practices: cloud/best_practices.md
# - REST API: cloud/rest.md
extra_css:
- styles/global.css

View File

@@ -0,0 +1,20 @@
This section provides a set of recommended best practices to help you get the most out of LanceDB Cloud. By following these guidelines, you can optimize your usage of LanceDB Cloud, improve performance, and ensure a smooth experience.
### Should the db connection be created once and keep it open?
Yes! It is recommended to establish a single db connection and maintain it throughout your interaction with the tables within.
LanceDB uses `requests.Session()` for connection pooling, which automatically manages connection reuse and cleanup. This approach avoids the overhead of repeatedly establishing HTTP connections, significantly improving efficiency.
### Should a single `open_table` call be made and maintained for subsequent table operations?
`table = db.open_table()` should be called once and used for all subsequent table operations. If there are changes to the opened table, `table` always reflect the latest version of the data.
### Row id
### What are the vector indexing types supported by LanceDB Cloud?
We support `IVF_PQ` and `IVF_HNSW_SQ` as the `index_type` which is passed to `create_index`. LanceDB Cloud tunes the indexing parameters automatically to achieve the best tradeoff betweeln query latency and query quality.
### Do I need to do anything when there is new data added to a table with an existing index?
No! LanceDB Cloud triggers an asynchronous background job to index the new vectors. This process will either merge the new vectors into the existing index or initiate a complete re-indexing if needed.
There is a flag `fast_search` in `table.search()` that allows you to control whether the unindexed rows should be searched or not.

View File

@@ -0,0 +1,64 @@
LanceDB Cloud supports **vector index**, **scalar index** and **full-text search index**. Compared to open-source version, LanceDB Cloud focuses on **automation**:
- If there is a single vector column in the table, the vector column can be inferred from the schema and the index will be automatically created.
- Indexing parameters will be automatically tuned for customer's data.
## Vector index
LanceDB has implemented the state-of-art indexing algorithms (more about [IVF-PQ](https://lancedb.github.io/lancedb/concepts/index_ivfpq/) and [HNSW](https://lancedb.github.io/lancedb/concepts/index_hnsw/)). We currently
support the _L2_, _Cosine_ and _Dot_ as distance calculation metrics. You can create multiple vector indices within a table.
=== "Python"
```python
--8<-- "python/python/tests/docs/test_cloud.py:create_index"
```
=== "Typescript"
```typescript
--8<-- "nodejs/examples/cloud.test.ts:imports"
--8<-- "nodejs/examples/cloud.test.ts:connect_db_and_open_table"
--8<-- "nodejs/examples/cloud.test.ts:create_index"
```
## Scalar index
LanceDB Cloud and LanceDB Enterprise supports several types of Scalar indices to accelerate search over scalar columns.
- *BTREE*: The most common type is BTREE. This index is inspired by the btree data structure although only the first few layers of the btree are cached in memory. It will perform well on columns with a large number of unique values and few rows per value.
- *BITMAP*: this index stores a bitmap for each unique value in the column. This index is useful for columns with a finite number of unique values and many rows per value.
- For example, columns that represent "categories", "labels", or "tags"
- *LABEL_LIST*: a special index that is used to index list columns whose values have a finite set of possibilities.
- For example, a column that contains lists of tags (e.g. ["tag1", "tag2", "tag3"]) can be indexed with a LABEL_LIST index.
You can create multiple scalar indices within a table.
=== "Python"
```python
--8<-- "python/python/tests/docs/test_cloud.py:create_scalar_index"
```
=== "Typescript"
```typescript
--8<-- "nodejs/examples/cloud.test.ts:imports"
--8<-- "nodejs/examples/cloud.test.ts:connect_db_and_open_table"
--8<-- "nodejs/examples/cloud.test.ts:create_scalar_index"
```
## Full-text search index
We provide performant full-text search on LanceDB Cloud, allowing you to incorporate keyword-based search (based on BM25) in your retrieval solutions.
!!! note ""
`use_tantivy` is not available with `create_fts_index` on LanceDB Cloud as we used our native implementation, which has better performance comparing to tantivy.
=== "Python"
```python
--8<-- "python/python/tests/docs/test_cloud.py:create_fts_index"
```
=== "Typescript"
```typescript
--8<-- "nodejs/examples/cloud.test.ts:imports"
--8<-- "nodejs/examples/cloud.test.ts:create_fts_index"
```

View File

@@ -0,0 +1,14 @@
The full-text search allows you to
incorporate keyword-based search (based on BM25) in your retrieval solutions.
=== "Python"
```python
--8<-- "python/python/tests/docs/test_cloud.py:full_text_search"
```
=== "Typescript"
```typescript
--8<-- "nodejs/examples/cloud.test.ts:imports"
--8<-- "nodejs/examples/cloud.test.ts:full_text_search"
```

View File

@@ -0,0 +1,10 @@
We support hybrid search that combines semantic and full-text search via a
reranking algorithm of your choice, to get the best of both worlds. LanceDB
comes with [built-in rerankers](https://lancedb.github.io/lancedb/reranking/)
and you can implement you own _customized reranker_ as well.
=== "Python"
```python
--8<-- "python/python/tests/docs/test_cloud.py:hybrid_search"
```

View File

@@ -0,0 +1,31 @@
## Insert data
The LanceDB Cloud SDK for data ingestion remains consistent with our open-source version,
ensuring a seamless transition for existing OSS users.
!!! note "unsupported parameters in create_table"
The following two parameters: `mode="overwrite"` and `exist_ok`, are expected to be added by Nov, 2024.
=== "Python"
```python
--8<-- "python/python/tests/docs/test_cloud.py:import-ingest-data"
--8<-- "python/python/tests/docs/test_cloud.py:ingest_data"
```
=== "Typescript"
```typescript
--8<-- "nodejs/examples/cloud.test.ts:imports"
--8<-- "nodejs/examples/cloud.test.ts:ingest_data"
```
## Insert large datasets
It is recommended to use itertators to add large datasets in batches when creating
your table in one go. Data will be automatically compacted for the best query performance.
!!! info "batch size"
The batch size .
=== "Python"
```python
--8<-- "python/python/tests/docs/test_cloud.py:ingest_data_in_batch"
```

View File

@@ -0,0 +1,33 @@
LanceDB Cloud supports rich filtering features of query results based on metadata fields.
By default, _post-filtering_ is performed on the top-k results returned by the vector search.
However, _pre-filtering_ is also an option that performs the filter prior to vector search.
This can be useful to narrow down on the search space on a very large dataset to reduce query
latency.
=== "Python"
```python
--8<-- "python/python/tests/docs/test_cloud.py:filtering"
```
=== "Typescript"
```typescript
--8<-- "nodejs/examples/cloud.test.ts:imports"
--8<-- "nodejs/examples/cloud.test.ts:filtering"
```
We also support standard SQL expressions as predicates for filtering operations.
It can be used during vector search, update, and deletion operations.
=== "Python"
```python
--8<-- "python/python/tests/docs/test_cloud.py:sql_filtering"
```
=== "Typescript"
```typescript
--8<-- "nodejs/examples/cloud.test.ts:imports"
--8<-- "nodejs/examples/cloud.test.ts:sql_filtering"
```

View File

@@ -0,0 +1,49 @@
LanceDB Cloud efficiently manages updates across many tables.
Currently, we offer _update_, _merge_insert_, and _delete_.
## update
=== "Python"
```python
--8<-- "python/python/tests/docs/test_cloud.py:update_data"
```
=== "Typescript"
```typescript
--8<-- "nodejs/examples/cloud.test.ts:imports"
--8<-- "nodejs/examples/cloud.test.ts:connect_db_and_open_table"
--8<-- "nodejs/examples/cloud.test.ts:update_data"
```
## merge insert
This merge insert can add rows, update rows, and remove rows all in a single transaction.
It combines new data from a source table with existing data in a target table by using a join.
=== "Python"
```python
--8<-- "python/python/tests/docs/test_cloud.py:merge_insert"
```
=== "Typescript"
```typescript
--8<-- "nodejs/examples/cloud.test.ts:imports"
--8<-- "nodejs/examples/cloud.test.ts:connect_db_and_open_table"
--8<-- "nodejs/examples/cloud.test.ts:merge_insert"
```
## delete
=== "Python"
```python
--8<-- "python/python/tests/docs/test_cloud.py:delete_data"
```
=== "Typescript"
```typescript
--8<-- "nodejs/examples/cloud.test.ts:imports"
--8<-- "nodejs/examples/cloud.test.ts:connect_db_and_open_table"
--8<-- "nodejs/examples/cloud.test.ts:delete_data"
```

View File

@@ -0,0 +1,21 @@
Users can also tune the following parameters for better search quality.
- [nprobes](https://lancedb.github.io/lancedb/js/classes/VectorQuery/#nprobes):
the number of partitions to search (probe).
- [refine factor](https://lancedb.github.io/lancedb/js/classes/VectorQuery/#refinefactor):
a multiplier to control how many additional rows are taken during the refine step.
[Metadata filtering](filtering) combined with the vector search is also supported.
=== "Python"
```python
--8<-- "python/python/tests/docs/test_cloud.py:vector_search"
```
=== "Typescript"
```typescript
--8<-- "nodejs/examples/cloud.test.ts:imports"
--8<-- "nodejs/examples/cloud.test.ts:vector_search"
```

View File

@@ -22,7 +22,8 @@ excluded_globs = [
"../src/embeddings/available_embedding_models/text_embedding_functions/*.md",
"../src/embeddings/available_embedding_models/multimodal_embedding_functions/*.md",
"../src/rag/*.md",
"../src/rag/advanced_techniques/*.md"
"../src/rag/advanced_techniques/*.md",
"../src/cloud/*.md"
]

View File

@@ -0,0 +1,230 @@
// --8<-- [start:imports]
import * as lancedb from "@lancedb/lancedb";
// --8<-- [end:imports]
// --8<-- [start:generate_data]
function genData(numRows: number, numVectorDim: number): any[] {
const data = [];
for (let i = 0; i < numRows; i++) {
const vector = [];
for (let j = 0; j < numVectorDim; j++) {
vector.push(i + j * 0.1);
}
data.push({
id: i,
name: `name_${i}`,
vector,
});
}
return data;
}
// --8<-- [end:generate_data]
test("cloud quickstart", async () => {
{
// --8<-- [start:connect]
const db = await lancedb.connect({
uri: "db://your-project-slug",
apiKey: "your-api-key",
region: "your-cloud-region",
});
// --8<-- [end:connect]
// --8<-- [start:create_table]
const tableName = "myTable"
const data = genData(5000, 1536)
const table = await db.createTable(tableName, data);
// --8<-- [end:create_table]
// --8<-- [start:create_index_search]
// create a vector index
await table.createIndex({
column: "vector",
metric_type: lancedb.MetricType.Cosine,
type: "ivf_pq",
});
const result = await table.search([0.01, 0.02])
.select(["vector", "item"])
.limit(1)
.execute();
// --8<-- [end:create_index_search]
// --8<-- [start:drop_table]
await db.dropTable(tableName);
// --8<-- [end:drop_table]
}
});
test("ingest data", async () => {
// --8<-- [start:ingest_data]
import { Schema, Field, Float32, FixedSizeList, Utf8 } from "apache-arrow";
const db = await lancedb.connect({
uri: "db://your-project-slug",
apiKey: "your-api-key",
region: "us-east-1"
});
const data = [
{ vector: [3.1, 4.1], item: "foo", price: 10.0 },
{ vector: [5.9, 26.5], item: "bar", price: 20.0 },
{ vector: [10.2, 100.8], item: "baz", price: 30.0},
{ vector: [1.4, 9.5], item: "fred", price: 40.0},
]
// create an empty table with schema
const schema = new Schema([
new Field(
"vector",
new FixedSizeList(2, new Field("float32", new Float32())),
),
new Field("item", new Utf8()),
new Field("price", new Float32()),
]);
const tableName = "myTable";
const table = await db.createTable({
name: tableName,
schema,
});
await table.add(data);
// --8<-- [end:ingest_data]
});
test("update data", async () => {
// --8<-- [start:connect_db_and_open_table]
const db = await lancedb.connect({
uri: "db://your-project-slug",
apiKey: "your-api-key",
region: "us-east-1"
});
const tableName = "myTable"
const table = await db.openTable(tableName);
// --8<-- [end:connect_db_and_open_table]
// --8<-- [start:update_data]
await table.update({
where: "price < 20.0",
values: { vector: [2, 2], item: "foo-updated" },
});
// --8<-- [end:update_data]
// --8<-- [start:merge_insert]
let newData = [
{vector: [1, 1], item: 'foo-updated', price: 50.0}
];
// upsert
await table.mergeInsert("item", newData, {
whenMatchedUpdateAll: true,
whenNotMatchedInsertAll: true,
});
// --8<-- [end:merge_insert]
// --8<-- [start:delete_data]
// delete data
const predicate = "price = 30.0";
await table.delete(predicate);
// --8<-- [end:delete_data]
});
test("create index", async () => {
const db = await lancedb.connect({
uri: "db://your-project-slug",
apiKey: "your-api-key",
region: "us-east-1"
});
const tableName = "myTable";
const table = await db.openTable(tableName);
// --8<-- [start:create_index]
// the vector column only needs to be specified when there are
// multiple vector columns or the column is not named as "vector"
// L2 is used as the default distance metric
await table.createIndex({
column: "vector",
metric_type: lancedb.MetricType.Cosine,
});
// --8<-- [end:create_index]
// --8<-- [start:create_scalar_index]
await table.createScalarIndex("item");
// --8<-- [end:create_scalar_index]
// --8<-- [start:create_fts_index]
const db = await lancedb.connect({
uri: "db://your-project-slug",
apiKey: "your-api-key",
region: "us-east-1"
});
const tableName = "myTable"
const data = [
{ vector: [3.1, 4.1], text: "Frodo was a happy puppy" },
{ vector: [5.9, 26.5], text: "There are several kittens playing" },
];
const table = createTable(tableName, data);
await table.createIndex("text", {
config: lancedb.Index.fts(),
});
// --8<-- [end:create_fts_index]
});
test("vector search", async () => {
// --8<-- [start:vector_search]
const db = await lancedb.connect({
uri: "db://your-project-slug",
apiKey: "your-api-key",
region: "us-east-1"
});
const tableName = "myTable"
const table = await db.openTable(tableName);
const result = await table.search([0.4, 1.4])
.where("price > 10.0")
.prefilter(true)
.select(["item", "vector"])
.limit(2)
.execute();
// --8<-- [end:vector_search]
});
test("full-text search", async () => {
// --8<-- [start:full_text_search]
const db = await lancedb.connect({
uri: "db://your-project-slug",
apiKey: "your-api-key",
region: "us-east-1"
});
const data = [
{ vector: [3.1, 4.1], text: "Frodo was a happy puppy" },
{ vector: [5.9, 26.5], text: "There are several kittens playing" },
];
const tableName = "myTable"
const table = await db.createTable(tableName, data);
await table.createIndex("text", {
config: lancedb.Index.fts(),
});
await tableName
.search("puppy", queryType="fts")
.select(["text"])
.limit(10)
.toArray();
// --8<-- [end:full_text_search]
});
test("metadata filtering", async () => {
// --8<-- [start:filtering]
const db = await lancedb.connect({
uri: "db://your-project-slug",
apiKey: "your-api-key",
region: "us-east-1"
});
const tableName = "myTable"
const table = await db.openTable(tableName);
await table
.search(Array(2).fill(0.1))
.where("(item IN ('foo', 'bar')) AND (price > 10.0)")
.postfilter()
.toArray();
// --8<-- [end:filtering]
// --8<-- [start:sql_filtering]
await table
.search(Array(2).fill(0.1))
.where("(item IN ('foo', 'bar')) AND (price > 10.0)")
.postfilter()
.toArray();
// --8<-- [end:sql_filtering]
});

View File

@@ -0,0 +1,293 @@
# --8<-- [start:imports]
# --8<-- [start:import-lancedb]
# --8<-- [start:import-ingest-data]
import lancedb
import pyarrow as pa
# --8<-- [end:import-ingest-data]
import numpy as np
# --8<-- [end:import-lancedb]
# --8<-- [end:imports]
# --8<-- [start:gen_data]
def gen_data(total_rows: int, ndims: int = 1536):
return pa.RecordBatch.from_pylist(
[
{
"vector": np.random.rand(ndims).astype(np.float32).tolist(),
"id": i,
"name": "name_" + str(i),
}
for i in range(total_rows)
],
).to_pandas()
# --8<-- [end:gen_data]
def test_cloud_quickstart():
# --8<-- [start:connect]
db = lancedb.connect(
uri="db://your-project-slug", api_key="your-api-key", region="your-cloud-region"
)
# --8<-- [end:connect]
# --8<-- [start:create_table]
table_name = "myTable"
table = db.create_table(table_name, data=gen_data(5000))
# --8<-- [end:create_table]
# --8<-- [start:create_index_search]
# create a vector index
table.create_index("cosine", vector_column_name="vector")
result = table.search([0.01, 0.02]).select(["vector", "item"]).limit(1).to_pandas()
print(result)
# --8<-- [end:create_index_search]
# --8<-- [start:drop_table]
db.drop_table(table_name)
# --8<-- [end:drop_table]
def test_ingest_data():
# --8<-- [start:ingest_data]
# connect to LanceDB
db = lancedb.connect(
uri="db://your-project-slug", api_key="your-api-key", region="us-east-1"
)
# create an empty table with schema
table_name = "myTable"
data = [
{"vector": [3.1, 4.1], "item": "foo", "price": 10.0},
{"vector": [5.9, 26.5], "item": "bar", "price": 20.0},
{"vector": [10.2, 100.8], "item": "baz", "price": 30.0},
{"vector": [1.4, 9.5], "item": "fred", "price": 40.0},
]
schema = pa.schema(
[
pa.field("vector", pa.list_(pa.float32(), 2)),
pa.field("item", pa.utf8()),
pa.field("price", pa.float32()),
]
)
table = db.create_table(table_name, schema=schema)
table.add(data)
# --8<-- [end:ingest_data]
# --8<-- [start:ingest_data_in_batch]
def make_batches():
for i in range(5):
yield pa.RecordBatch.from_arrays(
[
pa.array([[3.1, 4.1], [5.9, 26.5]], pa.list_(pa.float32(), 2)),
pa.array(["foo", "bar"]),
pa.array([10.0, 20.0]),
],
["vector", "item", "price"],
)
schema = pa.schema(
[
pa.field("vector", pa.list_(pa.float32(), 2)),
pa.field("item", pa.utf8()),
pa.field("price", pa.float32()),
]
)
db.create_table("table2", make_batches(), schema=schema)
# --8<-- [end:ingest_data_in_batch]
def test_updates():
# --8<-- [start:update_data]
import lancedb
# connect to LanceDB
db = lancedb.connect(
uri="db://your-project-slug", api_key="your-api-key", region="us-east-1"
)
table_name = "myTable"
table = db.open_table(table_name)
table.update(where="price < 20.0", values={"vector": [2, 2], "item": "foo-updated"})
# --8<-- [end:update_data]
# --8<-- [start:merge_insert]
table = db.open_table(table_name)
# upsert
new_data = [{"vector": [1, 1], "item": "foo-updated", "price": 50.0}]
table.merge_insert(
"item"
).when_matched_update_all().when_not_matched_insert_all().execute(new_data)
# --8<-- [end:merge_insert]
# --8<-- [start:delete_data]
table_name = "myTable"
table = db.open_table(table_name)
# delete data
predicate = "price = 30.0"
table.delete(predicate)
# --8<-- [end:delete_data]
def test_create_index():
# --8<-- [start:create_index]
import lancedb
# connect to LanceDB
db = lancedb.connect(
uri="db://your-project-slug", api_key="your-api-key", region="us-east-1"
)
table_name = "myTable"
table = db.open_table(table_name)
# the vector column only needs to be specified when there are
# multiple vector columns or the column is not named as "vector"
# L2 is used as the default distance metric
table.create_index(metric="cosine", vector_column_name="vector")
# --8<-- [end:create_index]
def test_create_scalar_index():
# --8<-- [start:create_scalar_index]
import lancedb
# connect to LanceDB
db = lancedb.connect(
uri="db://your-project-slug", api_key="your-api-key", region="us-east-1"
)
table_name = "myTable"
table = db.open_table(table_name)
# default is BTree
table.create_scalar_index("item", index_type="BITMAP")
# --8<-- [end:create_scalar_index]
def test_create_fts_index():
# --8<-- [start:create_fts_index]
import lancedb
# connect to LanceDB
db = lancedb.connect(
uri="db://your-project-slug", api_key="your-api-key", region="us-east-1"
)
table_name = "myTable"
data = [
{"vector": [3.1, 4.1], "text": "Frodo was a happy puppy"},
{"vector": [5.9, 26.5], "text": "There are several kittens playing"},
]
table = db.create_table(table_name, data=data)
table.create_fts_index("text")
# --8<-- [end:create_fts_index]
def test_search():
# --8<-- [start:vector_search]
import lancedb
# connect to LanceDB
db = lancedb.connect(
uri="db://your-project-slug", api_key="your-api-key", region="us-east-1"
)
table_name = "myTable"
table = db.open_table(table_name)
query = [0.4, 1.4]
result = (
table.search(query)
.where("price > 10.0", prefilter=True)
.select(["item", "vector"])
.limit(2)
.to_pandas()
)
print(result)
# --8<-- [end:vector_search]
# --8<-- [start:full_text_search]
import lancedb
# connect to LanceDB
db = lancedb.connect(
uri="db://your-project-slug", api_key="your-api-key", region="us-east-1"
)
table_name = "myTable"
table = db.create_table(
table_name,
data=[
{"vector": [3.1, 4.1], "text": "Frodo was a happy puppy"},
{"vector": [5.9, 26.5], "text": "There are several kittens playing"},
],
)
table.create_fts_index("text")
table.search("puppy", query_type="fts").limit(10).select(["text"]).to_list()
# --8<-- [end:full_text_search]
# --8<-- [start:hybrid_search]
import os
import lancedb
import openai
from lancedb.embeddings import get_registry
from lancedb.pydantic import LanceModel, Vector
from lancedb.rerankers import RRFReranker
# connect to LanceDB
db = lancedb.connect(
uri="db://your-project-slug", api_key="your-api-key", region="us-east-1"
)
# Configuring the environment variable OPENAI_API_KEY
if "OPENAI_API_KEY" not in os.environ:
# OR set the key here as a variable
openai.api_key = "sk-..."
embeddings = get_registry().get("openai").create()
class Documents(LanceModel):
text: str = embeddings.SourceField()
vector: Vector(embeddings.ndims()) = embeddings.VectorField()
table_name = "myTable"
table = db.create_table(table_name, schema=Documents)
data = [
{"text": "rebel spaceships striking from a hidden base"},
{"text": "have won their first victory against the evil Galactic Empire"},
{"text": "during the battle rebel spies managed to steal secret plans"},
{"text": "to the Empire's ultimate weapon the Death Star"},
]
table.add(data=data)
table.create_index("L2", "vector")
table.create_fts_index("text")
# you can use table.list_indices() to make sure indices have been created
reranker = RRFReranker()
result = (
table.search(
"flower moon",
query_type="hybrid",
vector_column_name="vector",
fts_columns="text",
)
.rerank(reranker)
.limit(10)
.to_pandas()
)
print(result)
# --8<-- [end:hybrid_search]
def test_filtering():
# --8<-- [start:filtering]
import lancedb
# connect to LanceDB
db = lancedb.connect(
uri="db://your-project-slug", api_key="your-api-key", region="us-east-1"
)
table_name = "myTable"
table = db.open_table(table_name)
result = (
table.search([100, 102])
.where("(item IN ('foo', 'bar')) AND (price > 10.0)")
.to_arrow()
)
print(result)
# --8<-- [end:filtering]
# --8<-- [start:sql_filtering]
table.search([100, 102]).where(
"(item IN ('foo', 'bar')) AND (price > 10.0)"
).to_arrow()
# --8<-- [end:sql_filtering]