mirror of
https://github.com/lancedb/lancedb.git
synced 2026-10-12 14:52:26 +00:00
docs: make the TypeScript and Rust quickstarts complete programs
The TypeScript connection example only defined a helper that nothing called, so every later step failed with `db is not defined`. It now connects, as the Python one does. The Rust one kept its connection inside a helper, the Enterprise one read its settings without connecting, and the later steps relied on imports and a record-batch helper the page never showed. The quickstart now says how the steps make one program: an ES module run with Node in TypeScript, and the body of an async `main` in Rust, whose dependencies the install step lists. Each Rust step brings its own imports, the data step shows the helper that turns the records into a reader, and Arrow comes from lancedb's re-exports, so no Arrow crate is needed. The row structs no longer derive serde traits nothing used. The connection examples are shared, so the connect, create-table and branching pages gain the import line their connection code now needs.
This commit is contained in:
@@ -3,35 +3,59 @@
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use lancedb::connect;
|
||||
use lancedb::{Connection, connect};
|
||||
|
||||
// --8<-- [start:connect]
|
||||
async fn connect_example(uri: &str) {
|
||||
let db = connect(uri).execute().await.unwrap();
|
||||
let _ = db;
|
||||
async fn connect_local() -> lancedb::Result<Connection> {
|
||||
// --8<-- [start:connect]
|
||||
let db = connect("ex_lancedb").execute().await?;
|
||||
// --8<-- [end:connect]
|
||||
Ok(db)
|
||||
}
|
||||
// --8<-- [end:connect]
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let temp_dir = tempfile::tempdir().unwrap();
|
||||
let uri = temp_dir.path().join("ex_lancedb");
|
||||
connect_example(uri.to_str().unwrap()).await;
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let temp_dir = tempfile::tempdir()?;
|
||||
std::env::set_current_dir(temp_dir.path())?;
|
||||
let db = connect_local().await?;
|
||||
db.create_empty_table(
|
||||
"probe",
|
||||
std::sync::Arc::new(arrow_schema::Schema::new(vec![arrow_schema::Field::new(
|
||||
"id",
|
||||
arrow_schema::DataType::Int64,
|
||||
false,
|
||||
)])),
|
||||
)
|
||||
.execute()
|
||||
.await?;
|
||||
let reopened = connect(temp_dir.path().join("ex_lancedb").to_str().unwrap())
|
||||
.execute()
|
||||
.await?;
|
||||
assert_eq!(reopened.table_names().execute().await?, vec!["probe"]);
|
||||
|
||||
// Keep the enterprise snippet in this file, but don't run it in CI.
|
||||
let _ = connect_enterprise_quickstart_config();
|
||||
// Connects to a deployment only when asked, and only lists its tables.
|
||||
if std::env::var("LANCEDB_DOCS_TEST_DEPLOYMENT").as_deref() == Ok("1") {
|
||||
let db = connect_enterprise_quickstart().await?;
|
||||
println!("{:?}", db.table_names().execute().await?);
|
||||
}
|
||||
let _ = connect_object_storage_config();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn connect_enterprise_quickstart_config()
|
||||
-> Result<(String, String, String, String), std::env::VarError> {
|
||||
async fn connect_enterprise_quickstart() -> Result<Connection, Box<dyn std::error::Error>> {
|
||||
// --8<-- [start:connect_enterprise_quickstart]
|
||||
let uri = std::env::var("LANCEDB_URI")?; // db://your-database
|
||||
let api_key = std::env::var("LANCEDB_API_KEY")?;
|
||||
let region = std::env::var("LANCEDB_REGION").unwrap_or_else(|_| "us-east-1".to_string());
|
||||
let host_override = std::env::var("LANCEDB_HOST_OVERRIDE")?; // https://your-endpoint
|
||||
|
||||
let db = connect(&uri)
|
||||
.api_key(&api_key)
|
||||
.region(®ion)
|
||||
.host_override(&host_override)
|
||||
.execute()
|
||||
.await?;
|
||||
// --8<-- [end:connect_enterprise_quickstart]
|
||||
Ok((uri, api_key, region, host_override))
|
||||
Ok(db)
|
||||
}
|
||||
|
||||
fn connect_object_storage_config() -> &'static str {
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: Copyright The LanceDB Authors
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use arrow_array::types::Float32Type;
|
||||
use arrow_array::{
|
||||
FixedSizeListArray, Int8Array, LargeStringArray, RecordBatch, RecordBatchIterator, StructArray,
|
||||
};
|
||||
use arrow_schema::{DataType, Field, FieldRef, Schema};
|
||||
use lancedb::arrow::IntoPolars;
|
||||
use lancedb::database::CreateTableMode;
|
||||
use lancedb::query::{ExecutableQuery, QueryBase, Select};
|
||||
use lancedb::{connect, table::NewColumnTransform};
|
||||
use polars::prelude::DataFrame;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
// --8<-- [start:quickstart_define_struct]
|
||||
use std::sync::Arc;
|
||||
|
||||
use lancedb::arrow::arrow_array::types::Float32Type;
|
||||
use lancedb::arrow::arrow_array::{
|
||||
FixedSizeListArray, Int8Array, LargeStringArray, RecordBatch, RecordBatchIterator,
|
||||
RecordBatchReader, StructArray,
|
||||
};
|
||||
use lancedb::arrow::arrow_schema::{DataType, Field, FieldRef, Fields, Schema};
|
||||
|
||||
// Define structs representing the data schema
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone)]
|
||||
struct Stats {
|
||||
strength: i8,
|
||||
magic: i8,
|
||||
@@ -25,7 +22,7 @@ struct Stats {
|
||||
wisdom: i8,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone)]
|
||||
struct Character {
|
||||
id: String,
|
||||
name: String,
|
||||
@@ -43,7 +40,7 @@ fn characters_schema() -> Arc<Schema> {
|
||||
Field::new("description", DataType::LargeUtf8, false),
|
||||
Field::new(
|
||||
"stats",
|
||||
DataType::Struct(arrow_schema::Fields::from(vec![
|
||||
DataType::Struct(Fields::from(vec![
|
||||
Arc::new(Field::new("strength", DataType::Int8, false)),
|
||||
Arc::new(Field::new("magic", DataType::Int8, false)),
|
||||
Arc::new(Field::new("leadership", DataType::Int8, false)),
|
||||
@@ -58,11 +55,11 @@ fn characters_schema() -> Arc<Schema> {
|
||||
),
|
||||
]))
|
||||
}
|
||||
// --8<-- [end:quickstart_define_struct]
|
||||
|
||||
type BatchIter = Box<dyn arrow_array::RecordBatchReader + Send>;
|
||||
|
||||
fn characters_to_reader(schema: Arc<Schema>, rows: &[Character]) -> BatchIter {
|
||||
fn characters_to_reader(
|
||||
schema: Arc<Schema>,
|
||||
rows: &[Character],
|
||||
) -> Box<dyn RecordBatchReader + Send> {
|
||||
let ids = LargeStringArray::from_iter_values(rows.iter().map(|row| row.id.as_str()));
|
||||
let names = LargeStringArray::from_iter_values(rows.iter().map(|row| row.name.as_str()));
|
||||
let roles = LargeStringArray::from_iter_values(rows.iter().map(|row| row.role.as_str()));
|
||||
@@ -114,6 +111,7 @@ fn characters_to_reader(schema: Arc<Schema>, rows: &[Character]) -> BatchIter {
|
||||
schema,
|
||||
))
|
||||
}
|
||||
// --8<-- [end:quickstart_define_struct]
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
@@ -166,6 +164,8 @@ async fn main() {
|
||||
// --8<-- [end:quickstart_data]
|
||||
|
||||
// --8<-- [start:quickstart_create_table]
|
||||
use lancedb::database::CreateTableMode;
|
||||
|
||||
let schema = characters_schema();
|
||||
let table = db
|
||||
.create_table("characters", characters_to_reader(schema.clone(), &data))
|
||||
@@ -199,10 +199,13 @@ async fn main() {
|
||||
assert_eq!(table.count_rows(None).await.unwrap(), 4);
|
||||
|
||||
// --8<-- [start:quickstart_vector_search_1]
|
||||
use lancedb::arrow::IntoPolars;
|
||||
use lancedb::query::{ExecutableQuery, QueryBase, Select};
|
||||
|
||||
// Search for examples similar to a "wise magical advisor"
|
||||
let query_vector = [0.2, 0.8, 0.4, 0.9];
|
||||
|
||||
let result: DataFrame = table
|
||||
let result = table
|
||||
.query()
|
||||
.nearest_to(&query_vector)
|
||||
.unwrap()
|
||||
@@ -226,7 +229,7 @@ async fn main() {
|
||||
assert_eq!(name_col.get(1).unwrap(), "Morgana");
|
||||
|
||||
// --8<-- [start:quickstart_curate_with_metadata]
|
||||
let curated: DataFrame = table
|
||||
let curated = table
|
||||
.query()
|
||||
.nearest_to(&query_vector)
|
||||
.unwrap()
|
||||
@@ -251,7 +254,7 @@ async fn main() {
|
||||
assert_eq!(curated_name_col.get(1).unwrap(), "Morgana");
|
||||
|
||||
// --8<-- [start:quickstart_output_array]
|
||||
let result: DataFrame = table
|
||||
let result = table
|
||||
.query()
|
||||
.nearest_to(&query_vector)
|
||||
.unwrap()
|
||||
@@ -288,7 +291,7 @@ async fn main() {
|
||||
// --8<-- [end:quickstart_add_feature]
|
||||
|
||||
// --8<-- [start:quickstart_query_feature]
|
||||
let features: DataFrame = table
|
||||
let features = table
|
||||
.query()
|
||||
.select(Select::Columns(vec![
|
||||
"name".to_string(),
|
||||
@@ -317,12 +320,7 @@ async fn main() {
|
||||
std::env::set_current_dir(app.path()).unwrap();
|
||||
|
||||
// --8<-- [start:quickstart_multimodal_bytes]
|
||||
use std::sync::Arc;
|
||||
|
||||
use arrow_array::{
|
||||
BinaryArray, FixedSizeListArray, LargeStringArray, RecordBatch, RecordBatchIterator,
|
||||
};
|
||||
use arrow_schema::{DataType, Field, Schema};
|
||||
use lancedb::arrow::arrow_array::BinaryArray;
|
||||
|
||||
let image_bytes = std::fs::read("data/sir-lancelot.jpg").unwrap();
|
||||
|
||||
@@ -356,9 +354,10 @@ async fn main() {
|
||||
],
|
||||
)
|
||||
.unwrap();
|
||||
let image_reader: Box<dyn arrow_array::RecordBatchReader + Send> = Box::new(
|
||||
RecordBatchIterator::new(vec![Ok(image_batch)].into_iter(), image_schema),
|
||||
);
|
||||
let image_reader: Box<dyn RecordBatchReader + Send> = Box::new(RecordBatchIterator::new(
|
||||
vec![Ok(image_batch)].into_iter(),
|
||||
image_schema,
|
||||
));
|
||||
let multimodal_table = db
|
||||
.create_table("character_images", image_reader)
|
||||
.mode(CreateTableMode::Overwrite)
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: Copyright The LanceDB Authors
|
||||
import { afterEach, describe, expect, jest, test } from "@jest/globals";
|
||||
import * as path from "node:path";
|
||||
import { withTempDirectory } from "./util.ts";
|
||||
// --8<-- [start:connect]
|
||||
import * as lancedb from "@lancedb/lancedb";
|
||||
|
||||
async function connectExample(uri: string) {
|
||||
const db = await lancedb.connect(uri);
|
||||
return db;
|
||||
}
|
||||
// --8<-- [end:connect]
|
||||
import { withTempDirectory } from "./util.ts";
|
||||
|
||||
test("connect to a local database", async () => {
|
||||
await withTempDirectory(async (tempDir) => {
|
||||
const uri = path.join(tempDir, "ex_lancedb");
|
||||
const db = await connectExample(uri);
|
||||
expect(db).toBeDefined();
|
||||
const cwd = process.cwd();
|
||||
process.chdir(tempDir);
|
||||
try {
|
||||
// --8<-- [start:connect]
|
||||
const db = await lancedb.connect("ex_lancedb");
|
||||
// --8<-- [end:connect]
|
||||
await db.createTable("probe", [{ id: 1 }]);
|
||||
expect((await db.listTables()).tables).toEqual(["probe"]);
|
||||
} finally {
|
||||
process.chdir(cwd);
|
||||
}
|
||||
const reopened = await lancedb.connect(`${tempDir}/ex_lancedb`);
|
||||
expect((await reopened.listTables()).tables).toEqual(["probe"]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ directory on disk.
|
||||
</CodeBlock>
|
||||
|
||||
<CodeBlock filename="TypeScript" language="TypeScript" icon="square-js">
|
||||
{ "import * as lancedb from \"@lancedb/lancedb\";\n\n" }
|
||||
{TsConnect}
|
||||
</CodeBlock>
|
||||
|
||||
|
||||
@@ -64,10 +64,12 @@ Initialize a LanceDB connection and create a table. A table's name follows the
|
||||
</CodeBlock>
|
||||
|
||||
<CodeBlock filename="TypeScript" language="TypeScript" icon="square-js">
|
||||
{ "import * as lancedb from \"@lancedb/lancedb\";\n\n" }
|
||||
{TsConnect}
|
||||
</CodeBlock>
|
||||
|
||||
<CodeBlock filename="Rust" language="Rust" icon="rust">
|
||||
{ "use lancedb::connect;\n\n" }
|
||||
{RsConnect}
|
||||
</CodeBlock>
|
||||
</CodeGroup>
|
||||
|
||||
+23
-4
@@ -79,10 +79,27 @@ npm install @lancedb/lancedb
|
||||
```
|
||||
|
||||
```bash Rust icon=Rust
|
||||
cargo add lancedb
|
||||
cargo add lancedb --features polars,remote
|
||||
cargo add tokio --features macros,rt-multi-thread
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
The TypeScript and Rust code of steps 2 to 5 makes one program. In TypeScript,
|
||||
put it, in order, in an ES module such as `quickstart.mts` and run
|
||||
`node quickstart.mts`; Node.js 22.18 and later run TypeScript directly. In Rust,
|
||||
it goes, in order, inside `main` in `src/main.rs`, and `cargo run` runs it. The
|
||||
`polars` feature returns results as DataFrames, and `remote` connects to
|
||||
LanceDB Enterprise.
|
||||
|
||||
```rust src/main.rs icon="rust"
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// The Rust code of steps 2 to 5 goes here.
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
### Python pre-release builds {#python-pre-release-builds}
|
||||
|
||||
To pick up the latest features and bug fixes
|
||||
@@ -149,6 +166,7 @@ client SDK of choice and point to a local directory path.
|
||||
</CodeBlock>
|
||||
|
||||
<CodeBlock filename="TypeScript" language="TypeScript" icon="square-js">
|
||||
{ "import * as lancedb from \"@lancedb/lancedb\";\n\n" }
|
||||
{TsConnect}
|
||||
</CodeBlock>
|
||||
|
||||
@@ -213,12 +231,12 @@ endpoint is required: without it the code stops rather than guessing one.
|
||||
</CodeBlock>
|
||||
|
||||
<CodeBlock filename="Rust" language="Rust" icon="rust">
|
||||
{ "use lancedb::connect;\n\n" }
|
||||
{RsConnectEnterpriseQuickstart}
|
||||
</CodeBlock>
|
||||
</CodeGroup >
|
||||
|
||||
In Rust, pass the same settings to the connection builder's `api_key`, `region`
|
||||
and `host_override`. A deployment runs some things differently -- maintenance,
|
||||
A deployment runs some things differently -- maintenance,
|
||||
long-running work, a few unsupported methods; see
|
||||
[Moving to LanceDB Enterprise](/basics/sdk#moving-to-enterprise), and the
|
||||
[Enterprise overview](/enterprise) for how a deployment is put together.
|
||||
@@ -371,7 +389,8 @@ deployment.
|
||||
## Optional extensions {#extensions}
|
||||
|
||||
Each extension below starts from the `characters` table of step 3 and stands on its own,
|
||||
so take any of them, in any order, or none.
|
||||
so take any of them, in any order, or none. In TypeScript and Rust, its code goes after
|
||||
step 5's.
|
||||
|
||||
### Add a derived feature {#6-add-a-derived-feature}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ export const PyNamespaceAdminOps = "import lancedb\n\ndb = lancedb.connect_names
|
||||
|
||||
export const PyNamespaceTableOps = "import lancedb\n\ndb = lancedb.connect_namespace(\"dir\", {\"root\": \"./local_lancedb\"})\n\n# Create namespace tree: prod/search\ndb.create_namespace([\"prod\"], mode=\"exist_ok\")\ndb.create_namespace([\"prod\", \"search\"], mode=\"exist_ok\")\ndb.create_namespace([\"prod\", \"recommendations\"], mode=\"exist_ok\")\n\ndb.create_table(\n \"user\",\n data=[{\"id\": 1, \"vector\": [0.1, 0.2], \"name\": \"alice\"}],\n namespace_path=[\"prod\", \"search\"],\n mode=\"create\", # use \"overwrite\" only if you want to replace existing table\n)\n\ndb.create_table(\n \"user\",\n data=[{\"id\": 2, \"vector\": [0.3, 0.4], \"name\": \"bob\"}],\n namespace_path=[\"prod\", \"recommendations\"],\n mode=\"create\", # use \"overwrite\" only if you want to replace existing table\n)\n\n# Verify: listings return a response with the names and a page token\nprint(db.list_namespaces().namespaces) # ['prod']\nprint(db.list_namespaces(namespace_path=[\"prod\"]).namespaces)\n# ['recommendations', 'search']\nprint(db.list_tables(namespace_path=[\"prod\", \"search\"]).tables) # ['user']\nprint(db.list_tables(namespace_path=[\"prod\", \"recommendations\"]).tables) # ['user']\n";
|
||||
|
||||
export const TsConnect = "import * as lancedb from \"@lancedb/lancedb\";\n\nasync function connectExample(uri: string) {\n const db = await lancedb.connect(uri);\n return db;\n}\n";
|
||||
export const TsConnect = "const db = await lancedb.connect(\"ex_lancedb\");\n";
|
||||
|
||||
export const TsConnectEnterpriseQuickstart = "const setting = (name: string) => {\n const value = process.env[name];\n if (!value) throw new Error(`Set ${name}`);\n return value;\n};\n\nconst db = await lancedb.connect(setting(\"LANCEDB_URI\"), {\n apiKey: setting(\"LANCEDB_API_KEY\"),\n region: process.env.LANCEDB_REGION ?? \"us-east-1\",\n hostOverride: setting(\"LANCEDB_HOST_OVERRIDE\"),\n});\n";
|
||||
|
||||
@@ -24,9 +24,9 @@ export const TsNamespaceAdminOps = "const db = await lancedb.connectNamespace(\"
|
||||
|
||||
export const TsNamespaceTableOps = "const db = await lancedb.connectNamespace(\"dir\", { root: \"./local_lancedb\" });\n\n// Create namespace tree: prod/search and prod/recommendations\nawait db.createNamespace([\"prod\"], { mode: \"exist_ok\" });\nawait db.createNamespace([\"prod\", \"search\"], { mode: \"exist_ok\" });\nawait db.createNamespace([\"prod\", \"recommendations\"], { mode: \"exist_ok\" });\n\nawait db.createTable(\n \"user\",\n [{ id: 1, vector: [0.1, 0.2], name: \"alice\" }],\n [\"prod\", \"search\"],\n { mode: \"create\" }, // use \"overwrite\" only if you want to replace existing table\n);\n\nawait db.createTable(\n \"user\",\n [{ id: 2, vector: [0.3, 0.4], name: \"bob\" }],\n [\"prod\", \"recommendations\"],\n { mode: \"create\" },\n);\n\n// Verify\nconsole.log((await db.listNamespaces()).namespaces); // [\"prod\"]\nconsole.log((await db.listNamespaces([\"prod\"])).namespaces); // [\"recommendations\", \"search\"]\nconsole.log(await db.tableNames([\"prod\", \"search\"])); // [\"user\"]\nconsole.log(await db.tableNames([\"prod\", \"recommendations\"])); // [\"user\"]\n";
|
||||
|
||||
export const RsConnect = "async fn connect_example(uri: &str) {\n let db = connect(uri).execute().await.unwrap();\n let _ = db;\n}\n";
|
||||
export const RsConnect = "let db = connect(\"ex_lancedb\").execute().await?;\n";
|
||||
|
||||
export const RsConnectEnterpriseQuickstart = "let uri = std::env::var(\"LANCEDB_URI\")?; // db://your-database\nlet api_key = std::env::var(\"LANCEDB_API_KEY\")?;\nlet region = std::env::var(\"LANCEDB_REGION\").unwrap_or_else(|_| \"us-east-1\".to_string());\nlet host_override = std::env::var(\"LANCEDB_HOST_OVERRIDE\")?; // https://your-endpoint\n";
|
||||
export const RsConnectEnterpriseQuickstart = "let uri = std::env::var(\"LANCEDB_URI\")?; // db://your-database\nlet api_key = std::env::var(\"LANCEDB_API_KEY\")?;\nlet region = std::env::var(\"LANCEDB_REGION\").unwrap_or_else(|_| \"us-east-1\".to_string());\nlet host_override = std::env::var(\"LANCEDB_HOST_OVERRIDE\")?; // https://your-endpoint\n\nlet db = connect(&uri)\n .api_key(&api_key)\n .region(®ion)\n .host_override(&host_override)\n .execute()\n .await?;\n";
|
||||
|
||||
export const RsConnectObjectStorage = "let uri = \"s3://your-bucket/path\";\n// You can also use \"gs://your-bucket/path\" or \"az://your-container/path\".\n";
|
||||
|
||||
|
||||
@@ -48,19 +48,19 @@ export const RsQuickstartAddData = "let more_data = vec![Character {\n id: \"
|
||||
|
||||
export const RsQuickstartAddFeature = "table\n .add_columns(\n NewColumnTransform::SqlExpressions(vec![(\n \"power_score\".to_string(),\n \"cast(((stats.strength + stats.magic + stats.leadership + stats.wisdom) / 4.0) as float)\"\n .to_string(),\n )]),\n None,\n )\n .await\n .unwrap();\n";
|
||||
|
||||
export const RsQuickstartCreateTable = "let schema = characters_schema();\nlet table = db\n .create_table(\"characters\", characters_to_reader(schema.clone(), &data))\n .mode(CreateTableMode::Overwrite)\n .execute()\n .await\n .unwrap();\n";
|
||||
export const RsQuickstartCreateTable = "use lancedb::database::CreateTableMode;\n\nlet schema = characters_schema();\nlet table = db\n .create_table(\"characters\", characters_to_reader(schema.clone(), &data))\n .mode(CreateTableMode::Overwrite)\n .execute()\n .await\n .unwrap();\n";
|
||||
|
||||
export const RsQuickstartCurateWithMetadata = "let curated: DataFrame = table\n .query()\n .nearest_to(&query_vector)\n .unwrap()\n .only_if(\"stats.magic >= 4\")\n .select(Select::Columns(vec![\n \"name\".to_string(),\n \"role\".to_string(),\n \"description\".to_string(),\n \"_distance\".to_string(),\n ]))\n .limit(2)\n .execute()\n .await\n .unwrap()\n .into_polars()\n .await\n .unwrap();\nprintln!(\"{curated:?}\");\n";
|
||||
export const RsQuickstartCurateWithMetadata = "let curated = table\n .query()\n .nearest_to(&query_vector)\n .unwrap()\n .only_if(\"stats.magic >= 4\")\n .select(Select::Columns(vec![\n \"name\".to_string(),\n \"role\".to_string(),\n \"description\".to_string(),\n \"_distance\".to_string(),\n ]))\n .limit(2)\n .execute()\n .await\n .unwrap()\n .into_polars()\n .await\n .unwrap();\nprintln!(\"{curated:?}\");\n";
|
||||
|
||||
export const RsQuickstartData = "let data = vec![\n Character {\n id: \"1\".to_string(),\n name: \"King Arthur\".to_string(),\n role: \"King\".to_string(),\n description: \"Leader of Camelot and wielder of Excalibur.\".to_string(),\n stats: Stats {\n strength: 4,\n magic: 1,\n leadership: 5,\n wisdom: 4,\n },\n vector: [0.7, 0.1, 0.9, 0.7],\n },\n Character {\n id: \"2\".to_string(),\n name: \"Merlin\".to_string(),\n role: \"Wizard\".to_string(),\n description: \"Advisor and prophet with deep magical knowledge.\".to_string(),\n stats: Stats {\n strength: 2,\n magic: 5,\n leadership: 4,\n wisdom: 5,\n },\n vector: [0.2, 0.9, 0.4, 0.9],\n },\n Character {\n id: \"3\".to_string(),\n name: \"Sir Lancelot\".to_string(),\n role: \"Knight\".to_string(),\n description: \"Legendary knight known for courage and combat skill.\".to_string(),\n stats: Stats {\n strength: 5,\n magic: 1,\n leadership: 3,\n wisdom: 3,\n },\n vector: [0.9, 0.1, 0.5, 0.4],\n },\n];\n";
|
||||
|
||||
export const RsQuickstartDefineStruct = "// Define structs representing the data schema\n#[derive(Debug, Clone, Serialize, Deserialize)]\nstruct Stats {\n strength: i8,\n magic: i8,\n leadership: i8,\n wisdom: i8,\n}\n\n#[derive(Debug, Clone, Serialize, Deserialize)]\nstruct Character {\n id: String,\n name: String,\n role: String,\n description: String,\n stats: Stats,\n vector: [f32; 4],\n}\n\nfn characters_schema() -> Arc<Schema> {\n Arc::new(Schema::new(vec![\n Field::new(\"id\", DataType::LargeUtf8, false),\n Field::new(\"name\", DataType::LargeUtf8, false),\n Field::new(\"role\", DataType::LargeUtf8, false),\n Field::new(\"description\", DataType::LargeUtf8, false),\n Field::new(\n \"stats\",\n DataType::Struct(arrow_schema::Fields::from(vec![\n Arc::new(Field::new(\"strength\", DataType::Int8, false)),\n Arc::new(Field::new(\"magic\", DataType::Int8, false)),\n Arc::new(Field::new(\"leadership\", DataType::Int8, false)),\n Arc::new(Field::new(\"wisdom\", DataType::Int8, false)),\n ])),\n false,\n ),\n Field::new(\n \"vector\",\n DataType::FixedSizeList(Arc::new(Field::new(\"item\", DataType::Float32, true)), 4),\n false,\n ),\n ]))\n}\n";
|
||||
export const RsQuickstartDefineStruct = "use std::sync::Arc;\n\nuse lancedb::arrow::arrow_array::types::Float32Type;\nuse lancedb::arrow::arrow_array::{\n FixedSizeListArray, Int8Array, LargeStringArray, RecordBatch, RecordBatchIterator,\n RecordBatchReader, StructArray,\n};\nuse lancedb::arrow::arrow_schema::{DataType, Field, FieldRef, Fields, Schema};\n\n// Define structs representing the data schema\n#[derive(Debug, Clone)]\nstruct Stats {\n strength: i8,\n magic: i8,\n leadership: i8,\n wisdom: i8,\n}\n\n#[derive(Debug, Clone)]\nstruct Character {\n id: String,\n name: String,\n role: String,\n description: String,\n stats: Stats,\n vector: [f32; 4],\n}\n\nfn characters_schema() -> Arc<Schema> {\n Arc::new(Schema::new(vec![\n Field::new(\"id\", DataType::LargeUtf8, false),\n Field::new(\"name\", DataType::LargeUtf8, false),\n Field::new(\"role\", DataType::LargeUtf8, false),\n Field::new(\"description\", DataType::LargeUtf8, false),\n Field::new(\n \"stats\",\n DataType::Struct(Fields::from(vec![\n Arc::new(Field::new(\"strength\", DataType::Int8, false)),\n Arc::new(Field::new(\"magic\", DataType::Int8, false)),\n Arc::new(Field::new(\"leadership\", DataType::Int8, false)),\n Arc::new(Field::new(\"wisdom\", DataType::Int8, false)),\n ])),\n false,\n ),\n Field::new(\n \"vector\",\n DataType::FixedSizeList(Arc::new(Field::new(\"item\", DataType::Float32, true)), 4),\n false,\n ),\n ]))\n}\n\nfn characters_to_reader(\n schema: Arc<Schema>,\n rows: &[Character],\n) -> Box<dyn RecordBatchReader + Send> {\n let ids = LargeStringArray::from_iter_values(rows.iter().map(|row| row.id.as_str()));\n let names = LargeStringArray::from_iter_values(rows.iter().map(|row| row.name.as_str()));\n let roles = LargeStringArray::from_iter_values(rows.iter().map(|row| row.role.as_str()));\n let descriptions =\n LargeStringArray::from_iter_values(rows.iter().map(|row| row.description.as_str()));\n\n let strength = Int8Array::from_iter_values(rows.iter().map(|row| row.stats.strength));\n let magic = Int8Array::from_iter_values(rows.iter().map(|row| row.stats.magic));\n let leadership = Int8Array::from_iter_values(rows.iter().map(|row| row.stats.leadership));\n let wisdom = Int8Array::from_iter_values(rows.iter().map(|row| row.stats.wisdom));\n let stats_fields: Vec<FieldRef> = vec![\n Arc::new(Field::new(\"strength\", DataType::Int8, false)),\n Arc::new(Field::new(\"magic\", DataType::Int8, false)),\n Arc::new(Field::new(\"leadership\", DataType::Int8, false)),\n Arc::new(Field::new(\"wisdom\", DataType::Int8, false)),\n ];\n let stats = StructArray::new(\n stats_fields.into(),\n vec![\n Arc::new(strength),\n Arc::new(magic),\n Arc::new(leadership),\n Arc::new(wisdom),\n ],\n None,\n );\n\n let vectors = FixedSizeListArray::from_iter_primitive::<Float32Type, _, _>(\n rows.iter()\n .map(|row| Some(row.vector.iter().copied().map(Some).collect::<Vec<_>>())),\n 4,\n );\n\n let batch = RecordBatch::try_new(\n schema.clone(),\n vec![\n Arc::new(ids),\n Arc::new(names),\n Arc::new(roles),\n Arc::new(descriptions),\n Arc::new(stats),\n Arc::new(vectors),\n ],\n )\n .unwrap();\n\n Box::new(RecordBatchIterator::new(\n vec![Ok(batch)].into_iter(),\n schema,\n ))\n}\n";
|
||||
|
||||
export const RsQuickstartMultimodalBytes = "use std::sync::Arc;\n\nuse arrow_array::{\n BinaryArray, FixedSizeListArray, LargeStringArray, RecordBatch, RecordBatchIterator,\n};\nuse arrow_schema::{DataType, Field, Schema};\n\nlet image_bytes = std::fs::read(\"data/sir-lancelot.jpg\").unwrap();\n\nlet image_schema = Arc::new(Schema::new(vec![\n Field::new(\"id\", DataType::LargeUtf8, false),\n Field::new(\"description\", DataType::LargeUtf8, false),\n Field::new(\"image\", DataType::Binary, false),\n Field::new(\n \"vector\",\n DataType::FixedSizeList(Arc::new(Field::new(\"item\", DataType::Float32, true)), 4),\n false,\n ),\n]));\nlet image_vectors = [[0.9_f32, 0.1, 0.5, 0.4]];\nlet image_batch = RecordBatch::try_new(\n image_schema.clone(),\n vec![\n Arc::new(LargeStringArray::from_iter_values([\"lancelot\"])),\n Arc::new(LargeStringArray::from_iter_values([\n \"Portrait of Sir Lancelot\",\n ])),\n Arc::new(BinaryArray::from_iter_values([image_bytes.as_slice()])),\n Arc::new(\n FixedSizeListArray::from_iter_primitive::<Float32Type, _, _>(\n image_vectors\n .iter()\n .map(|vector| Some(vector.iter().copied().map(Some).collect::<Vec<_>>())),\n 4,\n ),\n ),\n ],\n)\n.unwrap();\nlet image_reader: Box<dyn arrow_array::RecordBatchReader + Send> = Box::new(\n RecordBatchIterator::new(vec![Ok(image_batch)].into_iter(), image_schema),\n);\nlet multimodal_table = db\n .create_table(\"character_images\", image_reader)\n .mode(CreateTableMode::Overwrite)\n .execute()\n .await\n .unwrap();\n";
|
||||
export const RsQuickstartMultimodalBytes = "use lancedb::arrow::arrow_array::BinaryArray;\n\nlet image_bytes = std::fs::read(\"data/sir-lancelot.jpg\").unwrap();\n\nlet image_schema = Arc::new(Schema::new(vec![\n Field::new(\"id\", DataType::LargeUtf8, false),\n Field::new(\"description\", DataType::LargeUtf8, false),\n Field::new(\"image\", DataType::Binary, false),\n Field::new(\n \"vector\",\n DataType::FixedSizeList(Arc::new(Field::new(\"item\", DataType::Float32, true)), 4),\n false,\n ),\n]));\nlet image_vectors = [[0.9_f32, 0.1, 0.5, 0.4]];\nlet image_batch = RecordBatch::try_new(\n image_schema.clone(),\n vec![\n Arc::new(LargeStringArray::from_iter_values([\"lancelot\"])),\n Arc::new(LargeStringArray::from_iter_values([\n \"Portrait of Sir Lancelot\",\n ])),\n Arc::new(BinaryArray::from_iter_values([image_bytes.as_slice()])),\n Arc::new(\n FixedSizeListArray::from_iter_primitive::<Float32Type, _, _>(\n image_vectors\n .iter()\n .map(|vector| Some(vector.iter().copied().map(Some).collect::<Vec<_>>())),\n 4,\n ),\n ),\n ],\n)\n.unwrap();\nlet image_reader: Box<dyn RecordBatchReader + Send> = Box::new(RecordBatchIterator::new(\n vec![Ok(image_batch)].into_iter(),\n image_schema,\n));\nlet multimodal_table = db\n .create_table(\"character_images\", image_reader)\n .mode(CreateTableMode::Overwrite)\n .execute()\n .await\n .unwrap();\n";
|
||||
|
||||
export const RsQuickstartOutputArray = "let result: DataFrame = table\n .query()\n .nearest_to(&query_vector)\n .unwrap()\n .select(Select::Columns(vec![\n \"name\".to_string(),\n \"role\".to_string(),\n \"description\".to_string(),\n \"_distance\".to_string(),\n ]))\n .limit(2)\n .execute()\n .await\n .unwrap()\n .into_polars()\n .await\n .unwrap();\nprintln!(\"{result:?}\");\n";
|
||||
export const RsQuickstartOutputArray = "let result = table\n .query()\n .nearest_to(&query_vector)\n .unwrap()\n .select(Select::Columns(vec![\n \"name\".to_string(),\n \"role\".to_string(),\n \"description\".to_string(),\n \"_distance\".to_string(),\n ]))\n .limit(2)\n .execute()\n .await\n .unwrap()\n .into_polars()\n .await\n .unwrap();\nprintln!(\"{result:?}\");\n";
|
||||
|
||||
export const RsQuickstartQueryFeature = "let features: DataFrame = table\n .query()\n .select(Select::Columns(vec![\n \"name\".to_string(),\n \"role\".to_string(),\n \"power_score\".to_string(),\n ]))\n .execute()\n .await\n .unwrap()\n .into_polars()\n .await\n .unwrap();\nprintln!(\"{features:?}\");\n";
|
||||
export const RsQuickstartQueryFeature = "let features = table\n .query()\n .select(Select::Columns(vec![\n \"name\".to_string(),\n \"role\".to_string(),\n \"power_score\".to_string(),\n ]))\n .execute()\n .await\n .unwrap()\n .into_polars()\n .await\n .unwrap();\nprintln!(\"{features:?}\");\n";
|
||||
|
||||
export const RsQuickstartVectorSearch1 = "// Search for examples similar to a \"wise magical advisor\"\nlet query_vector = [0.2, 0.8, 0.4, 0.9];\n\nlet result: DataFrame = table\n .query()\n .nearest_to(&query_vector)\n .unwrap()\n .select(Select::Columns(vec![\n \"name\".to_string(),\n \"role\".to_string(),\n \"description\".to_string(),\n \"_distance\".to_string(),\n ]))\n .limit(2)\n .execute()\n .await\n .unwrap()\n .into_polars()\n .await\n .unwrap();\nprintln!(\"{result:?}\");\n";
|
||||
export const RsQuickstartVectorSearch1 = "use lancedb::arrow::IntoPolars;\nuse lancedb::query::{ExecutableQuery, QueryBase, Select};\n\n// Search for examples similar to a \"wise magical advisor\"\nlet query_vector = [0.2, 0.8, 0.4, 0.9];\n\nlet result = table\n .query()\n .nearest_to(&query_vector)\n .unwrap()\n .select(Select::Columns(vec![\n \"name\".to_string(),\n \"role\".to_string(),\n \"description\".to_string(),\n \"_distance\".to_string(),\n ]))\n .limit(2)\n .execute()\n .await\n .unwrap()\n .into_polars()\n .await\n .unwrap();\nprintln!(\"{result:?}\");\n";
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ embedded library.
|
||||
</CodeBlock>
|
||||
|
||||
<CodeBlock filename="TypeScript" language="TypeScript" icon="square-js">
|
||||
{ "import * as lancedb from \"@lancedb/lancedb\";\n\n" }
|
||||
{TsConnect}
|
||||
</CodeBlock>
|
||||
|
||||
@@ -114,6 +115,7 @@ every example that follows.
|
||||
</CodeBlock>
|
||||
|
||||
<CodeBlock filename="Rust" language="Rust" icon="rust">
|
||||
{ "use lancedb::connect;\n\n" }
|
||||
{RsConnectEnterpriseQuickstart}
|
||||
</CodeBlock>
|
||||
</CodeGroup>
|
||||
|
||||
Reference in New Issue
Block a user