Compare commits

..

8 Commits

Author SHA1 Message Date
Lance Release
a9897d9d85 Bump version: 0.18.1-beta.1 → 0.18.1-beta.2 2025-01-28 22:31:14 +00:00
Will Jones
acda7a4589 feat: upgrade lance to v0.23.0-beta.3 (#2074)
This includes several bugfixes for `merge_insert` and null handling in
vector search.

https://github.com/lancedb/lance/releases/tag/v0.23.0-beta.3
2025-01-28 14:00:06 -08:00
Vaibhav
dac0857745 feat: add distance_type() parameter to python sync query builders and metric() as an alias (#2073)
This PR aims to fix #2047 by doing the following things:
- Add a distance_type parameter to the sync query builders of Python
SDK.
- Make metric an alias to distance_type.
2025-01-28 13:59:53 -08:00
Will Jones
0a9e1eab75 fix(node): createTable() should save embeddings, and mergeInsert should use them (#2065)
* `createTable()` now saves embeddings in the schema metadata.
Previously, it would drop them. (`createEmptyTable()` was already tested
and worked.)
* `mergeInsert()` now uses embeddings.

Fixes #2066
2025-01-28 12:38:50 -08:00
V
d999d72c8d docs: pandas example (#2044)
Fix example for section ## From pandas DataFrame
2025-01-24 11:37:47 -08:00
Lance Release
de4720993e Updating package-lock.json 2025-01-23 23:02:20 +00:00
Lance Release
6c14a307e2 Updating package-lock.json 2025-01-23 23:02:03 +00:00
Lance Release
43747278c8 Bump version: 0.15.0 → 0.15.1-beta.0 2025-01-23 23:01:40 +00:00
33 changed files with 241 additions and 189 deletions

View File

@@ -1,5 +1,5 @@
[tool.bumpversion] [tool.bumpversion]
current_version = "0.15.0" current_version = "0.15.1-beta.0"
parse = """(?x) parse = """(?x)
(?P<major>0|[1-9]\\d*)\\. (?P<major>0|[1-9]\\d*)\\.
(?P<minor>0|[1-9]\\d*)\\. (?P<minor>0|[1-9]\\d*)\\.

View File

@@ -23,14 +23,14 @@ rust-version = "1.78.0"
[workspace.dependencies] [workspace.dependencies]
lance = { "version" = "=0.23.0", "features" = [ lance = { "version" = "=0.23.0", "features" = [
"dynamodb", "dynamodb",
], git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.2" } ], git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.3" }
lance-io = { version = "=0.23.0", git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.2" } lance-io = { version = "=0.23.0", git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.3" }
lance-index = { version = "=0.23.0", git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.2" } lance-index = { version = "=0.23.0", git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.3" }
lance-linalg = { version = "=0.23.0", git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.2" } lance-linalg = { version = "=0.23.0", git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.3" }
lance-table = { version = "=0.23.0", git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.2" } lance-table = { version = "=0.23.0", git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.3" }
lance-testing = { version = "=0.23.0", git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.2" } lance-testing = { version = "=0.23.0", git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.3" }
lance-datafusion = { version = "=0.23.0", git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.2" } lance-datafusion = { version = "=0.23.0", git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.3" }
lance-encoding = { version = "=0.23.0", git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.2" } lance-encoding = { version = "=0.23.0", git = "https://github.com/lancedb/lance.git", tag = "v0.23.0-beta.3" }
# Note that this one does not include pyarrow # Note that this one does not include pyarrow
arrow = { version = "53.2", optional = false } arrow = { version = "53.2", optional = false }
arrow-array = "53.2" arrow-array = "53.2"

View File

@@ -114,14 +114,17 @@
} }
], ],
"source": [ "source": [
"data = [\n", "import pandas as pd\n",
" {\"vector\": [1.1, 1.2], \"lat\": 45.5, \"long\": -122.7},\n",
" {\"vector\": [0.2, 1.8], \"lat\": 40.1, \"long\": -74.1},\n",
"]\n",
"\n", "\n",
"db.create_table(\"table2\", data)\n", "data = pd.DataFrame(\n",
"\n", " {\n",
"db[\"table2\"].head() " " \"vector\": [[1.1, 1.2, 1.3, 1.4], [0.2, 1.8, 0.4, 3.6]],\n",
" \"lat\": [45.5, 40.1],\n",
" \"long\": [-122.7, -74.1],\n",
" }\n",
")\n",
"db.create_table(\"my_table_pandas\", data)\n",
"db[\"my_table_pandas\"].head()"
] ]
}, },
{ {
@@ -164,7 +167,7 @@
"import pyarrow as pa\n", "import pyarrow as pa\n",
"\n", "\n",
"custom_schema = pa.schema([\n", "custom_schema = pa.schema([\n",
"pa.field(\"vector\", pa.list_(pa.float32(), 2)),\n", "pa.field(\"vector\", pa.list_(pa.float32(), 4)),\n",
"pa.field(\"lat\", pa.float32()),\n", "pa.field(\"lat\", pa.float32()),\n",
"pa.field(\"long\", pa.float32())\n", "pa.field(\"long\", pa.float32())\n",
"])\n", "])\n",

View File

@@ -8,7 +8,7 @@
<parent> <parent>
<groupId>com.lancedb</groupId> <groupId>com.lancedb</groupId>
<artifactId>lancedb-parent</artifactId> <artifactId>lancedb-parent</artifactId>
<version>0.15.0-final.0</version> <version>0.15.1-beta.0</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@@ -6,7 +6,7 @@
<groupId>com.lancedb</groupId> <groupId>com.lancedb</groupId>
<artifactId>lancedb-parent</artifactId> <artifactId>lancedb-parent</artifactId>
<version>0.15.0-final.0</version> <version>0.15.1-beta.0</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>LanceDB Parent</name> <name>LanceDB Parent</name>

124
node/package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "vectordb", "name": "vectordb",
"version": "0.15.0", "version": "0.15.1-beta.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "vectordb", "name": "vectordb",
"version": "0.15.0", "version": "0.15.1-beta.0",
"cpu": [ "cpu": [
"x64", "x64",
"arm64" "arm64"
@@ -52,14 +52,14 @@
"uuid": "^9.0.0" "uuid": "^9.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@lancedb/vectordb-darwin-arm64": "0.15.0", "@lancedb/vectordb-darwin-arm64": "0.15.1-beta.0",
"@lancedb/vectordb-darwin-x64": "0.15.0", "@lancedb/vectordb-darwin-x64": "0.15.1-beta.0",
"@lancedb/vectordb-linux-arm64-gnu": "0.15.0", "@lancedb/vectordb-linux-arm64-gnu": "0.15.1-beta.0",
"@lancedb/vectordb-linux-arm64-musl": "0.15.0", "@lancedb/vectordb-linux-arm64-musl": "0.15.1-beta.0",
"@lancedb/vectordb-linux-x64-gnu": "0.15.0", "@lancedb/vectordb-linux-x64-gnu": "0.15.1-beta.0",
"@lancedb/vectordb-linux-x64-musl": "0.15.0", "@lancedb/vectordb-linux-x64-musl": "0.15.1-beta.0",
"@lancedb/vectordb-win32-arm64-msvc": "0.15.0", "@lancedb/vectordb-win32-arm64-msvc": "0.15.1-beta.0",
"@lancedb/vectordb-win32-x64-msvc": "0.15.0" "@lancedb/vectordb-win32-x64-msvc": "0.15.1-beta.0"
}, },
"peerDependencies": { "peerDependencies": {
"@apache-arrow/ts": "^14.0.2", "@apache-arrow/ts": "^14.0.2",
@@ -329,110 +329,6 @@
"@jridgewell/sourcemap-codec": "^1.4.10" "@jridgewell/sourcemap-codec": "^1.4.10"
} }
}, },
"node_modules/@lancedb/vectordb-darwin-arm64": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-darwin-arm64/-/vectordb-darwin-arm64-0.15.0.tgz",
"integrity": "sha512-FnBRsCrxvecjhkMQus9M9RQpXyhu1jxQjYGDaqqRIfcUd3ew7ahIR4qk9FyALHmjpPd72xJZgNLjliHtsIX4/w==",
"cpu": [
"arm64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@lancedb/vectordb-darwin-x64": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-darwin-x64/-/vectordb-darwin-x64-0.15.0.tgz",
"integrity": "sha512-zy+nt1WBCabVI16u2t3sqGUXBOmnF5ZXMsHa9TWYEXVnbw5112K7/1783DTNA/ZBI/WziUa5jqYQ0GOwkgruqA==",
"cpu": [
"x64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@lancedb/vectordb-linux-arm64-gnu": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-linux-arm64-gnu/-/vectordb-linux-arm64-gnu-0.15.0.tgz",
"integrity": "sha512-2Pbw+z5Ij5QBvmBxmjaT5F2lNHftVWlarDM1bDc4JtgodJ3Js729qnVLQ0yehnlt+hM6aGFEyn8bH5vf6gEvpQ==",
"cpu": [
"arm64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@lancedb/vectordb-linux-arm64-musl": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-linux-arm64-musl/-/vectordb-linux-arm64-musl-0.15.0.tgz",
"integrity": "sha512-WIvgd2EY2maCdYNHPC0C9RprjNWL83FkQKtn591xixltFk3XKgvBQ2USZW2tXndH/WVdvFQvystmZ3dgUrh8DQ==",
"cpu": [
"arm64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@lancedb/vectordb-linux-x64-gnu": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-linux-x64-gnu/-/vectordb-linux-x64-gnu-0.15.0.tgz",
"integrity": "sha512-Pet3aPE+yQT13Gm0+fh11pgHvImS4X8Uf0zRdzsx0eja7x8j15VrVcZTEVTT4QdBNiZrhXBuiq482NJBsqe6vw==",
"cpu": [
"x64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@lancedb/vectordb-linux-x64-musl": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-linux-x64-musl/-/vectordb-linux-x64-musl-0.15.0.tgz",
"integrity": "sha512-BC1RvIoEmyOr7ENp618vs9F05gdN7aKlToJNZnGIoi++hRZ25y39B1xxMXQHDnUL8G+Ur9kJObfQ43nVWqueTQ==",
"cpu": [
"x64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@lancedb/vectordb-win32-arm64-msvc": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-win32-arm64-msvc/-/vectordb-win32-arm64-msvc-0.15.0.tgz",
"integrity": "sha512-H9BeryZl1aLxldtVP0XyiQJyzKStkuxS6SmIg+zaANr9Dns+LmVxYCz429JLC0DlvBWoYjTfK9WJTgMSZXr0Cg==",
"cpu": [
"arm64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@lancedb/vectordb-win32-x64-msvc": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-win32-x64-msvc/-/vectordb-win32-x64-msvc-0.15.0.tgz",
"integrity": "sha512-J8JICux2M82OR27i/4YAbEPlvszuE7EnGIU5jmm2+RTFaptKOCshH1C4D4jEXDAaHcUkVgsxyc9lGmGJCkGLhg==",
"cpu": [
"x64"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@neon-rs/cli": { "node_modules/@neon-rs/cli": {
"version": "0.0.160", "version": "0.0.160",
"resolved": "https://registry.npmjs.org/@neon-rs/cli/-/cli-0.0.160.tgz", "resolved": "https://registry.npmjs.org/@neon-rs/cli/-/cli-0.0.160.tgz",

View File

@@ -1,6 +1,6 @@
{ {
"name": "vectordb", "name": "vectordb",
"version": "0.15.0", "version": "0.15.1-beta.0",
"description": " Serverless, low-latency vector database for AI applications", "description": " Serverless, low-latency vector database for AI applications",
"private": false, "private": false,
"main": "dist/index.js", "main": "dist/index.js",
@@ -92,13 +92,13 @@
} }
}, },
"optionalDependencies": { "optionalDependencies": {
"@lancedb/vectordb-darwin-x64": "0.15.0", "@lancedb/vectordb-darwin-x64": "0.15.1-beta.0",
"@lancedb/vectordb-darwin-arm64": "0.15.0", "@lancedb/vectordb-darwin-arm64": "0.15.1-beta.0",
"@lancedb/vectordb-linux-x64-gnu": "0.15.0", "@lancedb/vectordb-linux-x64-gnu": "0.15.1-beta.0",
"@lancedb/vectordb-linux-arm64-gnu": "0.15.0", "@lancedb/vectordb-linux-arm64-gnu": "0.15.1-beta.0",
"@lancedb/vectordb-linux-x64-musl": "0.15.0", "@lancedb/vectordb-linux-x64-musl": "0.15.1-beta.0",
"@lancedb/vectordb-linux-arm64-musl": "0.15.0", "@lancedb/vectordb-linux-arm64-musl": "0.15.1-beta.0",
"@lancedb/vectordb-win32-x64-msvc": "0.15.0", "@lancedb/vectordb-win32-x64-msvc": "0.15.1-beta.0",
"@lancedb/vectordb-win32-arm64-msvc": "0.15.0" "@lancedb/vectordb-win32-arm64-msvc": "0.15.1-beta.0"
} }
} }

View File

@@ -1,7 +1,7 @@
[package] [package]
name = "lancedb-nodejs" name = "lancedb-nodejs"
edition.workspace = true edition.workspace = true
version = "0.15.0" version = "0.15.1-beta.0"
license.workspace = true license.workspace = true
description.workspace = true description.workspace = true
repository.workspace = true repository.workspace = true

View File

@@ -83,6 +83,74 @@ describe("embedding functions", () => {
expect(vector0).toEqual([1, 2, 3]); expect(vector0).toEqual([1, 2, 3]);
}); });
it("should be able to append and upsert using embedding function", async () => {
@register()
class MockEmbeddingFunction extends EmbeddingFunction<string> {
toJSON(): object {
return {};
}
ndims() {
return 3;
}
embeddingDataType(): Float {
return new Float32();
}
async computeQueryEmbeddings(_data: string) {
return [1, 2, 3];
}
async computeSourceEmbeddings(data: string[]) {
return Array.from({ length: data.length }).fill([
1, 2, 3,
]) as number[][];
}
}
const func = new MockEmbeddingFunction();
const db = await connect(tmpDir.name);
const table = await db.createTable(
"test",
[
{ id: 1, text: "hello" },
{ id: 2, text: "world" },
],
{
embeddingFunction: {
function: func,
sourceColumn: "text",
},
},
);
const schema = await table.schema();
expect(schema.metadata.get("embedding_functions")).toBeDefined();
// Append some new data
const data1 = [
{ id: 3, text: "forest" },
{ id: 4, text: "mountain" },
];
await table.add(data1);
// Upsert some data
const data2 = [
{ id: 5, text: "river" },
{ id: 2, text: "canyon" },
];
await table
.mergeInsert("id")
.whenMatchedUpdateAll()
.whenNotMatchedInsertAll()
.execute(data2);
const rows = await table.query().toArray();
rows.sort((a, b) => a.id - b.id);
const texts = rows.map((row) => row.text);
expect(texts).toEqual(["hello", "canyon", "forest", "mountain", "river"]);
const vectorsDefined = rows.map(
(row) => row.vector !== undefined && row.vector !== null,
);
expect(vectorsDefined).toEqual(new Array(5).fill(true));
});
it("should be able to create an empty table with an embedding function", async () => { it("should be able to create an empty table with an embedding function", async () => {
@register() @register()
class MockEmbeddingFunction extends EmbeddingFunction<string> { class MockEmbeddingFunction extends EmbeddingFunction<string> {

View File

@@ -609,6 +609,14 @@ async function applyEmbeddings<T>(
return table; return table;
} }
let schemaMetadata = schema?.metadata || new Map<string, string>();
if (!(embeddings == null || embeddings === undefined)) {
const registry = getRegistry();
const embeddingMetadata = registry.getTableMetadata([embeddings]);
schemaMetadata = new Map([...schemaMetadata, ...embeddingMetadata]);
}
// Convert from ArrowTable to Record<String, Vector> // Convert from ArrowTable to Record<String, Vector>
const colEntries = [...Array(table.numCols).keys()].map((_, idx) => { const colEntries = [...Array(table.numCols).keys()].map((_, idx) => {
const name = table.schema.fields[idx].name; const name = table.schema.fields[idx].name;
@@ -677,15 +685,21 @@ async function applyEmbeddings<T>(
newColumns[destColumn] = makeVector(vectors, destType); newColumns[destColumn] = makeVector(vectors, destType);
} }
const newTable = new ArrowTable(newColumns); let newTable = new ArrowTable(newColumns);
if (schema != null) { if (schema != null) {
if (schema.fields.find((f) => f.name === destColumn) === undefined) { if (schema.fields.find((f) => f.name === destColumn) === undefined) {
throw new Error( throw new Error(
`When using embedding functions and specifying a schema the schema should include the embedding column but the column ${destColumn} was missing`, `When using embedding functions and specifying a schema the schema should include the embedding column but the column ${destColumn} was missing`,
); );
} }
return alignTable(newTable, schema as Schema); newTable = alignTable(newTable, schema as Schema);
} }
newTable = new ArrowTable(
new Schema(newTable.schema.fields, schemaMetadata),
newTable.batches,
);
return newTable; return newTable;
} }

View File

@@ -1,13 +1,20 @@
import { Data, fromDataToBuffer } from "./arrow"; // SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright The LanceDB Authors
import { Data, Schema, fromDataToBuffer } from "./arrow";
import { NativeMergeInsertBuilder } from "./native"; import { NativeMergeInsertBuilder } from "./native";
/** A builder used to create and run a merge insert operation */ /** A builder used to create and run a merge insert operation */
export class MergeInsertBuilder { export class MergeInsertBuilder {
#native: NativeMergeInsertBuilder; #native: NativeMergeInsertBuilder;
#schema: Schema | Promise<Schema>;
/** Construct a MergeInsertBuilder. __Internal use only.__ */ /** Construct a MergeInsertBuilder. __Internal use only.__ */
constructor(native: NativeMergeInsertBuilder) { constructor(
native: NativeMergeInsertBuilder,
schema: Schema | Promise<Schema>,
) {
this.#native = native; this.#native = native;
this.#schema = schema;
} }
/** /**
@@ -35,6 +42,7 @@ export class MergeInsertBuilder {
whenMatchedUpdateAll(options?: { where: string }): MergeInsertBuilder { whenMatchedUpdateAll(options?: { where: string }): MergeInsertBuilder {
return new MergeInsertBuilder( return new MergeInsertBuilder(
this.#native.whenMatchedUpdateAll(options?.where), this.#native.whenMatchedUpdateAll(options?.where),
this.#schema,
); );
} }
/** /**
@@ -42,7 +50,10 @@ export class MergeInsertBuilder {
* be inserted into the target table. * be inserted into the target table.
*/ */
whenNotMatchedInsertAll(): MergeInsertBuilder { whenNotMatchedInsertAll(): MergeInsertBuilder {
return new MergeInsertBuilder(this.#native.whenNotMatchedInsertAll()); return new MergeInsertBuilder(
this.#native.whenNotMatchedInsertAll(),
this.#schema,
);
} }
/** /**
* Rows that exist only in the target table (old data) will be * Rows that exist only in the target table (old data) will be
@@ -56,6 +67,7 @@ export class MergeInsertBuilder {
}): MergeInsertBuilder { }): MergeInsertBuilder {
return new MergeInsertBuilder( return new MergeInsertBuilder(
this.#native.whenNotMatchedBySourceDelete(options?.where), this.#native.whenNotMatchedBySourceDelete(options?.where),
this.#schema,
); );
} }
/** /**
@@ -64,7 +76,14 @@ export class MergeInsertBuilder {
* Nothing is returned but the `Table` is updated * Nothing is returned but the `Table` is updated
*/ */
async execute(data: Data): Promise<void> { async execute(data: Data): Promise<void> {
const buffer = await fromDataToBuffer(data); let schema: Schema;
if (this.#schema instanceof Promise) {
schema = await this.#schema;
this.#schema = schema; // In case of future calls
} else {
schema = this.#schema;
}
const buffer = await fromDataToBuffer(data, undefined, schema);
await this.#native.execute(buffer); await this.#native.execute(buffer);
} }
} }

View File

@@ -520,14 +520,8 @@ export class LocalTable extends Table {
async add(data: Data, options?: Partial<AddDataOptions>): Promise<void> { async add(data: Data, options?: Partial<AddDataOptions>): Promise<void> {
const mode = options?.mode ?? "append"; const mode = options?.mode ?? "append";
const schema = await this.schema(); const schema = await this.schema();
const registry = getRegistry();
const functions = await registry.parseFunctions(schema.metadata);
const buffer = await fromDataToBuffer( const buffer = await fromDataToBuffer(data, undefined, schema);
data,
functions.values().next().value,
schema,
);
await this.inner.add(buffer, mode); await this.inner.add(buffer, mode);
} }
@@ -733,7 +727,7 @@ export class LocalTable extends Table {
} }
mergeInsert(on: string | string[]): MergeInsertBuilder { mergeInsert(on: string | string[]): MergeInsertBuilder {
on = Array.isArray(on) ? on : [on]; on = Array.isArray(on) ? on : [on];
return new MergeInsertBuilder(this.inner.mergeInsert(on)); return new MergeInsertBuilder(this.inner.mergeInsert(on), this.schema());
} }
/** /**

View File

@@ -1,6 +1,6 @@
{ {
"name": "@lancedb/lancedb-darwin-arm64", "name": "@lancedb/lancedb-darwin-arm64",
"version": "0.15.0", "version": "0.15.1-beta.0",
"os": ["darwin"], "os": ["darwin"],
"cpu": ["arm64"], "cpu": ["arm64"],
"main": "lancedb.darwin-arm64.node", "main": "lancedb.darwin-arm64.node",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@lancedb/lancedb-darwin-x64", "name": "@lancedb/lancedb-darwin-x64",
"version": "0.15.0", "version": "0.15.1-beta.0",
"os": ["darwin"], "os": ["darwin"],
"cpu": ["x64"], "cpu": ["x64"],
"main": "lancedb.darwin-x64.node", "main": "lancedb.darwin-x64.node",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@lancedb/lancedb-linux-arm64-gnu", "name": "@lancedb/lancedb-linux-arm64-gnu",
"version": "0.15.0", "version": "0.15.1-beta.0",
"os": ["linux"], "os": ["linux"],
"cpu": ["arm64"], "cpu": ["arm64"],
"main": "lancedb.linux-arm64-gnu.node", "main": "lancedb.linux-arm64-gnu.node",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@lancedb/lancedb-linux-arm64-musl", "name": "@lancedb/lancedb-linux-arm64-musl",
"version": "0.15.0", "version": "0.15.1-beta.0",
"os": ["linux"], "os": ["linux"],
"cpu": ["arm64"], "cpu": ["arm64"],
"main": "lancedb.linux-arm64-musl.node", "main": "lancedb.linux-arm64-musl.node",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@lancedb/lancedb-linux-x64-gnu", "name": "@lancedb/lancedb-linux-x64-gnu",
"version": "0.15.0", "version": "0.15.1-beta.0",
"os": ["linux"], "os": ["linux"],
"cpu": ["x64"], "cpu": ["x64"],
"main": "lancedb.linux-x64-gnu.node", "main": "lancedb.linux-x64-gnu.node",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@lancedb/lancedb-linux-x64-musl", "name": "@lancedb/lancedb-linux-x64-musl",
"version": "0.15.0", "version": "0.15.1-beta.0",
"os": ["linux"], "os": ["linux"],
"cpu": ["x64"], "cpu": ["x64"],
"main": "lancedb.linux-x64-musl.node", "main": "lancedb.linux-x64-musl.node",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@lancedb/lancedb-win32-arm64-msvc", "name": "@lancedb/lancedb-win32-arm64-msvc",
"version": "0.15.0", "version": "0.15.1-beta.0",
"os": [ "os": [
"win32" "win32"
], ],

View File

@@ -1,6 +1,6 @@
{ {
"name": "@lancedb/lancedb-win32-x64-msvc", "name": "@lancedb/lancedb-win32-x64-msvc",
"version": "0.15.0", "version": "0.15.1-beta.0",
"os": ["win32"], "os": ["win32"],
"cpu": ["x64"], "cpu": ["x64"],
"main": "lancedb.win32-x64-msvc.node", "main": "lancedb.win32-x64-msvc.node",

View File

@@ -1,12 +1,12 @@
{ {
"name": "@lancedb/lancedb", "name": "@lancedb/lancedb",
"version": "0.15.0", "version": "0.15.1-beta.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@lancedb/lancedb", "name": "@lancedb/lancedb",
"version": "0.15.0", "version": "0.15.1-beta.0",
"cpu": [ "cpu": [
"x64", "x64",
"arm64" "arm64"

View File

@@ -11,7 +11,7 @@
"ann" "ann"
], ],
"private": false, "private": false,
"version": "0.15.0", "version": "0.15.1-beta.0",
"main": "dist/index.js", "main": "dist/index.js",
"exports": { "exports": {
".": "./dist/index.js", ".": "./dist/index.js",

View File

@@ -1,5 +1,5 @@
[tool.bumpversion] [tool.bumpversion]
current_version = "0.18.1-beta.1" current_version = "0.18.1-beta.2"
parse = """(?x) parse = """(?x)
(?P<major>0|[1-9]\\d*)\\. (?P<major>0|[1-9]\\d*)\\.
(?P<minor>0|[1-9]\\d*)\\. (?P<minor>0|[1-9]\\d*)\\.

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "lancedb-python" name = "lancedb-python"
version = "0.18.1-beta.1" version = "0.18.1-beta.2"
edition.workspace = true edition.workspace = true
description = "Python bindings for LanceDB" description = "Python bindings for LanceDB"
license.workspace = true license.workspace = true

View File

@@ -4,7 +4,7 @@ name = "lancedb"
dynamic = ["version"] dynamic = ["version"]
dependencies = [ dependencies = [
"deprecation", "deprecation",
"pylance==0.23.0b2", "pylance==0.23.0b3",
"tqdm>=4.27.0", "tqdm>=4.27.0",
"pydantic>=1.10", "pydantic>=1.10",
"packaging", "packaging",

View File

@@ -505,7 +505,7 @@ class LanceQueryBuilder(ABC):
"column": self._vector_column, "column": self._vector_column,
"q": self._query, "q": self._query,
"k": self._limit, "k": self._limit,
"metric": self._metric, "metric": self._distance_type,
"nprobes": self._nprobes, "nprobes": self._nprobes,
"refine_factor": self._refine_factor, "refine_factor": self._refine_factor,
"use_index": self._use_index, "use_index": self._use_index,
@@ -576,7 +576,7 @@ class LanceVectorQueryBuilder(LanceQueryBuilder):
>>> db = lancedb.connect("./.lancedb") >>> db = lancedb.connect("./.lancedb")
>>> table = db.create_table("my_table", data=data) >>> table = db.create_table("my_table", data=data)
>>> (table.search([0.4, 0.4]) >>> (table.search([0.4, 0.4])
... .metric("cosine") ... .distance_type("cosine")
... .where("b < 10") ... .where("b < 10")
... .select(["b", "vector"]) ... .select(["b", "vector"])
... .limit(2) ... .limit(2)
@@ -596,7 +596,7 @@ class LanceVectorQueryBuilder(LanceQueryBuilder):
): ):
super().__init__(table) super().__init__(table)
self._query = query self._query = query
self._metric = "L2" self._distance_type = "L2"
self._nprobes = 20 self._nprobes = 20
self._lower_bound = None self._lower_bound = None
self._upper_bound = None self._upper_bound = None
@@ -610,6 +610,9 @@ class LanceVectorQueryBuilder(LanceQueryBuilder):
def metric(self, metric: Literal["L2", "cosine", "dot"]) -> LanceVectorQueryBuilder: def metric(self, metric: Literal["L2", "cosine", "dot"]) -> LanceVectorQueryBuilder:
"""Set the distance metric to use. """Set the distance metric to use.
This is an alias for distance_type() and may be deprecated in the future.
Please use distance_type() instead.
Parameters Parameters
---------- ----------
metric: "L2" or "cosine" or "dot" metric: "L2" or "cosine" or "dot"
@@ -620,7 +623,32 @@ class LanceVectorQueryBuilder(LanceQueryBuilder):
LanceVectorQueryBuilder LanceVectorQueryBuilder
The LanceQueryBuilder object. The LanceQueryBuilder object.
""" """
self._metric = metric.lower() return self.distance_type(metric)
def distance_type(
self, distance_type: Literal["L2", "cosine", "dot"]
) -> "LanceVectorQueryBuilder":
"""Set the distance metric to use.
When performing a vector search we try and find the "nearest" vectors according
to some kind of distance metric. This parameter controls which distance metric
to use.
Note: if there is a vector index then the distance type used MUST match the
distance type used to train the vector index. If this is not done then the
results will be invalid.
Parameters
----------
distance_type: "L2" or "cosine" or "dot"
The distance metric to use. By default "L2" is used.
Returns
-------
LanceVectorQueryBuilder
The LanceQueryBuilder object.
"""
self._distance_type = distance_type.lower()
return self return self
def nprobes(self, nprobes: int) -> LanceVectorQueryBuilder: def nprobes(self, nprobes: int) -> LanceVectorQueryBuilder:
@@ -745,7 +773,7 @@ class LanceVectorQueryBuilder(LanceQueryBuilder):
filter=self._where, filter=self._where,
prefilter=self._prefilter, prefilter=self._prefilter,
k=self._limit, k=self._limit,
metric=self._metric, metric=self._distance_type,
columns=self._columns, columns=self._columns,
nprobes=self._nprobes, nprobes=self._nprobes,
lower_bound=self._lower_bound, lower_bound=self._lower_bound,
@@ -1078,7 +1106,7 @@ class LanceHybridQueryBuilder(LanceQueryBuilder):
self._reranker = RRFReranker() self._reranker = RRFReranker()
self._nprobes = None self._nprobes = None
self._refine_factor = None self._refine_factor = None
self._metric = None self._distance_type = None
self._phrase_query = False self._phrase_query = False
def _validate_query(self, query, vector=None, text=None): def _validate_query(self, query, vector=None, text=None):
@@ -1146,8 +1174,8 @@ class LanceHybridQueryBuilder(LanceQueryBuilder):
self._fts_query.with_row_id(True) self._fts_query.with_row_id(True)
if self._phrase_query: if self._phrase_query:
self._fts_query.phrase_query(True) self._fts_query.phrase_query(True)
if self._metric: if self._distance_type:
self._vector_query.metric(self._metric) self._vector_query.metric(self._distance_type)
if self._nprobes: if self._nprobes:
self._vector_query.nprobes(self._nprobes) self._vector_query.nprobes(self._nprobes)
if self._refine_factor: if self._refine_factor:
@@ -1386,6 +1414,9 @@ class LanceHybridQueryBuilder(LanceQueryBuilder):
def metric(self, metric: Literal["L2", "cosine", "dot"]) -> LanceHybridQueryBuilder: def metric(self, metric: Literal["L2", "cosine", "dot"]) -> LanceHybridQueryBuilder:
"""Set the distance metric to use. """Set the distance metric to use.
This is an alias for distance_type() and may be deprecated in the future.
Please use distance_type() instead.
Parameters Parameters
---------- ----------
metric: "L2" or "cosine" or "dot" metric: "L2" or "cosine" or "dot"
@@ -1396,7 +1427,32 @@ class LanceHybridQueryBuilder(LanceQueryBuilder):
LanceVectorQueryBuilder LanceVectorQueryBuilder
The LanceQueryBuilder object. The LanceQueryBuilder object.
""" """
self._metric = metric.lower() return self.distance_type(metric)
def distance_type(
self, distance_type: Literal["L2", "cosine", "dot"]
) -> "LanceHybridQueryBuilder":
"""Set the distance metric to use.
When performing a vector search we try and find the "nearest" vectors according
to some kind of distance metric. This parameter controls which distance metric
to use.
Note: if there is a vector index then the distance type used MUST match the
distance type used to train the vector index. If this is not done then the
results will be invalid.
Parameters
----------
distance_type: "L2" or "cosine" or "dot"
The distance metric to use. By default "L2" is used.
Returns
-------
LanceVectorQueryBuilder
The LanceQueryBuilder object.
"""
self._distance_type = distance_type.lower()
return self return self
def refine_factor(self, refine_factor: int) -> LanceHybridQueryBuilder: def refine_factor(self, refine_factor: int) -> LanceHybridQueryBuilder:

View File

@@ -38,7 +38,7 @@ def test_binary_vector():
query = np.random.randint(0, 2, size=256) query = np.random.randint(0, 2, size=256)
packed_query = np.packbits(query) packed_query = np.packbits(query)
tbl.search(packed_query).metric("hamming").to_arrow() tbl.search(packed_query).distance_type("hamming").to_arrow()
# --8<-- [end:sync_binary_vector] # --8<-- [end:sync_binary_vector]
db.drop_table("my_binary_vectors") db.drop_table("my_binary_vectors")

View File

@@ -65,7 +65,7 @@ def test_vector_search():
tbl.search(np.random.random((1536))).limit(10).to_list() tbl.search(np.random.random((1536))).limit(10).to_list()
# --8<-- [end:exhaustive_search] # --8<-- [end:exhaustive_search]
# --8<-- [start:exhaustive_search_cosine] # --8<-- [start:exhaustive_search_cosine]
tbl.search(np.random.random((1536))).metric("cosine").limit(10).to_list() tbl.search(np.random.random((1536))).distance_type("cosine").limit(10).to_list()
# --8<-- [end:exhaustive_search_cosine] # --8<-- [end:exhaustive_search_cosine]
# --8<-- [start:create_table_with_nested_schema] # --8<-- [start:create_table_with_nested_schema]
# Let's add 100 sample rows to our dataset # Let's add 100 sample rows to our dataset

View File

@@ -377,14 +377,14 @@ def test_query_builder_with_metric(table):
df_default = LanceVectorQueryBuilder(table, query, vector_column_name).to_pandas() df_default = LanceVectorQueryBuilder(table, query, vector_column_name).to_pandas()
df_l2 = ( df_l2 = (
LanceVectorQueryBuilder(table, query, vector_column_name) LanceVectorQueryBuilder(table, query, vector_column_name)
.metric("L2") .distance_type("L2")
.to_pandas() .to_pandas()
) )
tm.assert_frame_equal(df_default, df_l2) tm.assert_frame_equal(df_default, df_l2)
df_cosine = ( df_cosine = (
LanceVectorQueryBuilder(table, query, vector_column_name) LanceVectorQueryBuilder(table, query, vector_column_name)
.metric("cosine") .distance_type("cosine")
.limit(1) .limit(1)
.to_pandas() .to_pandas()
) )
@@ -401,7 +401,7 @@ def test_query_builder_with_different_vector_column():
vector_column_name = "foo_vector" vector_column_name = "foo_vector"
builder = ( builder = (
LanceVectorQueryBuilder(table, query, vector_column_name) LanceVectorQueryBuilder(table, query, vector_column_name)
.metric("cosine") .distance_type("cosine")
.where("b < 10") .where("b < 10")
.select(["b"]) .select(["b"])
.limit(2) .limit(2)

View File

@@ -366,7 +366,7 @@ def test_query_sync_maximal():
with query_test_table(handler) as table: with query_test_table(handler) as table:
( (
table.search([1, 2, 3], vector_column_name="vector2", fast_search=True) table.search([1, 2, 3], vector_column_name="vector2", fast_search=True)
.metric("cosine") .distance_type("cosine")
.limit(42) .limit(42)
.offset(10) .offset(10)
.refine_factor(10) .refine_factor(10)

View File

@@ -1242,7 +1242,9 @@ def test_hybrid_search_metric_type(tmp_db: DBConnection):
# with custom metric # with custom metric
result_dot = ( result_dot = (
table.search("feeling lucky", query_type="hybrid").metric("dot").to_arrow() table.search("feeling lucky", query_type="hybrid")
.distance_type("dot")
.to_arrow()
) )
result_l2 = table.search("feeling lucky", query_type="hybrid").to_arrow() result_l2 = table.search("feeling lucky", query_type="hybrid").to_arrow()
assert len(result_dot) > 0 assert len(result_dot) > 0

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "lancedb-node" name = "lancedb-node"
version = "0.15.0" version = "0.15.1-beta.0"
description = "Serverless, low-latency vector database for AI applications" description = "Serverless, low-latency vector database for AI applications"
license.workspace = true license.workspace = true
edition.workspace = true edition.workspace = true

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "lancedb" name = "lancedb"
version = "0.15.0" version = "0.15.1-beta.0"
edition.workspace = true edition.workspace = true
description = "LanceDB: A serverless, low-latency vector database for AI applications" description = "LanceDB: A serverless, low-latency vector database for AI applications"
license.workspace = true license.workspace = true