mirror of
https://github.com/lancedb/lancedb.git
synced 2025-12-23 13:29:57 +00:00
Compare commits
104 Commits
python-v0.
...
python-v0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8bcdc81fd3 | ||
|
|
39e14c70c5 | ||
|
|
af8263af94 | ||
|
|
be4ab9eef3 | ||
|
|
184d2bc969 | ||
|
|
ff6f005336 | ||
|
|
49333e522c | ||
|
|
4568df422d | ||
|
|
986891db98 | ||
|
|
036bf02901 | ||
|
|
4e31f0cc7a | ||
|
|
0a16e29b93 | ||
|
|
cf7d7a19f5 | ||
|
|
fe2fb91a8b | ||
|
|
81af350d85 | ||
|
|
99adfe065a | ||
|
|
277406509e | ||
|
|
63411b4d8b | ||
|
|
d998f80b04 | ||
|
|
629379a532 | ||
|
|
99ba5331f0 | ||
|
|
121687231c | ||
|
|
ac40d4b235 | ||
|
|
c5a52565ac | ||
|
|
b0a88a7286 | ||
|
|
d41d849e0e | ||
|
|
bf5202f196 | ||
|
|
8be2861061 | ||
|
|
0560e3a0e5 | ||
|
|
b83fbfc344 | ||
|
|
60b22d84bf | ||
|
|
7d55a94efd | ||
|
|
4d8e401d34 | ||
|
|
684eb8b087 | ||
|
|
4e3b82feaa | ||
|
|
8e248a9d67 | ||
|
|
065ffde443 | ||
|
|
c3059dc689 | ||
|
|
a9caa5f2d4 | ||
|
|
8411c36b96 | ||
|
|
7773bda7ee | ||
|
|
392777952f | ||
|
|
7e75e50d3a | ||
|
|
4b8af261a3 | ||
|
|
c8728d4ca1 | ||
|
|
446f837335 | ||
|
|
8f9ad978f5 | ||
|
|
0df38341d5 | ||
|
|
60260018cf | ||
|
|
bb100c5c19 | ||
|
|
eab9072bb5 | ||
|
|
ee0f0611d9 | ||
|
|
34966312cb | ||
|
|
756188358c | ||
|
|
dc5126d8d1 | ||
|
|
50c20af060 | ||
|
|
0965d7dd5a | ||
|
|
7bbb2872de | ||
|
|
e81d2975da | ||
|
|
2c7f96ba4f | ||
|
|
f9dd7a5d8a | ||
|
|
1d4943688d | ||
|
|
7856a94d2c | ||
|
|
371d2f979e | ||
|
|
fff8e399a3 | ||
|
|
73e4015797 | ||
|
|
5142a27482 | ||
|
|
81df2a524e | ||
|
|
40638e5515 | ||
|
|
018314a5c1 | ||
|
|
409eb30ea5 | ||
|
|
ff9872fd44 | ||
|
|
a0608044a1 | ||
|
|
2e4ea7d2bc | ||
|
|
57e5695a54 | ||
|
|
ce58ea7c38 | ||
|
|
57207eff4a | ||
|
|
2d78bff120 | ||
|
|
7c09b9b9a9 | ||
|
|
bd0034a157 | ||
|
|
144b3b5d83 | ||
|
|
b6f0a31686 | ||
|
|
9ec526f73f | ||
|
|
600bfd7237 | ||
|
|
d087e7891d | ||
|
|
098e397cf0 | ||
|
|
63ee8fa6a1 | ||
|
|
693091db29 | ||
|
|
dca4533dbe | ||
|
|
f6bbe199dc | ||
|
|
366e522c2b | ||
|
|
244b6919cc | ||
|
|
aca785ff98 | ||
|
|
bbdebf2c38 | ||
|
|
1336cce0dc | ||
|
|
6c83b6a513 | ||
|
|
6bec4bec51 | ||
|
|
23d30dfc78 | ||
|
|
94c8c50f96 | ||
|
|
72765d8e1a | ||
|
|
a2a8f9615e | ||
|
|
b085d9aaa1 | ||
|
|
6eb662de9b | ||
|
|
2bb2bb581a |
@@ -1,5 +1,5 @@
|
||||
[bumpversion]
|
||||
current_version = 0.3.8
|
||||
current_version = 0.4.3
|
||||
commit = True
|
||||
message = Bump version: {current_version} → {new_version}
|
||||
tag = True
|
||||
|
||||
33
.github/ISSUE_TEMPLATE/bug-node.yml
vendored
Normal file
33
.github/ISSUE_TEMPLATE/bug-node.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
name: Bug Report - Node / Typescript
|
||||
description: File a bug report
|
||||
title: "bug(node): "
|
||||
labels: [bug, typescript]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: LanceDB version
|
||||
description: What version of LanceDB are you using? `npm list | grep vectordb`.
|
||||
placeholder: v0.3.2
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: Also tell us, what did you expect to happen?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Are there known steps to reproduce?
|
||||
description: |
|
||||
Let us know how to reproduce the bug and we may be able to fix it more
|
||||
quickly. This is not required, but it is helpful.
|
||||
validations:
|
||||
required: false
|
||||
33
.github/ISSUE_TEMPLATE/bug-python.yml
vendored
Normal file
33
.github/ISSUE_TEMPLATE/bug-python.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
name: Bug Report - Python
|
||||
description: File a bug report
|
||||
title: "bug(python): "
|
||||
labels: [bug, python]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: LanceDB version
|
||||
description: What version of LanceDB are you using? `python -c "import lancedb; print(lancedb.__version__)"`.
|
||||
placeholder: v0.3.2
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: Also tell us, what did you expect to happen?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Are there known steps to reproduce?
|
||||
description: |
|
||||
Let us know how to reproduce the bug and we may be able to fix it more
|
||||
quickly. This is not required, but it is helpful.
|
||||
validations:
|
||||
required: false
|
||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Discord Community Support
|
||||
url: https://discord.com/invite/zMM32dvNtd
|
||||
about: Please ask and answer questions here.
|
||||
23
.github/ISSUE_TEMPLATE/documentation.yml
vendored
Normal file
23
.github/ISSUE_TEMPLATE/documentation.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: 'Documentation improvement'
|
||||
description: Report an issue with the documentation.
|
||||
labels: [documentation]
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: >
|
||||
Describe the issue with the documentation and how it can be fixed or improved.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: link
|
||||
attributes:
|
||||
label: Link
|
||||
description: >
|
||||
Provide a link to the existing documentation, if applicable.
|
||||
placeholder: ex. https://lancedb.github.io/lancedb/guides/tables/...
|
||||
validations:
|
||||
required: false
|
||||
31
.github/ISSUE_TEMPLATE/feature.yml
vendored
Normal file
31
.github/ISSUE_TEMPLATE/feature.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: Feature suggestion
|
||||
description: Suggestion a new feature for LanceDB
|
||||
title: "Feature: "
|
||||
labels: [enhancement]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Share a new idea for a feature or improvement. Be sure to search existing
|
||||
issues first to avoid duplicates.
|
||||
- type: dropdown
|
||||
id: sdk
|
||||
attributes:
|
||||
label: SDK
|
||||
description: Which SDK are you using? This helps us prioritize.
|
||||
options:
|
||||
- Python
|
||||
- Node
|
||||
- Rust
|
||||
default: 0
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
Describe the feature and why it would be useful. If applicable, consider
|
||||
providing a code example of what it might be like to use the feature.
|
||||
validations:
|
||||
required: true
|
||||
3
.github/workflows/docs_test.yml
vendored
3
.github/workflows/docs_test.yml
vendored
@@ -88,6 +88,9 @@ jobs:
|
||||
cd docs/test
|
||||
node md_testing.js
|
||||
- name: Test
|
||||
env:
|
||||
LANCEDB_URI: ${{ secrets.LANCEDB_URI }}
|
||||
LANCEDB_DEV_API_KEY: ${{ secrets.LANCEDB_DEV_API_KEY }}
|
||||
run: |
|
||||
cd docs/test/node
|
||||
for d in *; do cd "$d"; echo "$d".js; node "$d".js; cd ..; done
|
||||
|
||||
20
.github/workflows/npm-publish.yml
vendored
20
.github/workflows/npm-publish.yml
vendored
@@ -38,13 +38,17 @@ jobs:
|
||||
node/vectordb-*.tgz
|
||||
|
||||
node-macos:
|
||||
runs-on: macos-13
|
||||
strategy:
|
||||
matrix:
|
||||
config:
|
||||
- arch: x86_64-apple-darwin
|
||||
runner: macos-13
|
||||
- arch: aarch64-apple-darwin
|
||||
# xlarge is implicitly arm64.
|
||||
runner: macos-13-xlarge
|
||||
runs-on: ${{ matrix.config.runner }}
|
||||
# Only runs on tags that matches the make-release action
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target: [x86_64-apple-darwin, aarch64-apple-darwin]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -54,17 +58,15 @@ jobs:
|
||||
run: |
|
||||
cd node
|
||||
npm ci
|
||||
- name: Install rustup target
|
||||
if: ${{ matrix.target == 'aarch64-apple-darwin' }}
|
||||
run: rustup target add aarch64-apple-darwin
|
||||
- name: Build MacOS native node modules
|
||||
run: bash ci/build_macos_artifacts.sh ${{ matrix.target }}
|
||||
run: bash ci/build_macos_artifacts.sh ${{ matrix.config.arch }}
|
||||
- name: Upload Darwin Artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: native-darwin
|
||||
path: |
|
||||
node/dist/lancedb-vectordb-darwin*.tgz
|
||||
|
||||
|
||||
node-linux:
|
||||
name: node-linux (${{ matrix.config.arch}}-unknown-linux-gnu
|
||||
|
||||
21
.github/workflows/python.yml
vendored
21
.github/workflows/python.yml
vendored
@@ -44,12 +44,19 @@ jobs:
|
||||
run: pytest -m "not slow" -x -v --durations=30 tests
|
||||
- name: doctest
|
||||
run: pytest --doctest-modules lancedb
|
||||
mac:
|
||||
platform:
|
||||
name: "Platform: ${{ matrix.config.name }}"
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
matrix:
|
||||
mac-runner: [ "macos-13", "macos-13-xlarge" ]
|
||||
runs-on: "${{ matrix.mac-runner }}"
|
||||
config:
|
||||
- name: x86 Mac
|
||||
runner: macos-13
|
||||
- name: Arm Mac
|
||||
runner: macos-13-xlarge
|
||||
- name: x86 Windows
|
||||
runner: windows-latest
|
||||
runs-on: "${{ matrix.config.runner }}"
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
@@ -67,7 +74,7 @@ jobs:
|
||||
run: |
|
||||
pip install -e .[tests]
|
||||
pip install tantivy@git+https://github.com/quickwit-oss/tantivy-py#164adc87e1a033117001cf70e38c82a53014d985
|
||||
pip install pytest pytest-mock black
|
||||
pip install pytest pytest-mock
|
||||
- name: Run tests
|
||||
run: pytest -m "not slow" -x -v --durations=30 tests
|
||||
pydantic1x:
|
||||
@@ -91,11 +98,7 @@ jobs:
|
||||
pip install "pydantic<2"
|
||||
pip install -e .[tests]
|
||||
pip install tantivy@git+https://github.com/quickwit-oss/tantivy-py#164adc87e1a033117001cf70e38c82a53014d985
|
||||
pip install pytest pytest-mock black isort
|
||||
- name: Black
|
||||
run: black --check --diff --no-color --quiet .
|
||||
- name: isort
|
||||
run: isort --check --diff --quiet .
|
||||
pip install pytest pytest-mock
|
||||
- name: Run tests
|
||||
run: pytest -m "not slow" -x -v --durations=30 tests
|
||||
- name: doctest
|
||||
|
||||
23
.github/workflows/rust.yml
vendored
23
.github/workflows/rust.yml
vendored
@@ -24,6 +24,29 @@ env:
|
||||
RUST_BACKTRACE: "1"
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
timeout-minutes: 30
|
||||
runs-on: ubuntu-22.04
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
working-directory: rust
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
lfs: true
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
workspaces: rust
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y protobuf-compiler libssl-dev
|
||||
- name: Run format
|
||||
run: cargo fmt --all -- --check
|
||||
- name: Run clippy
|
||||
run: cargo clippy --all --all-features -- -D warnings
|
||||
linux:
|
||||
timeout-minutes: 30
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
26
Cargo.toml
26
Cargo.toml
@@ -5,24 +5,24 @@ exclude = ["python"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.dependencies]
|
||||
lance = { "version" = "=0.8.17", "features" = ["dynamodb"] }
|
||||
lance-index = { "version" = "=0.8.17" }
|
||||
lance-linalg = { "version" = "=0.8.17" }
|
||||
lance-testing = { "version" = "=0.8.17" }
|
||||
lance = { "version" = "=0.9.6", "features" = ["dynamodb"] }
|
||||
lance-index = { "version" = "=0.9.6" }
|
||||
lance-linalg = { "version" = "=0.9.6" }
|
||||
lance-testing = { "version" = "=0.9.6" }
|
||||
# Note that this one does not include pyarrow
|
||||
arrow = { version = "47.0.0", optional = false }
|
||||
arrow-array = "47.0"
|
||||
arrow-data = "47.0"
|
||||
arrow-ipc = "47.0"
|
||||
arrow-ord = "47.0"
|
||||
arrow-schema = "47.0"
|
||||
arrow-arith = "47.0"
|
||||
arrow-cast = "47.0"
|
||||
arrow = { version = "49.0.0", optional = false }
|
||||
arrow-array = "49.0"
|
||||
arrow-data = "49.0"
|
||||
arrow-ipc = "49.0"
|
||||
arrow-ord = "49.0"
|
||||
arrow-schema = "49.0"
|
||||
arrow-arith = "49.0"
|
||||
arrow-cast = "49.0"
|
||||
chrono = "0.4.23"
|
||||
half = { "version" = "=2.3.1", default-features = false, features = [
|
||||
"num-traits",
|
||||
] }
|
||||
log = "0.4"
|
||||
object_store = "0.7.1"
|
||||
object_store = "0.8.0"
|
||||
snafu = "0.7.4"
|
||||
url = "2"
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
|
||||
**Developer-friendly, serverless vector database for AI applications**
|
||||
|
||||
<a href="https://lancedb.github.io/lancedb/">Documentation</a> •
|
||||
<a href="https://blog.lancedb.com/">Blog</a> •
|
||||
<a href="https://discord.gg/zMM32dvNtd">Discord</a> •
|
||||
<a href="https://twitter.com/lancedb">Twitter</a>
|
||||
<a href='https://github.com/lancedb/vectordb-recipes/tree/main' target="_blank"><img alt='LanceDB' src='https://img.shields.io/badge/VectorDB_Recipes-100000?style=for-the-badge&logo=LanceDB&logoColor=white&labelColor=645cfb&color=645cfb'/></a>
|
||||
<a href='https://lancedb.github.io/lancedb/' target="_blank"><img alt='lancdb' src='https://img.shields.io/badge/DOCS-100000?style=for-the-badge&logo=lancdb&logoColor=white&labelColor=645cfb&color=645cfb'/></a>
|
||||
[](https://blog.lancedb.com/)
|
||||
[](https://discord.gg/zMM32dvNtd)
|
||||
[](https://twitter.com/lancedb)
|
||||
|
||||
</p>
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Builds the macOS artifacts (node binaries).
|
||||
# Usage: ./ci/build_macos_artifacts.sh [target]
|
||||
# Targets supported: x86_64-apple-darwin aarch64-apple-darwin
|
||||
set -e
|
||||
|
||||
prebuild_rust() {
|
||||
# Building here for the sake of easier debugging.
|
||||
|
||||
@@ -98,6 +98,7 @@ nav:
|
||||
- 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
|
||||
- Example - Calculate CLIP Embeddings with Roboflow Inference: examples/image_embeddings_roboflow.md
|
||||
- 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:
|
||||
@@ -145,8 +146,10 @@ nav:
|
||||
- Serverless Chatbot from any website: examples/serverless_website_chatbot.md
|
||||
- TransformersJS Embedding Search: examples/transformerjs_embedding_search_nodejs.md
|
||||
- API references:
|
||||
- Python API: python/python.md
|
||||
- OSS Python API: python/python.md
|
||||
- SaaS Python API: python/saas-python.md
|
||||
- Javascript API: javascript/modules.md
|
||||
- SaaS Javascript API: javascript/saas-modules.md
|
||||
- LanceDB Cloud↗: https://noteforms.com/forms/lancedb-mailing-list-cloud-kty1o5?notionforms=1&utm_source=notionforms
|
||||
|
||||
extra_css:
|
||||
|
||||
@@ -2,3 +2,4 @@ mkdocs==1.4.2
|
||||
mkdocs-jupyter==0.24.1
|
||||
mkdocs-material==9.1.3
|
||||
mkdocstrings[python]==0.20.0
|
||||
pydantic
|
||||
@@ -164,6 +164,7 @@ You can further filter the elements returned by a search using a where clause.
|
||||
const results_2 = await table
|
||||
.search(Array(1536).fill(1.2))
|
||||
.where("id != '1141'")
|
||||
.limit(2)
|
||||
.execute()
|
||||
```
|
||||
|
||||
@@ -187,6 +188,7 @@ You can select the columns returned by the query using a select clause.
|
||||
const results_3 = await table
|
||||
.search(Array(1536).fill(1.2))
|
||||
.select(["id"])
|
||||
.limit(2)
|
||||
.execute()
|
||||
```
|
||||
|
||||
|
||||
@@ -64,18 +64,26 @@ We'll cover the basics of using LanceDB on your local machine in this section.
|
||||
tbl = db.create_table("table_from_df", data=df)
|
||||
```
|
||||
|
||||
!!! warning
|
||||
|
||||
If the table already exists, LanceDB will raise an error by default.
|
||||
If you want to make sure you overwrite the table, pass in `mode="overwrite"`
|
||||
to the `createTable` function.
|
||||
|
||||
=== "Javascript"
|
||||
```javascript
|
||||
const tb = await db.createTable("my_table",
|
||||
data=[{"vector": [3.1, 4.1], "item": "foo", "price": 10.0},
|
||||
{"vector": [5.9, 26.5], "item": "bar", "price": 20.0}])
|
||||
const tb = await db.createTable(
|
||||
"myTable",
|
||||
[{"vector": [3.1, 4.1], "item": "foo", "price": 10.0},
|
||||
{"vector": [5.9, 26.5], "item": "bar", "price": 20.0}])
|
||||
```
|
||||
|
||||
!!! warning
|
||||
|
||||
If the table already exists, LanceDB will raise an error by default.
|
||||
If you want to overwrite the table, you can pass in `mode="overwrite"`
|
||||
to the `createTable` function.
|
||||
!!! warning
|
||||
|
||||
If the table already exists, LanceDB will raise an error by default.
|
||||
If you want to overwrite the table, you can pass in `"overwrite"`
|
||||
to the `createTable` function like this: `await con.createTable(tableName, data, { writeMode: WriteMode.Overwrite })`
|
||||
|
||||
|
||||
??? info "Under the hood, LanceDB is converting the input data into an Apache Arrow table and persisting it to disk in [Lance format](https://www.github.com/lancedb/lance)."
|
||||
|
||||
@@ -108,7 +116,7 @@ Once created, you can open a table using the following code:
|
||||
|
||||
=== "Javascript"
|
||||
```javascript
|
||||
const tbl = await db.openTable("my_table");
|
||||
const tbl = await db.openTable("myTable");
|
||||
```
|
||||
|
||||
If you forget the name of your table, you can always get a listing of all table names:
|
||||
@@ -194,10 +202,17 @@ Use the `drop_table()` method on the database to remove a table.
|
||||
db.drop_table("my_table")
|
||||
```
|
||||
|
||||
This permanently removes the table and is not recoverable, unlike deleting rows.
|
||||
By default, if the table does not exist an exception is raised. To suppress this,
|
||||
you can pass in `ignore_missing=True`.
|
||||
This permanently removes the table and is not recoverable, unlike deleting rows.
|
||||
By default, if the table does not exist an exception is raised. To suppress this,
|
||||
you can pass in `ignore_missing=True`.
|
||||
|
||||
=== "JavaScript"
|
||||
```javascript
|
||||
await db.dropTable('myTable')
|
||||
```
|
||||
|
||||
This permanently removes the table and is not recoverable, unlike deleting rows.
|
||||
If the table does not exist an exception is raised.
|
||||
|
||||
## What's next
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
There are various Embedding functions available out of the box with lancedb. We're working on supporting other popular embedding APIs.
|
||||
There are various Embedding functions available out of the box with LanceDB. We're working on supporting other popular embedding APIs.
|
||||
|
||||
## Text Embedding Functions
|
||||
Here are the text embedding functions registered by default.
|
||||
Embedding functions have inbuilt rate limit handler wrapper for source and query embedding function calls that retry with exponential standoff.
|
||||
Each `EmbeddingFunction` implementation automatically takes `max_retries` as an argument which has the deafult value of 7.
|
||||
Embedding functions have an inbuilt rate limit handler wrapper for source and query embedding function calls that retry with exponential standoff.
|
||||
Each `EmbeddingFunction` implementation automatically takes `max_retries` as an argument which has the default value of 7.
|
||||
|
||||
### Sentence Transformers
|
||||
Here are the parameters that you can set when registering a `sentence-transformers` object, and their default values:
|
||||
@@ -69,15 +69,15 @@ print(actual.text)
|
||||
```
|
||||
|
||||
### Instructor Embeddings
|
||||
Instructor is an instruction-finetuned text embedding model that can generate text embeddings tailored to any task (e.g., classification, retrieval, clustering, text evaluation, etc.) and domains (e.g., science, finance, etc.) by simply providing the task instruction, without any finetuning
|
||||
Instructor is an instruction-finetuned text embedding model that can generate text embeddings tailored to any task (e.g. classification, retrieval, clustering, text evaluation, etc.) and domains (e.g. science, finance, etc.) by simply providing the task instruction, without any finetuning.
|
||||
|
||||
If you want to calculate customized embeddings for specific sentences, you may follow the unified template to write instructions:
|
||||
|
||||
Represent the `domain` `text_type` for `task_objective`:
|
||||
|
||||
* `domain` is optional, and it specifies the domain of the text, e.g., science, finance, medicine, etc.
|
||||
* `text_type` is required, and it specifies the encoding unit, e.g., sentence, document, paragraph, etc.
|
||||
* `task_objective` is optional, and it specifies the objective of embedding, e.g., retrieve a document, classify the sentence, etc.
|
||||
* `domain` is optional, and it specifies the domain of the text, e.g. science, finance, medicine, etc.
|
||||
* `text_type` is required, and it specifies the encoding unit, e.g. sentence, document, paragraph, etc.
|
||||
* `task_objective` is optional, and it specifies the objective of embedding, e.g. retrieve a document, classify the sentence, etc.
|
||||
|
||||
More information about the model can be found here - https://github.com/xlang-ai/instructor-embedding
|
||||
|
||||
@@ -118,11 +118,47 @@ texts = [{"text": "Capitalism has been dominant in the Western world since the e
|
||||
tbl.add(texts)
|
||||
```
|
||||
|
||||
## Gemini Embedding Function
|
||||
With Google's Gemini, you can represent text (words, sentences, and blocks of text) in a vectorized form, making it easier to compare and contrast embeddings. For example, two texts that share a similar subject matter or sentiment should have similar embeddings, which can be identified through mathematical comparison techniques such as cosine similarity. For more on how and why you should use embeddings, refer to the Embeddings guide.
|
||||
The Gemini Embedding Model API supports various task types:
|
||||
|
||||
| Task Type | Description |
|
||||
|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| "`retrieval_query`" | Specifies the given text is a query in a search/retrieval setting. |
|
||||
| "`retrieval_document`" | Specifies the given text is a document in a search/retrieval setting. Using this task type requires a title but is automatically proided by Embeddings API |
|
||||
| "`semantic_similarity`" | Specifies the given text will be used for Semantic Textual Similarity (STS). |
|
||||
| "`classification`" | Specifies that the embeddings will be used for classification. |
|
||||
| "`clusering`" | Specifies that the embeddings will be used for clustering. |
|
||||
|
||||
|
||||
Usage Example:
|
||||
|
||||
```python
|
||||
import lancedb
|
||||
import pandas as pd
|
||||
from lancedb.pydantic import LanceModel, Vector
|
||||
from lancedb.embeddings import get_registry
|
||||
|
||||
|
||||
model = get_registry().get("gemini-text").create()
|
||||
|
||||
class TextModel(LanceModel):
|
||||
text: str = model.SourceField()
|
||||
vector: Vector(model.ndims()) = model.VectorField()
|
||||
|
||||
df = pd.DataFrame({"text": ["hello world", "goodbye world"]})
|
||||
db = lancedb.connect("~/.lancedb")
|
||||
tbl = db.create_table("test", schema=TextModel, mode="overwrite")
|
||||
|
||||
tbl.add(df)
|
||||
rs = tbl.search("hello").limit(1).to_pandas()
|
||||
```
|
||||
|
||||
## Multi-modal embedding functions
|
||||
Multi-modal embedding functions allow you query your table using both images and text.
|
||||
Multi-modal embedding functions allow you to query your table using both images and text.
|
||||
|
||||
### OpenClipEmbeddings
|
||||
We support CLIP model embeddings using the open souce alternbative, open-clip which support various customizations. It is registered as `open-clip` and supports following customizations.
|
||||
We support CLIP model embeddings using the open source alternative, open-clip which supports various customizations. It is registered as `open-clip` and supports the following customizations:
|
||||
|
||||
|
||||
| Parameter | Type | Default Value | Description |
|
||||
@@ -205,4 +241,4 @@ print(actual.label)
|
||||
|
||||
```
|
||||
|
||||
If you have any questions about the embeddings API, supported models, or see a relevant model missing, please raise an issue.
|
||||
If you have any questions about the embeddings API, supported models, or see a relevant model missing, please raise an issue.
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
Representing multi-modal data as vector embeddings is becoming a standard practice. Embedding functions themselves be thought of as a part of the processing pipeline that each request(input) has to be passed through. After initial setup these components are not expected to change for a particular project.
|
||||
|
||||
This is main motivation behind our new embedding functions API, that allow you simply set it up once and the table remembers it, effectively making the **embedding functions disappear in the background** so you don't have to worry about modelling and simply focus on the DB aspects of VectorDB.
|
||||
Representing multi-modal data as vector embeddings is becoming a standard practice. Embedding functions themselves can be thought of as a part of the processing pipeline that each request(input) has to be passed through. After initial setup these components are not expected to change for a particular project.
|
||||
|
||||
Our new embedding functions API allow you simply set it up once and the table remembers it, effectively making the **embedding functions disappear in the background** so you don't have to worry about modelling and can simply focus on the DB aspects of VectorDB.
|
||||
|
||||
You can simply follow these steps and forget about the details of your embedding functions as long as you don't intend to change it.
|
||||
|
||||
### Step 1 - Define the embedding function
|
||||
We have some pre-defined embedding functions in the global registry with more coming soon. Here's let's an implementation of CLIP as example.
|
||||
```
|
||||
from lancedb.embeddings import EmbeddingFunctionRegistry
|
||||
|
||||
registry = EmbeddingFunctionRegistry.get_instance()
|
||||
clip = registry.get("open-clip").create()
|
||||
|
||||
@@ -15,9 +16,11 @@ clip = registry.get("open-clip").create()
|
||||
You can also define your own embedding function by implementing the `EmbeddingFunction` abstract base interface. It subclasses PyDantic Model which can be utilized to write complex schemas simply as we'll see next!
|
||||
|
||||
### Step 2 - Define the Data Model or Schema
|
||||
Our embedding function from the previous section abstracts away all the details about the models and dimensions required to define the schema. You can simply set a feild as **source** or **vector** column. Here's how
|
||||
Our embedding function from the previous section abstracts away all the details about the models and dimensions required to define the schema. You can simply set a field as **source** or **vector** column. Here's how
|
||||
|
||||
```python
|
||||
from lancedb.pydantic import LanceModel, Vector
|
||||
|
||||
class Pets(LanceModel):
|
||||
vector: Vector(clip.ndims) = clip.VectorField()
|
||||
image_uri: str = clip.SourceField()
|
||||
@@ -30,11 +33,13 @@ class Pets(LanceModel):
|
||||
Now that we have chosen/defined our embedding function and the schema, we can create the table
|
||||
|
||||
```python
|
||||
import lancedb
|
||||
|
||||
db = lancedb.connect("~/lancedb")
|
||||
table = db.create_table("pets", schema=Pets)
|
||||
|
||||
```
|
||||
That's it! We have ingested all the information needed to embed source and query inputs. We can now forget about the model and dimension details and start to build or VectorDB
|
||||
|
||||
That's it! We have ingested all the information needed to embed source and query inputs. We can now forget about the model and dimension details and start to build our VectorDB.
|
||||
|
||||
### Step 4 - Ingest lots of data and run vector search!
|
||||
Now you can just add the data and it'll be vectorized automatically
|
||||
@@ -52,29 +57,32 @@ result = table.search("dog")
|
||||
Let's query an image
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
|
||||
p = Path("path/to/images/samoyed_100.jpg")
|
||||
query_image = Image.open(p)
|
||||
table.search(query_image)
|
||||
|
||||
```
|
||||
|
||||
### Rate limit Handling
|
||||
`EmbeddingFunction` class wraps the calls for source and query embedding generation inside a rate limit handler that retries the requests with exponential backoff after successive failures. By default the maximum retires is set to 7. You can tune it by setting it to a different number or disable it by setting it to 0.
|
||||
Example
|
||||
----
|
||||
`EmbeddingFunction` class wraps the calls for source and query embedding generation inside a rate limit handler that retries the requests with exponential backoff after successive failures. By default the maximum retires is set to 7. You can tune it by setting it to a different number or disable it by setting it to 0. Example:
|
||||
|
||||
```python
|
||||
clip = registry.get("open-clip").create() # Defaults to 7 max retries
|
||||
clip = registry.get("open-clip").create(max_retries=10) # Increase max retries to 10
|
||||
clip = registry.get("open-clip").create(max_retries=0) # Retries disabled
|
||||
````
|
||||
```
|
||||
|
||||
NOTE:
|
||||
Embedding functions can also fail due to other errors that have nothing to do with rate limits. This is why the error is also logged.
|
||||
Embedding functions can also fail due to other errors that have nothing to do with rate limits. This is why the errors are also logged.
|
||||
|
||||
### A little fun with PyDantic
|
||||
LanceDB is integrated with PyDantic. Infact we've used the integration in the above example to define the schema. It is also being used behing the scene by the embdding function API to ingest useful information as table metadata.
|
||||
You can also use it for adding utility operations in the schema. For example, in our multi-modal example, you can search images using text or another image. Let us define a utility function to plot the image.
|
||||
LanceDB is integrated with PyDantic. In fact, we've used the integration in the above example to define the schema. It is also being used behind the scene by the embedding function API to ingest useful information as table metadata.
|
||||
You can also use it for adding utility operations in the schema. For example, in our multi-modal example, you can search images using text or another image. Let's define a utility function to plot the image.
|
||||
|
||||
```python
|
||||
from lancedb.pydantic import LanceModel, Vector
|
||||
|
||||
class Pets(LanceModel):
|
||||
vector: Vector(clip.ndims) = clip.VectorField()
|
||||
image_uri: str = clip.SourceField()
|
||||
@@ -83,7 +91,8 @@ class Pets(LanceModel):
|
||||
def image(self):
|
||||
return Image.open(self.image_uri)
|
||||
```
|
||||
Now, you can covert your search results to pydantic model and use this property.
|
||||
|
||||
Now, you can covert your search results to PyDantic model and use its property.
|
||||
|
||||
```python
|
||||
rs = table.search(query_image).limit(3).to_pydantic(Pets)
|
||||
@@ -92,4 +101,4 @@ rs[2].image
|
||||
|
||||

|
||||
|
||||
Now that you've the basic idea about LanceDB embedding function, let us now dive deeper into the API that you can use to implement your own embedding functions!
|
||||
Now that you have the basic idea about LanceDB embedding function, let us dive deeper into the API that you can use to implement your own embedding functions!
|
||||
|
||||
165
docs/src/examples/image_embeddings_roboflow.md
Normal file
165
docs/src/examples/image_embeddings_roboflow.md
Normal file
@@ -0,0 +1,165 @@
|
||||
# How to Load Image Embeddings into LanceDB
|
||||
|
||||
With the rise of Large Multimodal Models (LMMs) such as [GPT-4 Vision](https://blog.roboflow.com/gpt-4-vision/), the need for storing image embeddings is growing. The most effective way to store text and image embeddings is in a vector database such as LanceDB. Vector databases are a special kind of data store that enables efficient search over stored embeddings.
|
||||
|
||||
[CLIP](https://blog.roboflow.com/openai-clip/), a multimodal model developed by OpenAI, is commonly used to calculate image embeddings. These embeddings can then be used with a vector database to build a semantic search engine that you can query using images or text. For example, you could use LanceDB and CLIP embeddings to build a search engine for a database of folders.
|
||||
|
||||
In this guide, we are going to show you how to use Roboflow Inference to load image embeddings into LanceDB. Without further ado, let’s get started!
|
||||
|
||||
## Step #1: Install Roboflow Inference
|
||||
|
||||
[Roboflow Inference](https://inference.roboflow.com) enables you to run state-of-the-art computer vision models with minimal configuration. Inference supports a range of models, from fine-tuned object detection, classification, and segmentation models to foundation models like CLIP. We will use Inference to calculate CLIP image embeddings.
|
||||
|
||||
Inference provides a HTTP API through which you can run vision models.
|
||||
|
||||
Inference powers the Roboflow hosted API, and is available as an open source utility. In this guide, we are going to run Inference locally, which enables you to calculate CLIP embeddings on your own hardware. We will also show you how to use the hosted Roboflow CLIP API, which is ideal if you need to scale and do not want to manage a system for calculating embeddings.
|
||||
|
||||
To get started, first install the Inference CLI:
|
||||
|
||||
```
|
||||
pip install inference-cli
|
||||
```
|
||||
|
||||
Next, install Docker. Refer to the official Docker installation instructions for your operating system to get Docker set up. Once Docker is ready, you can start Inference using the following command:
|
||||
|
||||
```
|
||||
inference server start
|
||||
```
|
||||
|
||||
An Inference server will start running at ‘http://localhost:9001’.
|
||||
|
||||
## Step #2: Set Up a LanceDB Vector Database
|
||||
|
||||
Now that we have Inference running, we can set up a LanceDB vector database. You can run LanceDB in JavaScript and Python. For this guide, we will use the Python API. But, you can take the HTTP requests we make below and change them to JavaScript if required.
|
||||
|
||||
For this guide, we are going to search the [COCO 128 dataset](https://universe.roboflow.com/team-roboflow/coco-128), which contains a wide range of objects. The variability in objects present in this dataset makes it a good dataset to demonstrate the capabilities of vector search. If you want to use this dataset, you can download [COCO 128 from Roboflow Universe](https://universe.roboflow.com/team-roboflow/coco-128). With that said, you can search whatever folder of images you want.
|
||||
|
||||
Once you have a dataset ready, install LanceDB with the following command:
|
||||
|
||||
```
|
||||
pip install lancedb
|
||||
```
|
||||
|
||||
We also need to install a specific commit of `tantivy`, a dependency of the LanceDB full text search engine we will use later in this guide:
|
||||
|
||||
```
|
||||
pip install tantivy@git+https://github.com/quickwit-oss/tantivy-py#164adc87e1a033117001cf70e38c82a53014d985
|
||||
```
|
||||
|
||||
Create a new Python file and add the following code:
|
||||
|
||||
```python
|
||||
import cv2
|
||||
import supervision as sv
|
||||
import requests
|
||||
|
||||
import lancedb
|
||||
|
||||
db = lancedb.connect("./embeddings")
|
||||
|
||||
IMAGE_DIR = "images/"
|
||||
API_KEY = os.environ.get("ROBOFLOW_API_KEY")
|
||||
SERVER_URL = "http://localhost:9001"
|
||||
|
||||
results = []
|
||||
|
||||
for i, image in enumerate(os.listdir(IMAGE_DIR)):
|
||||
infer_clip_payload = {
|
||||
#Images can be provided as urls or as base64 encoded strings
|
||||
"image": {
|
||||
"type": "base64",
|
||||
"value": base64.b64encode(open(IMAGE_DIR + image, "rb").read()).decode("utf-8"),
|
||||
},
|
||||
}
|
||||
|
||||
res = requests.post(
|
||||
f"{SERVER_URL}/clip/embed_image?api_key={API_KEY}",
|
||||
json=infer_clip_payload,
|
||||
)
|
||||
|
||||
embeddings = res.json()['embeddings']
|
||||
|
||||
print("Calculated embedding for image: ", image)
|
||||
|
||||
image = {"vector": embeddings[0], "name": os.path.join(IMAGE_DIR, image)}
|
||||
|
||||
results.append(image)
|
||||
|
||||
tbl = db.create_table("images", data=results)
|
||||
|
||||
tbl.create_fts_index("name")
|
||||
```
|
||||
|
||||
To use the code above, you will need a Roboflow API key. [Learn how to retrieve a Roboflow API key](https://docs.roboflow.com/api-reference/authentication#retrieve-an-api-key). Run the following command to set up your API key in your environment:
|
||||
|
||||
```
|
||||
export ROBOFLOW_API_KEY=""
|
||||
```
|
||||
|
||||
Replace the `IMAGE_DIR` value with the folder in which you are storing the images for which you want to calculate embeddings. If you want to use the Roboflow CLIP API to calculate embeddings, replace the `SERVER_URL` value with `https://infer.roboflow.com`.
|
||||
|
||||
Run the script above to create a new LanceDB database. This database will be stored on your local machine. The database will be called `embeddings` and the table will be called `images`.
|
||||
|
||||
The script above calculates all embeddings for a folder then creates a new table. To add additional images, use the following code:
|
||||
|
||||
```python
|
||||
def make_batches():
|
||||
for i in range(5):
|
||||
yield [
|
||||
{"vector": [3.1, 4.1], "name": "image1.png"},
|
||||
{"vector": [5.9, 26.5], "name": "image2.png"}
|
||||
]
|
||||
|
||||
tbl = db.open_table("images")
|
||||
tbl.add(make_batches())
|
||||
```
|
||||
|
||||
Replacing the `make_batches()` function with code to load embeddings for images.
|
||||
|
||||
## Step #3: Run a Search Query
|
||||
|
||||
We are now ready to run a search query. To run a search query, we need a text embedding that represents a text query. We can use this embedding to search our LanceDB database for an entry.
|
||||
|
||||
Let’s calculate a text embedding for the query “cat”, then run a search query:
|
||||
|
||||
```python
|
||||
infer_clip_payload = {
|
||||
"text": "cat",
|
||||
}
|
||||
|
||||
res = requests.post(
|
||||
f"{SERVER_URL}/clip/embed_text?api_key={API_KEY}",
|
||||
json=infer_clip_payload,
|
||||
)
|
||||
|
||||
embeddings = res.json()['embeddings']
|
||||
|
||||
df = tbl.search(embeddings[0]).limit(3).to_list()
|
||||
|
||||
print("Results:")
|
||||
|
||||
for i in df:
|
||||
print(i["name"])
|
||||
```
|
||||
|
||||
This code will search for the three images most closely related to the prompt “cat”. The names of the most similar three images will be printed to the console. Here are the three top results:
|
||||
|
||||
```
|
||||
dataset/images/train/000000000650_jpg.rf.1b74ba165c5a3513a3211d4a80b69e1c.jpg
|
||||
dataset/images/train/000000000138_jpg.rf.af439ef1c55dd8a4e4b142d186b9c957.jpg
|
||||
dataset/images/train/000000000165_jpg.rf.eae14d5509bf0c9ceccddbb53a5f0c66.jpg
|
||||
```
|
||||
|
||||
Let’s open the top image:
|
||||
|
||||

|
||||
|
||||
The top image was a cat. Our search was successful.
|
||||
|
||||
## Conclusion
|
||||
|
||||
LanceDB is a vector database that you can use to store and efficiently search your image embeddings. You can use Roboflow Inference, a scalable computer vision inference server, to calculate CLIP embeddings that you can store in LanceDB.
|
||||
|
||||
You can use Inference and LanceDB together to build a range of applications with image embeddings, from a media search engine to a retrieval-augmented generation pipeline for use with LMMs.
|
||||
|
||||
To learn more about Inference and its capabilities, refer to the Inference documentation.
|
||||
@@ -29,8 +29,9 @@ uri = "data/sample-lancedb"
|
||||
db = lancedb.connect(uri)
|
||||
|
||||
table = db.create_table("my_table",
|
||||
data=[{"vector": [3.1, 4.1], "text": "Frodo was a happy puppy"},
|
||||
{"vector": [5.9, 26.5], "text": "There are several kittens playing"}])
|
||||
data=[{"vector": [3.1, 4.1], "text": "Frodo was a happy puppy", "meta": "foo"},
|
||||
{"vector": [5.9, 26.5], "text": "Sam was a loyal puppy", "meta": "bar"},
|
||||
{"vector": [15.9, 6.5], "text": "There are several kittens playing"}])
|
||||
|
||||
```
|
||||
|
||||
@@ -64,10 +65,51 @@ table.create_fts_index(["text1", "text2"])
|
||||
|
||||
Note that the search API call does not change - you can search over all indexed columns at once.
|
||||
|
||||
## Filtering
|
||||
|
||||
Currently the LanceDB full text search feature supports *post-filtering*, meaning filters are
|
||||
applied on top of the full text search results. This can be invoked via the familiar
|
||||
`where` syntax:
|
||||
|
||||
```python
|
||||
table.search("puppy").limit(10).where("meta='foo'").to_list()
|
||||
```
|
||||
|
||||
## Syntax
|
||||
|
||||
For full-text search you can perform either a phrase query like "the old man and the sea",
|
||||
or a structured search query like "(Old AND Man) AND Sea".
|
||||
Double quotes are used to disambiguate.
|
||||
|
||||
For example:
|
||||
|
||||
If you intended "they could have been dogs OR cats" as a phrase query, this actually
|
||||
raises a syntax error since `OR` is a recognized operator. If you make `or` lower case,
|
||||
this avoids the syntax error. However, it is cumbersome to have to remember what will
|
||||
conflict with the query syntax. Instead, if you search using
|
||||
`table.search('"they could have been dogs OR cats"')`, then the syntax checker avoids
|
||||
checking inside the quotes.
|
||||
|
||||
|
||||
## Configurations
|
||||
|
||||
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.
|
||||
|
||||
```python
|
||||
# configure a 512MB heap size
|
||||
heap = 1024 * 1024 * 512
|
||||
table.create_fts_index(["text1", "text2"], writer_heap_size=heap, replace=True)
|
||||
```
|
||||
|
||||
## Current limitations
|
||||
|
||||
1. Currently we do not yet support incremental writes.
|
||||
If you add data after fts index creation, it won't be reflected
|
||||
in search results until you do a full reindex.
|
||||
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.
|
||||
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.
|
||||
|
||||
2. We currently only support local filesystem paths for the fts index.
|
||||
@@ -1,5 +1,7 @@
|
||||
<a href="https://colab.research.google.com/github/lancedb/lancedb/blob/main/docs/src/notebooks/tables_guide.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"></a><br/>
|
||||
A Table is a collection of Records in a LanceDB Database. You can follow along on colab!
|
||||
A Table is a collection of Records in a LanceDB Database. Tables in Lance have a schema that defines the columns and their types. These schemas can include nested columns and can evolve over time.
|
||||
|
||||
This guide will show how to create tables, insert data into them, and update the data. You can follow along on colab!
|
||||
|
||||
## Creating a LanceDB Table
|
||||
|
||||
@@ -29,13 +31,23 @@ A Table is a collection of Records in a LanceDB Database. You can follow along o
|
||||
```
|
||||
|
||||
!!! info "Note"
|
||||
If the table already exists, LanceDB will raise an error by default. If you want to overwrite the table, you can pass in mode="overwrite" to the createTable function.
|
||||
If the table already exists, LanceDB will raise an error by default.
|
||||
|
||||
`create_table` supports an optional `exist_ok` parameter. When set to True
|
||||
and the table exists, then it simply opens the existing table. The data you
|
||||
passed in will NOT be appended to the table in that case.
|
||||
|
||||
```python
|
||||
db.create_table("name", data, exist_ok=True)
|
||||
```
|
||||
|
||||
Sometimes you want to make sure that you start fresh. If you want to
|
||||
overwrite the table, you can pass in mode="overwrite" to the createTable function.
|
||||
|
||||
```python
|
||||
db.create_table("name", data, mode="overwrite")
|
||||
```
|
||||
|
||||
|
||||
### From pandas DataFrame
|
||||
|
||||
```python
|
||||
@@ -116,6 +128,84 @@ A Table is a collection of Records in a LanceDB Database. You can follow along o
|
||||
table = db.create_table(table_name, schema=Content)
|
||||
```
|
||||
|
||||
#### Nested schemas
|
||||
|
||||
Sometimes your data model may contain nested objects.
|
||||
For example, you may want to store the document string
|
||||
and the document soure name as a nested Document object:
|
||||
|
||||
```python
|
||||
class Document(BaseModel):
|
||||
content: str
|
||||
source: str
|
||||
```
|
||||
|
||||
This can be used as the type of a LanceDB table column:
|
||||
|
||||
```python
|
||||
class NestedSchema(LanceModel):
|
||||
id: str
|
||||
vector: Vector(1536)
|
||||
document: Document
|
||||
|
||||
tbl = db.create_table("nested_table", schema=NestedSchema, mode="overwrite")
|
||||
```
|
||||
|
||||
This creates a struct column called "document" that has two subfields
|
||||
called "content" and "source":
|
||||
|
||||
```
|
||||
In [28]: tbl.schema
|
||||
Out[28]:
|
||||
id: string not null
|
||||
vector: fixed_size_list<item: float>[1536] not null
|
||||
child 0, item: float
|
||||
document: struct<content: string not null, source: string not null> not null
|
||||
child 0, content: string not null
|
||||
child 1, source: string not null
|
||||
```
|
||||
|
||||
#### Validators
|
||||
|
||||
Note that neither pydantic nor pyarrow automatically validates that input data
|
||||
is of the *correct* timezone, but this is easy to add as a custom field validator:
|
||||
|
||||
```python
|
||||
from datetime import datetime
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from lancedb.pydantic import LanceModel
|
||||
from pydantic import Field, field_validator, ValidationError, ValidationInfo
|
||||
|
||||
tzname = "America/New_York"
|
||||
tz = ZoneInfo(tzname)
|
||||
|
||||
class TestModel(LanceModel):
|
||||
dt_with_tz: datetime = Field(json_schema_extra={"tz": tzname})
|
||||
|
||||
@field_validator('dt_with_tz')
|
||||
@classmethod
|
||||
def tz_must_match(cls, dt: datetime) -> datetime:
|
||||
assert dt.tzinfo == tz
|
||||
return dt
|
||||
|
||||
ok = TestModel(dt_with_tz=datetime.now(tz))
|
||||
|
||||
try:
|
||||
TestModel(dt_with_tz=datetime.now(ZoneInfo("Asia/Shanghai")))
|
||||
assert 0 == 1, "this should raise ValidationError"
|
||||
except ValidationError:
|
||||
print("A ValidationError was raised.")
|
||||
pass
|
||||
```
|
||||
|
||||
When you run this code it should print "A ValidationError was raised."
|
||||
|
||||
#### Pydantic custom types
|
||||
|
||||
LanceDB does NOT yet support converting pydantic custom types. If this is something you need,
|
||||
please file a feature request on the [LanceDB Github repo](https://github.com/lancedb/lancedb/issues/new).
|
||||
|
||||
### Using Iterators / Writing Large Datasets
|
||||
|
||||
It is recommended to use itertators to add large datasets in batches when creating your table in one go. This does not create multiple versions of your dataset unlike manually adding batches using `table.add()`
|
||||
@@ -151,7 +241,7 @@ A Table is a collection of Records in a LanceDB Database. You can follow along o
|
||||
You can also use iterators of other types like Pandas dataframe or Pylists directly in the above example.
|
||||
|
||||
## Creating Empty Table
|
||||
You can also create empty tables in python. Initialize it with schema and later ingest data into it.
|
||||
You can create empty tables in python. Initialize it with schema and later ingest data into it.
|
||||
|
||||
```python
|
||||
import lancedb
|
||||
@@ -201,8 +291,8 @@ A Table is a collection of Records in a LanceDB Database. You can follow along o
|
||||
```javascript
|
||||
data
|
||||
const tb = await db.createTable("my_table",
|
||||
data=[{"vector": [3.1, 4.1], "item": "foo", "price": 10.0},
|
||||
{"vector": [5.9, 26.5], "item": "bar", "price": 20.0}])
|
||||
[{"vector": [3.1, 4.1], "item": "foo", "price": 10.0},
|
||||
{"vector": [5.9, 26.5], "item": "bar", "price": 20.0}])
|
||||
```
|
||||
|
||||
!!! info "Note"
|
||||
@@ -361,19 +451,28 @@ Use the `delete()` method on tables to delete rows from a table. To choose which
|
||||
await tbl.countRows() // Returns 1
|
||||
```
|
||||
|
||||
### Updating a Table [Experimental]
|
||||
EXPERIMENTAL: Update rows in the table (not threadsafe).
|
||||
## Updating a Table
|
||||
|
||||
This can be used to update zero to all rows depending on how many rows match the where clause.
|
||||
This can be used to update zero to all rows depending on how many rows match the where clause. The update queries follow the form of a SQL UPDATE statement. The `where` parameter is a SQL filter that matches on the metadata columns. The `values` or `values_sql` parameters are used to provide the new values for the columns.
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| Parameter | Type | Description |
|
||||
|---|---|---|
|
||||
| `where` | `str` | The SQL where clause to use when updating rows. For example, `'x = 2'` or `'x IN (1, 2, 3)'`. The filter must not be empty, or it will error. |
|
||||
| `values` | `dict` | The values to update. The keys are the column names and the values are the values to set. |
|
||||
| `values_sql` | `dict` | The values to update. The keys are the column names and the values are the SQL expressions to set. For example, `{'x': 'x + 1'}` will increment the value of the `x` column by 1. |
|
||||
|
||||
!!! info "SQL syntax"
|
||||
|
||||
See [SQL filters](sql.md) for more information on the supported SQL syntax.
|
||||
|
||||
!!! warning "Warning"
|
||||
|
||||
Updating nested columns is not yet supported.
|
||||
|
||||
=== "Python"
|
||||
|
||||
API Reference: [lancedb.table.Table.update][]
|
||||
|
||||
```python
|
||||
import lancedb
|
||||
import pandas as pd
|
||||
@@ -403,6 +502,55 @@ This can be used to update zero to all rows depending on how many rows match the
|
||||
2 2 [10.0, 10.0]
|
||||
```
|
||||
|
||||
=== "Javascript/Typescript"
|
||||
|
||||
API Reference: [vectordb.Table.update](../../javascript/interfaces/Table/#update)
|
||||
|
||||
```javascript
|
||||
const lancedb = require("vectordb");
|
||||
|
||||
const db = await lancedb.connect("./.lancedb");
|
||||
|
||||
const data = [
|
||||
{x: 1, vector: [1, 2]},
|
||||
{x: 2, vector: [3, 4]},
|
||||
{x: 3, vector: [5, 6]},
|
||||
];
|
||||
const tbl = await db.createTable("my_table", data)
|
||||
|
||||
await tbl.update({ where: "x = 2", values: {vector: [10, 10]} })
|
||||
```
|
||||
|
||||
The `values` parameter is used to provide the new values for the columns as literal values. You can also use the `values_sql` / `valuesSql` parameter to provide SQL expressions for the new values. For example, you can use `values_sql="x + 1"` to increment the value of the `x` column by 1.
|
||||
|
||||
=== "Python"
|
||||
|
||||
```python
|
||||
# Update the table where x = 2
|
||||
table.update(valuesSql={"x": "x + 1"})
|
||||
|
||||
print(table.to_pandas())
|
||||
```
|
||||
|
||||
Output
|
||||
```shell
|
||||
x vector
|
||||
0 2 [1.0, 2.0]
|
||||
1 4 [5.0, 6.0]
|
||||
2 3 [10.0, 10.0]
|
||||
```
|
||||
|
||||
=== "Javascript/Typescript"
|
||||
|
||||
```javascript
|
||||
await tbl.update({ valuesSql: { x: "x + 1" } })
|
||||
```
|
||||
|
||||
!!! info "Note"
|
||||
|
||||
When rows are updated, they are moved out of the index. The row will still show up in ANN queries, but the query will not be as fast as it would be if the row was in the index. If you update a large proportion of rows, consider rebuilding the index afterwards.
|
||||
|
||||
|
||||
## What's Next?
|
||||
|
||||
Learn how to Query your tables and create indices
|
||||
@@ -11,8 +11,13 @@ npm install vectordb
|
||||
```
|
||||
|
||||
This will download the appropriate native library for your platform. We currently
|
||||
support x86_64 Linux, aarch64 Linux, Intel MacOS, and ARM (M1/M2) MacOS. We do not
|
||||
yet support Windows or musl-based Linux (such as Alpine Linux).
|
||||
support:
|
||||
|
||||
* Linux (x86_64 and aarch64)
|
||||
* MacOS (Intel and ARM/M1/M2)
|
||||
* Windows (x86_64 only)
|
||||
|
||||
We do not yet support musl-based Linux (such as Alpine Linux) or aarch64 Windows.
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
41
docs/src/javascript/classes/DefaultWriteOptions.md
Normal file
41
docs/src/javascript/classes/DefaultWriteOptions.md
Normal file
@@ -0,0 +1,41 @@
|
||||
[vectordb](../README.md) / [Exports](../modules.md) / DefaultWriteOptions
|
||||
|
||||
# Class: DefaultWriteOptions
|
||||
|
||||
Write options when creating a Table.
|
||||
|
||||
## Implements
|
||||
|
||||
- [`WriteOptions`](../interfaces/WriteOptions.md)
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Constructors
|
||||
|
||||
- [constructor](DefaultWriteOptions.md#constructor)
|
||||
|
||||
### Properties
|
||||
|
||||
- [writeMode](DefaultWriteOptions.md#writemode)
|
||||
|
||||
## Constructors
|
||||
|
||||
### constructor
|
||||
|
||||
• **new DefaultWriteOptions**()
|
||||
|
||||
## Properties
|
||||
|
||||
### writeMode
|
||||
|
||||
• **writeMode**: [`WriteMode`](../enums/WriteMode.md) = `WriteMode.Create`
|
||||
|
||||
A [WriteMode](../enums/WriteMode.md) to use on this operation
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[WriteOptions](../interfaces/WriteOptions.md).[writeMode](../interfaces/WriteOptions.md#writemode)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:778](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L778)
|
||||
@@ -26,7 +26,7 @@ A connection to a LanceDB database.
|
||||
### Methods
|
||||
|
||||
- [createTable](LocalConnection.md#createtable)
|
||||
- [createTableArrow](LocalConnection.md#createtablearrow)
|
||||
- [createTableImpl](LocalConnection.md#createtableimpl)
|
||||
- [dropTable](LocalConnection.md#droptable)
|
||||
- [openTable](LocalConnection.md#opentable)
|
||||
- [tableNames](LocalConnection.md#tablenames)
|
||||
@@ -46,7 +46,7 @@ A connection to a LanceDB database.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:184](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L184)
|
||||
[index.ts:355](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L355)
|
||||
|
||||
## Properties
|
||||
|
||||
@@ -56,17 +56,25 @@ A connection to a LanceDB database.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:182](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L182)
|
||||
[index.ts:353](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L353)
|
||||
|
||||
___
|
||||
|
||||
### \_options
|
||||
|
||||
• `Private` `Readonly` **\_options**: [`ConnectionOptions`](../interfaces/ConnectionOptions.md)
|
||||
• `Private` `Readonly` **\_options**: () => [`ConnectionOptions`](../interfaces/ConnectionOptions.md)
|
||||
|
||||
#### Type declaration
|
||||
|
||||
▸ (): [`ConnectionOptions`](../interfaces/ConnectionOptions.md)
|
||||
|
||||
##### Returns
|
||||
|
||||
[`ConnectionOptions`](../interfaces/ConnectionOptions.md)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:181](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L181)
|
||||
[index.ts:352](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L352)
|
||||
|
||||
## Accessors
|
||||
|
||||
@@ -84,27 +92,34 @@ ___
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:189](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L189)
|
||||
[index.ts:360](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L360)
|
||||
|
||||
## Methods
|
||||
|
||||
### createTable
|
||||
|
||||
▸ **createTable**(`name`, `data`, `mode?`): `Promise`<[`Table`](../interfaces/Table.md)<`number`[]\>\>
|
||||
▸ **createTable**\<`T`\>(`name`, `data?`, `optsOrEmbedding?`, `opt?`): `Promise`\<[`Table`](../interfaces/Table.md)\<`T`\>\>
|
||||
|
||||
Creates a new Table and initialize it with new data.
|
||||
Creates a new Table, optionally initializing it with new data.
|
||||
|
||||
#### Type parameters
|
||||
|
||||
| Name |
|
||||
| :------ |
|
||||
| `T` |
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `name` | `string` | The name of the table. |
|
||||
| `data` | `Record`<`string`, `unknown`\>[] | Non-empty Array of Records to be inserted into the Table |
|
||||
| `mode?` | [`WriteMode`](../enums/WriteMode.md) | The write mode to use when creating the table. |
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `name` | `string` \| [`CreateTableOptions`](../interfaces/CreateTableOptions.md)\<`T`\> |
|
||||
| `data?` | `Record`\<`string`, `unknown`\>[] |
|
||||
| `optsOrEmbedding?` | [`WriteOptions`](../interfaces/WriteOptions.md) \| [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)\<`T`\> |
|
||||
| `opt?` | [`WriteOptions`](../interfaces/WriteOptions.md) |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](../interfaces/Table.md)<`number`[]\>\>
|
||||
`Promise`\<[`Table`](../interfaces/Table.md)\<`T`\>\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
@@ -112,120 +127,44 @@ Creates a new Table and initialize it with new data.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:230](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L230)
|
||||
|
||||
▸ **createTable**(`name`, `data`, `mode`): `Promise`<[`Table`](../interfaces/Table.md)<`number`[]\>\>
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `name` | `string` |
|
||||
| `data` | `Record`<`string`, `unknown`\>[] |
|
||||
| `mode` | [`WriteMode`](../enums/WriteMode.md) |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](../interfaces/Table.md)<`number`[]\>\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
Connection.createTable
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:231](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L231)
|
||||
|
||||
▸ **createTable**<`T`\>(`name`, `data`, `mode`, `embeddings`): `Promise`<[`Table`](../interfaces/Table.md)<`T`\>\>
|
||||
|
||||
Creates a new Table and initialize it with new data.
|
||||
|
||||
#### Type parameters
|
||||
|
||||
| Name |
|
||||
| :------ |
|
||||
| `T` |
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `name` | `string` | The name of the table. |
|
||||
| `data` | `Record`<`string`, `unknown`\>[] | Non-empty Array of Records to be inserted into the Table |
|
||||
| `mode` | [`WriteMode`](../enums/WriteMode.md) | The write mode to use when creating the table. |
|
||||
| `embeddings` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)<`T`\> | An embedding function to use on this Table |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](../interfaces/Table.md)<`T`\>\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
Connection.createTable
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:241](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L241)
|
||||
|
||||
▸ **createTable**<`T`\>(`name`, `data`, `mode`, `embeddings?`): `Promise`<[`Table`](../interfaces/Table.md)<`T`\>\>
|
||||
|
||||
#### Type parameters
|
||||
|
||||
| Name |
|
||||
| :------ |
|
||||
| `T` |
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `name` | `string` |
|
||||
| `data` | `Record`<`string`, `unknown`\>[] |
|
||||
| `mode` | [`WriteMode`](../enums/WriteMode.md) |
|
||||
| `embeddings?` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)<`T`\> |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](../interfaces/Table.md)<`T`\>\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
Connection.createTable
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:242](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L242)
|
||||
[index.ts:395](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L395)
|
||||
|
||||
___
|
||||
|
||||
### createTableArrow
|
||||
### createTableImpl
|
||||
|
||||
▸ **createTableArrow**(`name`, `table`): `Promise`<[`Table`](../interfaces/Table.md)<`number`[]\>\>
|
||||
▸ `Private` **createTableImpl**\<`T`\>(`«destructured»`): `Promise`\<[`Table`](../interfaces/Table.md)\<`T`\>\>
|
||||
|
||||
#### Type parameters
|
||||
|
||||
| Name |
|
||||
| :------ |
|
||||
| `T` |
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `name` | `string` |
|
||||
| `table` | `Table`<`any`\> |
|
||||
| `«destructured»` | `Object` |
|
||||
| › `data?` | `Table`\<`any`\> \| `Record`\<`string`, `unknown`\>[] |
|
||||
| › `embeddingFunction?` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)\<`T`\> |
|
||||
| › `name` | `string` |
|
||||
| › `schema?` | `Schema`\<`any`\> |
|
||||
| › `writeOptions?` | [`WriteOptions`](../interfaces/WriteOptions.md) |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](../interfaces/Table.md)<`number`[]\>\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Connection](../interfaces/Connection.md).[createTableArrow](../interfaces/Connection.md#createtablearrow)
|
||||
`Promise`\<[`Table`](../interfaces/Table.md)\<`T`\>\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:266](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L266)
|
||||
[index.ts:413](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L413)
|
||||
|
||||
___
|
||||
|
||||
### dropTable
|
||||
|
||||
▸ **dropTable**(`name`): `Promise`<`void`\>
|
||||
▸ **dropTable**(`name`): `Promise`\<`void`\>
|
||||
|
||||
Drop an existing table.
|
||||
|
||||
@@ -237,7 +176,7 @@ Drop an existing table.
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`void`\>
|
||||
`Promise`\<`void`\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
@@ -245,13 +184,13 @@ Drop an existing table.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:276](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L276)
|
||||
[index.ts:453](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L453)
|
||||
|
||||
___
|
||||
|
||||
### openTable
|
||||
|
||||
▸ **openTable**(`name`): `Promise`<[`Table`](../interfaces/Table.md)<`number`[]\>\>
|
||||
▸ **openTable**(`name`): `Promise`\<[`Table`](../interfaces/Table.md)\<`number`[]\>\>
|
||||
|
||||
Open a table in the database.
|
||||
|
||||
@@ -263,7 +202,7 @@ Open a table in the database.
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](../interfaces/Table.md)<`number`[]\>\>
|
||||
`Promise`\<[`Table`](../interfaces/Table.md)\<`number`[]\>\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
@@ -271,9 +210,9 @@ Open a table in the database.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:205](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L205)
|
||||
[index.ts:376](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L376)
|
||||
|
||||
▸ **openTable**<`T`\>(`name`, `embeddings`): `Promise`<[`Table`](../interfaces/Table.md)<`T`\>\>
|
||||
▸ **openTable**\<`T`\>(`name`, `embeddings`): `Promise`\<[`Table`](../interfaces/Table.md)\<`T`\>\>
|
||||
|
||||
Open a table in the database.
|
||||
|
||||
@@ -288,11 +227,11 @@ Open a table in the database.
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `name` | `string` | The name of the table. |
|
||||
| `embeddings` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)<`T`\> | An embedding function to use on this Table |
|
||||
| `embeddings` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)\<`T`\> | An embedding function to use on this Table |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](../interfaces/Table.md)<`T`\>\>
|
||||
`Promise`\<[`Table`](../interfaces/Table.md)\<`T`\>\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
@@ -300,9 +239,9 @@ Connection.openTable
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:212](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L212)
|
||||
[index.ts:384](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L384)
|
||||
|
||||
▸ **openTable**<`T`\>(`name`, `embeddings?`): `Promise`<[`Table`](../interfaces/Table.md)<`T`\>\>
|
||||
▸ **openTable**\<`T`\>(`name`, `embeddings?`): `Promise`\<[`Table`](../interfaces/Table.md)\<`T`\>\>
|
||||
|
||||
#### Type parameters
|
||||
|
||||
@@ -315,11 +254,11 @@ Connection.openTable
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `name` | `string` |
|
||||
| `embeddings?` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)<`T`\> |
|
||||
| `embeddings?` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)\<`T`\> |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](../interfaces/Table.md)<`T`\>\>
|
||||
`Promise`\<[`Table`](../interfaces/Table.md)\<`T`\>\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
@@ -327,19 +266,19 @@ Connection.openTable
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:213](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L213)
|
||||
[index.ts:385](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L385)
|
||||
|
||||
___
|
||||
|
||||
### tableNames
|
||||
|
||||
▸ **tableNames**(): `Promise`<`string`[]\>
|
||||
▸ **tableNames**(): `Promise`\<`string`[]\>
|
||||
|
||||
Get the names of all tables in the database.
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`string`[]\>
|
||||
`Promise`\<`string`[]\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
@@ -347,4 +286,4 @@ Get the names of all tables in the database.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:196](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L196)
|
||||
[index.ts:367](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L367)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[vectordb](../README.md) / [Exports](../modules.md) / LocalTable
|
||||
|
||||
# Class: LocalTable<T\>
|
||||
# Class: LocalTable\<T\>
|
||||
|
||||
A LanceDB Table is the collection of Records. Each Record has one or more vector fields.
|
||||
|
||||
@@ -12,7 +12,7 @@ A LanceDB Table is the collection of Records. Each Record has one or more vector
|
||||
|
||||
## Implements
|
||||
|
||||
- [`Table`](../interfaces/Table.md)<`T`\>
|
||||
- [`Table`](../interfaces/Table.md)\<`T`\>
|
||||
|
||||
## Table of contents
|
||||
|
||||
@@ -26,6 +26,7 @@ A LanceDB Table is the collection of Records. Each Record has one or more vector
|
||||
- [\_name](LocalTable.md#_name)
|
||||
- [\_options](LocalTable.md#_options)
|
||||
- [\_tbl](LocalTable.md#_tbl)
|
||||
- [where](LocalTable.md#where)
|
||||
|
||||
### Accessors
|
||||
|
||||
@@ -34,17 +35,23 @@ A LanceDB Table is the collection of Records. Each Record has one or more vector
|
||||
### Methods
|
||||
|
||||
- [add](LocalTable.md#add)
|
||||
- [cleanupOldVersions](LocalTable.md#cleanupoldversions)
|
||||
- [compactFiles](LocalTable.md#compactfiles)
|
||||
- [countRows](LocalTable.md#countrows)
|
||||
- [createIndex](LocalTable.md#createindex)
|
||||
- [delete](LocalTable.md#delete)
|
||||
- [filter](LocalTable.md#filter)
|
||||
- [indexStats](LocalTable.md#indexstats)
|
||||
- [listIndices](LocalTable.md#listindices)
|
||||
- [overwrite](LocalTable.md#overwrite)
|
||||
- [search](LocalTable.md#search)
|
||||
- [update](LocalTable.md#update)
|
||||
|
||||
## Constructors
|
||||
|
||||
### constructor
|
||||
|
||||
• **new LocalTable**<`T`\>(`tbl`, `name`, `options`)
|
||||
• **new LocalTable**\<`T`\>(`tbl`, `name`, `options`)
|
||||
|
||||
#### Type parameters
|
||||
|
||||
@@ -62,9 +69,9 @@ A LanceDB Table is the collection of Records. Each Record has one or more vector
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:287](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L287)
|
||||
[index.ts:464](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L464)
|
||||
|
||||
• **new LocalTable**<`T`\>(`tbl`, `name`, `options`, `embeddings`)
|
||||
• **new LocalTable**\<`T`\>(`tbl`, `name`, `options`, `embeddings`)
|
||||
|
||||
#### Type parameters
|
||||
|
||||
@@ -79,21 +86,21 @@ A LanceDB Table is the collection of Records. Each Record has one or more vector
|
||||
| `tbl` | `any` | |
|
||||
| `name` | `string` | |
|
||||
| `options` | [`ConnectionOptions`](../interfaces/ConnectionOptions.md) | |
|
||||
| `embeddings` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)<`T`\> | An embedding function to use when interacting with this table |
|
||||
| `embeddings` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)\<`T`\> | An embedding function to use when interacting with this table |
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:294](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L294)
|
||||
[index.ts:471](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L471)
|
||||
|
||||
## Properties
|
||||
|
||||
### \_embeddings
|
||||
|
||||
• `Private` `Optional` `Readonly` **\_embeddings**: [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)<`T`\>
|
||||
• `Private` `Optional` `Readonly` **\_embeddings**: [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)\<`T`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:284](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L284)
|
||||
[index.ts:461](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L461)
|
||||
|
||||
___
|
||||
|
||||
@@ -103,27 +110,61 @@ ___
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:283](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L283)
|
||||
[index.ts:460](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L460)
|
||||
|
||||
___
|
||||
|
||||
### \_options
|
||||
|
||||
• `Private` `Readonly` **\_options**: [`ConnectionOptions`](../interfaces/ConnectionOptions.md)
|
||||
• `Private` `Readonly` **\_options**: () => [`ConnectionOptions`](../interfaces/ConnectionOptions.md)
|
||||
|
||||
#### Type declaration
|
||||
|
||||
▸ (): [`ConnectionOptions`](../interfaces/ConnectionOptions.md)
|
||||
|
||||
##### Returns
|
||||
|
||||
[`ConnectionOptions`](../interfaces/ConnectionOptions.md)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:285](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L285)
|
||||
[index.ts:462](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L462)
|
||||
|
||||
___
|
||||
|
||||
### \_tbl
|
||||
|
||||
• `Private` `Readonly` **\_tbl**: `any`
|
||||
• `Private` **\_tbl**: `any`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:282](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L282)
|
||||
[index.ts:459](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L459)
|
||||
|
||||
___
|
||||
|
||||
### where
|
||||
|
||||
• **where**: (`value`: `string`) => [`Query`](Query.md)\<`T`\>
|
||||
|
||||
#### Type declaration
|
||||
|
||||
▸ (`value`): [`Query`](Query.md)\<`T`\>
|
||||
|
||||
Creates a filter query to find all rows matching the specified criteria
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `value` | `string` | The filter criteria (like SQL where clause syntax) |
|
||||
|
||||
##### Returns
|
||||
|
||||
[`Query`](Query.md)\<`T`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:499](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L499)
|
||||
|
||||
## Accessors
|
||||
|
||||
@@ -141,13 +182,13 @@ ___
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:302](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L302)
|
||||
[index.ts:479](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L479)
|
||||
|
||||
## Methods
|
||||
|
||||
### add
|
||||
|
||||
▸ **add**(`data`): `Promise`<`number`\>
|
||||
▸ **add**(`data`): `Promise`\<`number`\>
|
||||
|
||||
Insert records into this Table.
|
||||
|
||||
@@ -155,11 +196,11 @@ Insert records into this Table.
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `data` | `Record`<`string`, `unknown`\>[] | Records to be inserted into the Table |
|
||||
| `data` | `Record`\<`string`, `unknown`\>[] | Records to be inserted into the Table |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`number`\>
|
||||
`Promise`\<`number`\>
|
||||
|
||||
The number of rows added to the table
|
||||
|
||||
@@ -169,19 +210,69 @@ The number of rows added to the table
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:320](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L320)
|
||||
[index.ts:507](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L507)
|
||||
|
||||
___
|
||||
|
||||
### cleanupOldVersions
|
||||
|
||||
▸ **cleanupOldVersions**(`olderThan?`, `deleteUnverified?`): `Promise`\<[`CleanupStats`](../interfaces/CleanupStats.md)\>
|
||||
|
||||
Clean up old versions of the table, freeing disk space.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `olderThan?` | `number` | The minimum age in minutes of the versions to delete. If not provided, defaults to two weeks. |
|
||||
| `deleteUnverified?` | `boolean` | Because they may be part of an in-progress transaction, uncommitted files newer than 7 days old are not deleted by default. This means that failed transactions can leave around data that takes up disk space for up to 7 days. You can override this safety mechanism by setting this option to `true`, only if you promise there are no in progress writes while you run this operation. Failure to uphold this promise can lead to corrupted tables. |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`\<[`CleanupStats`](../interfaces/CleanupStats.md)\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:596](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L596)
|
||||
|
||||
___
|
||||
|
||||
### compactFiles
|
||||
|
||||
▸ **compactFiles**(`options?`): `Promise`\<[`CompactionMetrics`](../interfaces/CompactionMetrics.md)\>
|
||||
|
||||
Run the compaction process on the table.
|
||||
|
||||
This can be run after making several small appends to optimize the table
|
||||
for faster reads.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `options?` | [`CompactionOptions`](../interfaces/CompactionOptions.md) | Advanced options configuring compaction. In most cases, you can omit this arguments, as the default options are sensible for most tables. |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`\<[`CompactionMetrics`](../interfaces/CompactionMetrics.md)\>
|
||||
|
||||
Metrics about the compaction operation.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:615](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L615)
|
||||
|
||||
___
|
||||
|
||||
### countRows
|
||||
|
||||
▸ **countRows**(): `Promise`<`number`\>
|
||||
▸ **countRows**(): `Promise`\<`number`\>
|
||||
|
||||
Returns the number of rows in this table.
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`number`\>
|
||||
`Promise`\<`number`\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
@@ -189,20 +280,16 @@ Returns the number of rows in this table.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:362](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L362)
|
||||
[index.ts:543](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L543)
|
||||
|
||||
___
|
||||
|
||||
### createIndex
|
||||
|
||||
▸ **createIndex**(`indexParams`): `Promise`<`any`\>
|
||||
▸ **createIndex**(`indexParams`): `Promise`\<`any`\>
|
||||
|
||||
Create an ANN index on this Table vector index.
|
||||
|
||||
**`See`**
|
||||
|
||||
VectorIndexParams.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
@@ -211,7 +298,11 @@ VectorIndexParams.
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`any`\>
|
||||
`Promise`\<`any`\>
|
||||
|
||||
**`See`**
|
||||
|
||||
VectorIndexParams.
|
||||
|
||||
#### Implementation of
|
||||
|
||||
@@ -219,13 +310,13 @@ VectorIndexParams.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:355](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L355)
|
||||
[index.ts:536](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L536)
|
||||
|
||||
___
|
||||
|
||||
### delete
|
||||
|
||||
▸ **delete**(`filter`): `Promise`<`void`\>
|
||||
▸ **delete**(`filter`): `Promise`\<`void`\>
|
||||
|
||||
Delete rows from this table.
|
||||
|
||||
@@ -237,7 +328,7 @@ Delete rows from this table.
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`void`\>
|
||||
`Promise`\<`void`\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
@@ -245,13 +336,81 @@ Delete rows from this table.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:371](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L371)
|
||||
[index.ts:552](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L552)
|
||||
|
||||
___
|
||||
|
||||
### filter
|
||||
|
||||
▸ **filter**(`value`): [`Query`](Query.md)\<`T`\>
|
||||
|
||||
Creates a filter query to find all rows matching the specified criteria
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `value` | `string` | The filter criteria (like SQL where clause syntax) |
|
||||
|
||||
#### Returns
|
||||
|
||||
[`Query`](Query.md)\<`T`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:495](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L495)
|
||||
|
||||
___
|
||||
|
||||
### indexStats
|
||||
|
||||
▸ **indexStats**(`indexUuid`): `Promise`\<[`IndexStats`](../interfaces/IndexStats.md)\>
|
||||
|
||||
Get statistics about an index.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `indexUuid` | `string` |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`\<[`IndexStats`](../interfaces/IndexStats.md)\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Table](../interfaces/Table.md).[indexStats](../interfaces/Table.md#indexstats)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:628](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L628)
|
||||
|
||||
___
|
||||
|
||||
### listIndices
|
||||
|
||||
▸ **listIndices**(): `Promise`\<[`VectorIndex`](../interfaces/VectorIndex.md)[]\>
|
||||
|
||||
List the indicies on this table.
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`\<[`VectorIndex`](../interfaces/VectorIndex.md)[]\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Table](../interfaces/Table.md).[listIndices](../interfaces/Table.md#listindices)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:624](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L624)
|
||||
|
||||
___
|
||||
|
||||
### overwrite
|
||||
|
||||
▸ **overwrite**(`data`): `Promise`<`number`\>
|
||||
▸ **overwrite**(`data`): `Promise`\<`number`\>
|
||||
|
||||
Insert records into this Table, replacing its contents.
|
||||
|
||||
@@ -259,11 +418,11 @@ Insert records into this Table, replacing its contents.
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `data` | `Record`<`string`, `unknown`\>[] | Records to be inserted into the Table |
|
||||
| `data` | `Record`\<`string`, `unknown`\>[] | Records to be inserted into the Table |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`number`\>
|
||||
`Promise`\<`number`\>
|
||||
|
||||
The number of rows added to the table
|
||||
|
||||
@@ -273,13 +432,13 @@ The number of rows added to the table
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:338](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L338)
|
||||
[index.ts:522](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L522)
|
||||
|
||||
___
|
||||
|
||||
### search
|
||||
|
||||
▸ **search**(`query`): [`Query`](Query.md)<`T`\>
|
||||
▸ **search**(`query`): [`Query`](Query.md)\<`T`\>
|
||||
|
||||
Creates a search query to find the nearest neighbors of the given search term
|
||||
|
||||
@@ -291,7 +450,7 @@ Creates a search query to find the nearest neighbors of the given search term
|
||||
|
||||
#### Returns
|
||||
|
||||
[`Query`](Query.md)<`T`\>
|
||||
[`Query`](Query.md)\<`T`\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
@@ -299,4 +458,30 @@ Creates a search query to find the nearest neighbors of the given search term
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:310](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L310)
|
||||
[index.ts:487](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L487)
|
||||
|
||||
___
|
||||
|
||||
### update
|
||||
|
||||
▸ **update**(`args`): `Promise`\<`void`\>
|
||||
|
||||
Update rows in this table.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `args` | [`UpdateArgs`](../interfaces/UpdateArgs.md) \| [`UpdateSqlArgs`](../interfaces/UpdateSqlArgs.md) | see [UpdateArgs](../interfaces/UpdateArgs.md) and [UpdateSqlArgs](../interfaces/UpdateSqlArgs.md) for more details |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`\<`void`\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Table](../interfaces/Table.md).[update](../interfaces/Table.md#update)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:563](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L563)
|
||||
|
||||
@@ -6,7 +6,7 @@ An embedding function that automatically creates vector representation for a giv
|
||||
|
||||
## Implements
|
||||
|
||||
- [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)<`string`\>
|
||||
- [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)\<`string`\>
|
||||
|
||||
## Table of contents
|
||||
|
||||
@@ -40,7 +40,7 @@ An embedding function that automatically creates vector representation for a giv
|
||||
|
||||
#### Defined in
|
||||
|
||||
[embedding/openai.ts:21](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/embedding/openai.ts#L21)
|
||||
[embedding/openai.ts:21](https://github.com/lancedb/lancedb/blob/7856a94/node/src/embedding/openai.ts#L21)
|
||||
|
||||
## Properties
|
||||
|
||||
@@ -50,7 +50,7 @@ An embedding function that automatically creates vector representation for a giv
|
||||
|
||||
#### Defined in
|
||||
|
||||
[embedding/openai.ts:19](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/embedding/openai.ts#L19)
|
||||
[embedding/openai.ts:19](https://github.com/lancedb/lancedb/blob/7856a94/node/src/embedding/openai.ts#L19)
|
||||
|
||||
___
|
||||
|
||||
@@ -60,7 +60,7 @@ ___
|
||||
|
||||
#### Defined in
|
||||
|
||||
[embedding/openai.ts:18](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/embedding/openai.ts#L18)
|
||||
[embedding/openai.ts:18](https://github.com/lancedb/lancedb/blob/7856a94/node/src/embedding/openai.ts#L18)
|
||||
|
||||
___
|
||||
|
||||
@@ -76,13 +76,13 @@ The name of the column that will be used as input for the Embedding Function.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[embedding/openai.ts:50](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/embedding/openai.ts#L50)
|
||||
[embedding/openai.ts:50](https://github.com/lancedb/lancedb/blob/7856a94/node/src/embedding/openai.ts#L50)
|
||||
|
||||
## Methods
|
||||
|
||||
### embed
|
||||
|
||||
▸ **embed**(`data`): `Promise`<`number`[][]\>
|
||||
▸ **embed**(`data`): `Promise`\<`number`[][]\>
|
||||
|
||||
Creates a vector representation for the given values.
|
||||
|
||||
@@ -94,7 +94,7 @@ Creates a vector representation for the given values.
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`number`[][]\>
|
||||
`Promise`\<`number`[][]\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
@@ -102,4 +102,4 @@ Creates a vector representation for the given values.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[embedding/openai.ts:38](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/embedding/openai.ts#L38)
|
||||
[embedding/openai.ts:38](https://github.com/lancedb/lancedb/blob/7856a94/node/src/embedding/openai.ts#L38)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[vectordb](../README.md) / [Exports](../modules.md) / Query
|
||||
|
||||
# Class: Query<T\>
|
||||
# Class: Query\<T\>
|
||||
|
||||
A builder for nearest neighbor queries for LanceDB.
|
||||
|
||||
@@ -23,6 +23,7 @@ A builder for nearest neighbor queries for LanceDB.
|
||||
- [\_limit](Query.md#_limit)
|
||||
- [\_metricType](Query.md#_metrictype)
|
||||
- [\_nprobes](Query.md#_nprobes)
|
||||
- [\_prefilter](Query.md#_prefilter)
|
||||
- [\_query](Query.md#_query)
|
||||
- [\_queryVector](Query.md#_queryvector)
|
||||
- [\_refineFactor](Query.md#_refinefactor)
|
||||
@@ -34,9 +35,11 @@ A builder for nearest neighbor queries for LanceDB.
|
||||
|
||||
- [execute](Query.md#execute)
|
||||
- [filter](Query.md#filter)
|
||||
- [isElectron](Query.md#iselectron)
|
||||
- [limit](Query.md#limit)
|
||||
- [metricType](Query.md#metrictype)
|
||||
- [nprobes](Query.md#nprobes)
|
||||
- [prefilter](Query.md#prefilter)
|
||||
- [refineFactor](Query.md#refinefactor)
|
||||
- [select](Query.md#select)
|
||||
|
||||
@@ -44,7 +47,7 @@ A builder for nearest neighbor queries for LanceDB.
|
||||
|
||||
### constructor
|
||||
|
||||
• **new Query**<`T`\>(`tbl`, `query`, `embeddings?`)
|
||||
• **new Query**\<`T`\>(`query?`, `tbl?`, `embeddings?`)
|
||||
|
||||
#### Type parameters
|
||||
|
||||
@@ -56,23 +59,23 @@ A builder for nearest neighbor queries for LanceDB.
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `tbl` | `any` |
|
||||
| `query` | `T` |
|
||||
| `embeddings?` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)<`T`\> |
|
||||
| `query?` | `T` |
|
||||
| `tbl?` | `any` |
|
||||
| `embeddings?` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)\<`T`\> |
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:448](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L448)
|
||||
[query.ts:38](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L38)
|
||||
|
||||
## Properties
|
||||
|
||||
### \_embeddings
|
||||
|
||||
• `Private` `Optional` `Readonly` **\_embeddings**: [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)<`T`\>
|
||||
• `Protected` `Optional` `Readonly` **\_embeddings**: [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)\<`T`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:446](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L446)
|
||||
[query.ts:36](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L36)
|
||||
|
||||
___
|
||||
|
||||
@@ -82,17 +85,17 @@ ___
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:444](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L444)
|
||||
[query.ts:33](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L33)
|
||||
|
||||
___
|
||||
|
||||
### \_limit
|
||||
|
||||
• `Private` **\_limit**: `number`
|
||||
• `Private` `Optional` **\_limit**: `number`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:440](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L440)
|
||||
[query.ts:29](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L29)
|
||||
|
||||
___
|
||||
|
||||
@@ -102,7 +105,7 @@ ___
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:445](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L445)
|
||||
[query.ts:34](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L34)
|
||||
|
||||
___
|
||||
|
||||
@@ -112,17 +115,27 @@ ___
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:442](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L442)
|
||||
[query.ts:31](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L31)
|
||||
|
||||
___
|
||||
|
||||
### \_prefilter
|
||||
|
||||
• `Private` **\_prefilter**: `boolean`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[query.ts:35](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L35)
|
||||
|
||||
___
|
||||
|
||||
### \_query
|
||||
|
||||
• `Private` `Readonly` **\_query**: `T`
|
||||
• `Private` `Optional` `Readonly` **\_query**: `T`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:438](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L438)
|
||||
[query.ts:26](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L26)
|
||||
|
||||
___
|
||||
|
||||
@@ -132,7 +145,7 @@ ___
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:439](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L439)
|
||||
[query.ts:28](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L28)
|
||||
|
||||
___
|
||||
|
||||
@@ -142,7 +155,7 @@ ___
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:441](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L441)
|
||||
[query.ts:30](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L30)
|
||||
|
||||
___
|
||||
|
||||
@@ -152,27 +165,27 @@ ___
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:443](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L443)
|
||||
[query.ts:32](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L32)
|
||||
|
||||
___
|
||||
|
||||
### \_tbl
|
||||
|
||||
• `Private` `Readonly` **\_tbl**: `any`
|
||||
• `Private` `Optional` `Readonly` **\_tbl**: `any`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:437](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L437)
|
||||
[query.ts:27](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L27)
|
||||
|
||||
___
|
||||
|
||||
### where
|
||||
|
||||
• **where**: (`value`: `string`) => [`Query`](Query.md)<`T`\>
|
||||
• **where**: (`value`: `string`) => [`Query`](Query.md)\<`T`\>
|
||||
|
||||
#### Type declaration
|
||||
|
||||
▸ (`value`): [`Query`](Query.md)<`T`\>
|
||||
▸ (`value`): [`Query`](Query.md)\<`T`\>
|
||||
|
||||
A filter statement to be applied to this query.
|
||||
|
||||
@@ -184,17 +197,17 @@ A filter statement to be applied to this query.
|
||||
|
||||
##### Returns
|
||||
|
||||
[`Query`](Query.md)<`T`\>
|
||||
[`Query`](Query.md)\<`T`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:496](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L496)
|
||||
[query.ts:87](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L87)
|
||||
|
||||
## Methods
|
||||
|
||||
### execute
|
||||
|
||||
▸ **execute**<`T`\>(): `Promise`<`T`[]\>
|
||||
▸ **execute**\<`T`\>(): `Promise`\<`T`[]\>
|
||||
|
||||
Execute the query and return the results as an Array of Objects
|
||||
|
||||
@@ -202,21 +215,21 @@ Execute the query and return the results as an Array of Objects
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `T` | `Record`<`string`, `unknown`\> |
|
||||
| `T` | `Record`\<`string`, `unknown`\> |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`T`[]\>
|
||||
`Promise`\<`T`[]\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:519](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L519)
|
||||
[query.ts:115](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L115)
|
||||
|
||||
___
|
||||
|
||||
### filter
|
||||
|
||||
▸ **filter**(`value`): [`Query`](Query.md)<`T`\>
|
||||
▸ **filter**(`value`): [`Query`](Query.md)\<`T`\>
|
||||
|
||||
A filter statement to be applied to this query.
|
||||
|
||||
@@ -228,17 +241,31 @@ A filter statement to be applied to this query.
|
||||
|
||||
#### Returns
|
||||
|
||||
[`Query`](Query.md)<`T`\>
|
||||
[`Query`](Query.md)\<`T`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:491](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L491)
|
||||
[query.ts:82](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L82)
|
||||
|
||||
___
|
||||
|
||||
### isElectron
|
||||
|
||||
▸ `Private` **isElectron**(): `boolean`
|
||||
|
||||
#### Returns
|
||||
|
||||
`boolean`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[query.ts:142](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L142)
|
||||
|
||||
___
|
||||
|
||||
### limit
|
||||
|
||||
▸ **limit**(`value`): [`Query`](Query.md)<`T`\>
|
||||
▸ **limit**(`value`): [`Query`](Query.md)\<`T`\>
|
||||
|
||||
Sets the number of results that will be returned
|
||||
|
||||
@@ -250,24 +277,20 @@ Sets the number of results that will be returned
|
||||
|
||||
#### Returns
|
||||
|
||||
[`Query`](Query.md)<`T`\>
|
||||
[`Query`](Query.md)\<`T`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:464](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L464)
|
||||
[query.ts:55](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L55)
|
||||
|
||||
___
|
||||
|
||||
### metricType
|
||||
|
||||
▸ **metricType**(`value`): [`Query`](Query.md)<`T`\>
|
||||
▸ **metricType**(`value`): [`Query`](Query.md)\<`T`\>
|
||||
|
||||
The MetricType used for this Query.
|
||||
|
||||
**`See`**
|
||||
|
||||
MetricType for the different options
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
@@ -276,17 +299,21 @@ MetricType for the different options
|
||||
|
||||
#### Returns
|
||||
|
||||
[`Query`](Query.md)<`T`\>
|
||||
[`Query`](Query.md)\<`T`\>
|
||||
|
||||
**`See`**
|
||||
|
||||
MetricType for the different options
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:511](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L511)
|
||||
[query.ts:102](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L102)
|
||||
|
||||
___
|
||||
|
||||
### nprobes
|
||||
|
||||
▸ **nprobes**(`value`): [`Query`](Query.md)<`T`\>
|
||||
▸ **nprobes**(`value`): [`Query`](Query.md)\<`T`\>
|
||||
|
||||
The number of probes used. A higher number makes search more accurate but also slower.
|
||||
|
||||
@@ -298,17 +325,37 @@ The number of probes used. A higher number makes search more accurate but also s
|
||||
|
||||
#### Returns
|
||||
|
||||
[`Query`](Query.md)<`T`\>
|
||||
[`Query`](Query.md)\<`T`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:482](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L482)
|
||||
[query.ts:73](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L73)
|
||||
|
||||
___
|
||||
|
||||
### prefilter
|
||||
|
||||
▸ **prefilter**(`value`): [`Query`](Query.md)\<`T`\>
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `value` | `boolean` |
|
||||
|
||||
#### Returns
|
||||
|
||||
[`Query`](Query.md)\<`T`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[query.ts:107](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L107)
|
||||
|
||||
___
|
||||
|
||||
### refineFactor
|
||||
|
||||
▸ **refineFactor**(`value`): [`Query`](Query.md)<`T`\>
|
||||
▸ **refineFactor**(`value`): [`Query`](Query.md)\<`T`\>
|
||||
|
||||
Refine the results by reading extra elements and re-ranking them in memory.
|
||||
|
||||
@@ -320,17 +367,17 @@ Refine the results by reading extra elements and re-ranking them in memory.
|
||||
|
||||
#### Returns
|
||||
|
||||
[`Query`](Query.md)<`T`\>
|
||||
[`Query`](Query.md)\<`T`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:473](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L473)
|
||||
[query.ts:64](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L64)
|
||||
|
||||
___
|
||||
|
||||
### select
|
||||
|
||||
▸ **select**(`value`): [`Query`](Query.md)<`T`\>
|
||||
▸ **select**(`value`): [`Query`](Query.md)\<`T`\>
|
||||
|
||||
Return only the specified columns.
|
||||
|
||||
@@ -342,8 +389,8 @@ Return only the specified columns.
|
||||
|
||||
#### Returns
|
||||
|
||||
[`Query`](Query.md)<`T`\>
|
||||
[`Query`](Query.md)\<`T`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:502](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L502)
|
||||
[query.ts:93](https://github.com/lancedb/lancedb/blob/7856a94/node/src/query.ts#L93)
|
||||
|
||||
226
docs/src/javascript/classes/RemoteConnection.md
Normal file
226
docs/src/javascript/classes/RemoteConnection.md
Normal file
@@ -0,0 +1,226 @@
|
||||
[vectordb](../README.md) / [Exports](../saas-modules.md) / RemoteConnection
|
||||
|
||||
# Class: RemoteConnection
|
||||
|
||||
A connection to a remote LanceDB database. The class RemoteConnection implements interface Connection
|
||||
|
||||
## Implements
|
||||
|
||||
- [`Connection`](../interfaces/Connection.md)
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Constructors
|
||||
|
||||
- [constructor](RemoteConnection.md#constructor)
|
||||
|
||||
### Methods
|
||||
|
||||
- [createTable](RemoteConnection.md#createtable)
|
||||
- [tableNames](RemoteConnection.md#tablenames)
|
||||
- [openTable](RemoteConnection.md#opentable)
|
||||
- [dropTable](RemoteConnection.md#droptable)
|
||||
|
||||
|
||||
## Constructors
|
||||
|
||||
### constructor
|
||||
|
||||
• **new RemoteConnection**(`client`, `dbName`)
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `client` | `HttpLancedbClient` |
|
||||
| `dbName` | `string` |
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:37](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L37)
|
||||
|
||||
## Methods
|
||||
|
||||
### createTable
|
||||
|
||||
▸ **createTable**(`name`, `data`, `mode?`): `Promise`<[`Table`](../interfaces/Table.md)<`number`[]\>\>
|
||||
|
||||
Creates a new Table and initialize it with new data.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `name` | `string` | The name of the table. |
|
||||
| `data` | `Record`<`string`, `unknown`\>[] | Non-empty Array of Records to be inserted into the Table |
|
||||
| `mode?` | [`WriteMode`](../enums/WriteMode.md) | The write mode to use when creating the table. |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](../interfaces/Table.md)<`number`[]\>\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Connection](../interfaces/Connection.md).[createTable](../interfaces/Connection.md#createtable)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:75](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L75)
|
||||
|
||||
▸ **createTable**(`name`, `data`, `mode`): `Promise`<[`Table`](../interfaces/Table.md)<`number`[]\>\>
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `name` | `string` |
|
||||
| `data` | `Record`<`string`, `unknown`\>[] |
|
||||
| `mode` | [`WriteMode`](../enums/WriteMode.md) |
|
||||
| `embeddings` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)<`T`\> | An embedding function to use on this Table |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](../interfaces/Table.md)<`number`[]\>\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
Connection.createTable
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:231](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L231)
|
||||
|
||||
___
|
||||
|
||||
### dropTable
|
||||
|
||||
▸ **dropTable**(`name`): `Promise`<`void`\>
|
||||
|
||||
Drop an existing table.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `name` | `string` | The name of the table to drop. |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`void`\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Connection](../interfaces/Connection.md).[dropTable](../interfaces/Connection.md#droptable)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:131](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L131)
|
||||
|
||||
___
|
||||
|
||||
### openTable
|
||||
|
||||
▸ **openTable**(`name`): `Promise`<[`Table`](../interfaces/Table.md)<`number`[]\>\>
|
||||
|
||||
Open a table in the database.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `name` | `string` | The name of the table. |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](../interfaces/Table.md)<`number`[]\>\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Connection](../interfaces/Connection.md).[openTable](../interfaces/Connection.md#opentable)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:65](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L65)
|
||||
|
||||
▸ **openTable**<`T`\>(`name`, `embeddings`): `Promise`<[`Table`](../interfaces/Table.md)<`T`\>\>
|
||||
|
||||
Open a table in the database.
|
||||
|
||||
#### Type parameters
|
||||
|
||||
| Name |
|
||||
| :------ |
|
||||
| `T` |
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `name` | `string` | The name of the table. |
|
||||
| `embeddings` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)<`T`\> | An embedding function to use on this Table |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](../interfaces/Table.md)<`T`\>\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
Connection.openTable
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:66](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L66)
|
||||
|
||||
▸ **openTable**<`T`\>(`name`, `embeddings?`): `Promise`<[`Table`](../interfaces/Table.md)<`T`\>\>
|
||||
|
||||
#### Type parameters
|
||||
|
||||
| Name |
|
||||
| :------ |
|
||||
| `T` |
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `name` | `string` |
|
||||
| `embeddings?` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)<`T`\> |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](../interfaces/Table.md)<`T`\>\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
Connection.openTable
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:67](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L67)
|
||||
|
||||
___
|
||||
|
||||
### tableNames
|
||||
|
||||
▸ **tableNames**(): `Promise`<`string`[]\>
|
||||
|
||||
Get the names of all tables in the database, with pagination.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `pageToken` | `string` |
|
||||
| `limit` | `int` |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`string`[]\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Connection](../interfaces/Connection.md).[tableNames](../interfaces/Connection.md#tablenames)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:60](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L60)
|
||||
76
docs/src/javascript/classes/RemoteQuery.md
Normal file
76
docs/src/javascript/classes/RemoteQuery.md
Normal file
@@ -0,0 +1,76 @@
|
||||
[vectordb](../README.md) / [Exports](../saas-modules.md) / RemoteQuery
|
||||
|
||||
# Class: Query<T\>
|
||||
|
||||
A builder for nearest neighbor queries for LanceDB.
|
||||
|
||||
## Type parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `T` | `number`[] |
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Constructors
|
||||
|
||||
- [constructor](RemoteQuery.md#constructor)
|
||||
|
||||
### Properties
|
||||
|
||||
- [\_embeddings](RemoteQuery.md#_embeddings)
|
||||
- [\_query](RemoteQuery.md#_query)
|
||||
- [\_name](RemoteQuery.md#_name)
|
||||
- [\_client](RemoteQuery.md#_client)
|
||||
|
||||
### Methods
|
||||
|
||||
- [execute](RemoteQuery.md#execute)
|
||||
|
||||
|
||||
## Constructors
|
||||
|
||||
### constructor
|
||||
|
||||
• **new Query**<`T`\>(`name`, `client`, `query`, `embeddings?`)
|
||||
|
||||
#### Type parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `T` | `number`[] |
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `name` | `string` |
|
||||
| `client` | `HttpLancedbClient` |
|
||||
| `query` | `T` |
|
||||
| `embeddings?` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)<`T`\> |
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:137](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L137)
|
||||
|
||||
## Methods
|
||||
|
||||
### execute
|
||||
|
||||
▸ **execute**<`T`\>(): `Promise`<`T`[]\>
|
||||
|
||||
Execute the query and return the results as an Array of Objects
|
||||
|
||||
#### Type parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `T` | `Record`<`string`, `unknown`\> |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`T`[]\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:143](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L143)
|
||||
355
docs/src/javascript/classes/RemoteTable.md
Normal file
355
docs/src/javascript/classes/RemoteTable.md
Normal file
@@ -0,0 +1,355 @@
|
||||
[vectordb](../README.md) / [Exports](../saas-modules.md) / RemoteTable
|
||||
|
||||
# Class: RemoteTable<T\>
|
||||
|
||||
A LanceDB Table is the collection of Records. Each Record has one or more vector fields.
|
||||
|
||||
## Type parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `T` | `number`[] |
|
||||
|
||||
## Implements
|
||||
|
||||
- [`Table`](../interfaces/Table.md)<`T`\>
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Constructors
|
||||
|
||||
- [constructor](RemoteTable.md#constructor)
|
||||
|
||||
### Properties
|
||||
|
||||
- [\_name](RemoteTable.md#_name)
|
||||
- [\_client](RemoteTable.md#_client)
|
||||
- [\_embeddings](RemoteTable.md#_embeddings)
|
||||
|
||||
### Accessors
|
||||
|
||||
- [name](RemoteTable.md#name)
|
||||
|
||||
### Methods
|
||||
|
||||
- [add](RemoteTable.md#add)
|
||||
- [countRows](RemoteTable.md#countrows)
|
||||
- [createIndex](RemoteTable.md#createindex)
|
||||
- [delete](RemoteTable.md#delete)
|
||||
- [listIndices](classes/RemoteTable.md#listindices)
|
||||
- [indexStats](classes/RemoteTable.md#liststats)
|
||||
- [overwrite](RemoteTable.md#overwrite)
|
||||
- [search](RemoteTable.md#search)
|
||||
- [schema](classes/RemoteTable.md#schema)
|
||||
- [update](RemoteTable.md#update)
|
||||
|
||||
## Constructors
|
||||
|
||||
### constructor
|
||||
|
||||
• **new RemoteTable**<`T`\>(`client`, `name`)
|
||||
|
||||
#### Type parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `T` | `number`[] |
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `client` | `HttpLancedbClient` |
|
||||
| `name` | `string` |
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:186](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L186)
|
||||
|
||||
• **new RemoteTable**<`T`\>(`client`, `name`, `embeddings`)
|
||||
|
||||
#### Type parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `T` | `number`[] |
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `client` | `HttpLancedbClient` | |
|
||||
| `name` | `string` | |
|
||||
| `embeddings` | [`EmbeddingFunction`](../interfaces/EmbeddingFunction.md)<`T`\> | An embedding function to use when interacting with this table |
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:187](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L187)
|
||||
|
||||
## Accessors
|
||||
|
||||
### name
|
||||
|
||||
• `get` **name**(): `string`
|
||||
|
||||
#### Returns
|
||||
|
||||
`string`
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Table](../interfaces/Table.md).[name](../interfaces/Table.md#name)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:194](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L194)
|
||||
|
||||
## Methods
|
||||
|
||||
### add
|
||||
|
||||
▸ **add**(`data`): `Promise`<`number`\>
|
||||
|
||||
Insert records into this Table.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `data` | `Record`<`string`, `unknown`\>[] | Records to be inserted into the Table |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`number`\>
|
||||
|
||||
The number of rows added to the table
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Table](../interfaces/Table.md).[add](../interfaces/Table.md#add)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:293](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L293)
|
||||
|
||||
___
|
||||
|
||||
### countRows
|
||||
|
||||
▸ **countRows**(): `Promise`<`number`\>
|
||||
|
||||
Returns the number of rows in this table.
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`number`\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Table](../interfaces/Table.md).[countRows](../interfaces/Table.md#countrows)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:290](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L290)
|
||||
|
||||
___
|
||||
|
||||
### createIndex
|
||||
|
||||
▸ **createIndex**(`metric_type`, `column`, `index_cache_size`): `Promise`<`any`\>
|
||||
|
||||
Create an ANN index on this Table vector index.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `metric_type` | `string` | distance metric type, L2 or cosine or dot |
|
||||
| `column` | `string` | the name of the column to be indexed |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`any`\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Table](../interfaces/Table.md).[createIndex](../interfaces/Table.md#createindex)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:249](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L249)
|
||||
|
||||
___
|
||||
|
||||
### delete
|
||||
|
||||
▸ **delete**(`filter`): `Promise`<`void`\>
|
||||
|
||||
Delete rows from this table.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `filter` | `string` | A filter in the same format used by a sql WHERE clause. |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`void`\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Table](../interfaces/Table.md).[delete](../interfaces/Table.md#delete)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:295](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L295)
|
||||
|
||||
___
|
||||
|
||||
### overwrite
|
||||
|
||||
▸ **overwrite**(`data`): `Promise`<`number`\>
|
||||
|
||||
Insert records into this Table, replacing its contents.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `data` | `Record`<`string`, `unknown`\>[] | Records to be inserted into the Table |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`number`\>
|
||||
|
||||
The number of rows added to the table
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Table](../interfaces/Table.md).[overwrite](../interfaces/Table.md#overwrite)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:231](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L231)
|
||||
|
||||
___
|
||||
|
||||
### search
|
||||
|
||||
▸ **search**(`query`): [`Query`](Query.md)<`T`\>
|
||||
|
||||
Creates a search query to find the nearest neighbors of the given search term
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `query` | `T` | The query search term |
|
||||
|
||||
#### Returns
|
||||
|
||||
[`Query`](Query.md)<`T`\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Table](../interfaces/Table.md).[search](../interfaces/Table.md#search)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:209](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L209)
|
||||
|
||||
___
|
||||
|
||||
### update
|
||||
|
||||
▸ **update**(`args`): `Promise`<`void`\>
|
||||
|
||||
Update zero to all rows depending on how many rows match the where clause.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `args` | `UpdateArgs` or `UpdateSqlArgs` | The query search arguments |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`any`\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Table](../interfaces/Table.md).[search](../interfaces/Table.md#update)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:299](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L299)
|
||||
|
||||
___
|
||||
|
||||
### schema
|
||||
|
||||
▸ **schema**(): `Promise`<`void`\>
|
||||
|
||||
Get the schema of the table
|
||||
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`any`\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Table](../interfaces/Table.md).[search](../interfaces/Table.md#schema)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:198](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L198)
|
||||
|
||||
___
|
||||
|
||||
### listIndices
|
||||
|
||||
▸ **listIndices**(): `Promise`<`void`\>
|
||||
|
||||
List the indices of the table
|
||||
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`any`\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Table](../interfaces/Table.md).[search](../interfaces/Table.md#listIndices)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:319](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L319)
|
||||
|
||||
___
|
||||
|
||||
### indexStats
|
||||
|
||||
▸ **indexStats**(`indexUuid`): `Promise`<`void`\>
|
||||
|
||||
Get the indexed/unindexed of rows from the table
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `indexUuid` | `string` | the uuid of the index |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`numIndexedRows`\>
|
||||
`Promise`<`numUnindexedRows`\>
|
||||
|
||||
#### Implementation of
|
||||
|
||||
[Table](../interfaces/Table.md).[search](../interfaces/Table.md#indexStats)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[remote/index.ts:328](https://github.com/lancedb/lancedb/blob/main/node/src/remote/index.ts#L328)
|
||||
@@ -22,7 +22,7 @@ Cosine distance
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:567](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L567)
|
||||
[index.ts:798](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L798)
|
||||
|
||||
___
|
||||
|
||||
@@ -34,7 +34,7 @@ Dot product
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:572](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L572)
|
||||
[index.ts:803](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L803)
|
||||
|
||||
___
|
||||
|
||||
@@ -46,4 +46,4 @@ Euclidean distance
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:562](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L562)
|
||||
[index.ts:793](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L793)
|
||||
|
||||
@@ -22,7 +22,7 @@ Append new data to the table.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:552](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L552)
|
||||
[index.ts:766](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L766)
|
||||
|
||||
___
|
||||
|
||||
@@ -34,7 +34,7 @@ Create a new [Table](../interfaces/Table.md).
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:548](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L548)
|
||||
[index.ts:762](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L762)
|
||||
|
||||
___
|
||||
|
||||
@@ -46,4 +46,4 @@ Overwrite the existing [Table](../interfaces/Table.md) if presented.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:550](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L550)
|
||||
[index.ts:764](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L764)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:31](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L31)
|
||||
[index.ts:34](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L34)
|
||||
|
||||
___
|
||||
|
||||
@@ -28,7 +28,7 @@ ___
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:33](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L33)
|
||||
[index.ts:36](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L36)
|
||||
|
||||
___
|
||||
|
||||
@@ -38,4 +38,4 @@ ___
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:35](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L35)
|
||||
[index.ts:38](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L38)
|
||||
|
||||
34
docs/src/javascript/interfaces/CleanupStats.md
Normal file
34
docs/src/javascript/interfaces/CleanupStats.md
Normal file
@@ -0,0 +1,34 @@
|
||||
[vectordb](../README.md) / [Exports](../modules.md) / CleanupStats
|
||||
|
||||
# Interface: CleanupStats
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Properties
|
||||
|
||||
- [bytesRemoved](CleanupStats.md#bytesremoved)
|
||||
- [oldVersions](CleanupStats.md#oldversions)
|
||||
|
||||
## Properties
|
||||
|
||||
### bytesRemoved
|
||||
|
||||
• **bytesRemoved**: `number`
|
||||
|
||||
The number of bytes removed from disk.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:637](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L637)
|
||||
|
||||
___
|
||||
|
||||
### oldVersions
|
||||
|
||||
• **oldVersions**: `number`
|
||||
|
||||
The number of old table versions removed.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:641](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L641)
|
||||
62
docs/src/javascript/interfaces/CompactionMetrics.md
Normal file
62
docs/src/javascript/interfaces/CompactionMetrics.md
Normal file
@@ -0,0 +1,62 @@
|
||||
[vectordb](../README.md) / [Exports](../modules.md) / CompactionMetrics
|
||||
|
||||
# Interface: CompactionMetrics
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Properties
|
||||
|
||||
- [filesAdded](CompactionMetrics.md#filesadded)
|
||||
- [filesRemoved](CompactionMetrics.md#filesremoved)
|
||||
- [fragmentsAdded](CompactionMetrics.md#fragmentsadded)
|
||||
- [fragmentsRemoved](CompactionMetrics.md#fragmentsremoved)
|
||||
|
||||
## Properties
|
||||
|
||||
### filesAdded
|
||||
|
||||
• **filesAdded**: `number`
|
||||
|
||||
The number of files added. This is typically equal to the number of
|
||||
fragments added.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:692](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L692)
|
||||
|
||||
___
|
||||
|
||||
### filesRemoved
|
||||
|
||||
• **filesRemoved**: `number`
|
||||
|
||||
The number of files that were removed. Each fragment may have more than one
|
||||
file.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:687](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L687)
|
||||
|
||||
___
|
||||
|
||||
### fragmentsAdded
|
||||
|
||||
• **fragmentsAdded**: `number`
|
||||
|
||||
The number of new fragments that were created.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:682](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L682)
|
||||
|
||||
___
|
||||
|
||||
### fragmentsRemoved
|
||||
|
||||
• **fragmentsRemoved**: `number`
|
||||
|
||||
The number of fragments that were removed.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:678](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L678)
|
||||
80
docs/src/javascript/interfaces/CompactionOptions.md
Normal file
80
docs/src/javascript/interfaces/CompactionOptions.md
Normal file
@@ -0,0 +1,80 @@
|
||||
[vectordb](../README.md) / [Exports](../modules.md) / CompactionOptions
|
||||
|
||||
# Interface: CompactionOptions
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Properties
|
||||
|
||||
- [materializeDeletions](CompactionOptions.md#materializedeletions)
|
||||
- [materializeDeletionsThreshold](CompactionOptions.md#materializedeletionsthreshold)
|
||||
- [maxRowsPerGroup](CompactionOptions.md#maxrowspergroup)
|
||||
- [numThreads](CompactionOptions.md#numthreads)
|
||||
- [targetRowsPerFragment](CompactionOptions.md#targetrowsperfragment)
|
||||
|
||||
## Properties
|
||||
|
||||
### materializeDeletions
|
||||
|
||||
• `Optional` **materializeDeletions**: `boolean`
|
||||
|
||||
If true, fragments that have rows that are deleted may be compacted to
|
||||
remove the deleted rows. This can improve the performance of queries.
|
||||
Default is true.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:660](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L660)
|
||||
|
||||
___
|
||||
|
||||
### materializeDeletionsThreshold
|
||||
|
||||
• `Optional` **materializeDeletionsThreshold**: `number`
|
||||
|
||||
A number between 0 and 1, representing the proportion of rows that must be
|
||||
marked deleted before a fragment is a candidate for compaction to remove
|
||||
the deleted rows. Default is 10%.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:666](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L666)
|
||||
|
||||
___
|
||||
|
||||
### maxRowsPerGroup
|
||||
|
||||
• `Optional` **maxRowsPerGroup**: `number`
|
||||
|
||||
The maximum number of rows per group. Defaults to 1024.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:654](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L654)
|
||||
|
||||
___
|
||||
|
||||
### numThreads
|
||||
|
||||
• `Optional` **numThreads**: `number`
|
||||
|
||||
The number of threads to use for compaction. If not provided, defaults to
|
||||
the number of cores on the machine.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:671](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L671)
|
||||
|
||||
___
|
||||
|
||||
### targetRowsPerFragment
|
||||
|
||||
• `Optional` **targetRowsPerFragment**: `number`
|
||||
|
||||
The number of rows per fragment to target. Fragments that have fewer rows
|
||||
will be compacted into adjacent fragments to produce larger fragments.
|
||||
Defaults to 1024 * 1024.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:650](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L650)
|
||||
@@ -19,7 +19,6 @@ Connection could be local against filesystem or remote against a server.
|
||||
### Methods
|
||||
|
||||
- [createTable](Connection.md#createtable)
|
||||
- [createTableArrow](Connection.md#createtablearrow)
|
||||
- [dropTable](Connection.md#droptable)
|
||||
- [openTable](Connection.md#opentable)
|
||||
- [tableNames](Connection.md#tablenames)
|
||||
@@ -32,13 +31,76 @@ Connection could be local against filesystem or remote against a server.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:70](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L70)
|
||||
[index.ts:125](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L125)
|
||||
|
||||
## Methods
|
||||
|
||||
### createTable
|
||||
|
||||
▸ **createTable**<`T`\>(`name`, `data`, `mode?`, `embeddings?`): `Promise`<[`Table`](Table.md)<`T`\>\>
|
||||
▸ **createTable**\<`T`\>(`«destructured»`): `Promise`\<[`Table`](Table.md)\<`T`\>\>
|
||||
|
||||
Creates a new Table, optionally initializing it with new data.
|
||||
|
||||
#### Type parameters
|
||||
|
||||
| Name |
|
||||
| :------ |
|
||||
| `T` |
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `«destructured»` | [`CreateTableOptions`](CreateTableOptions.md)\<`T`\> |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`\<[`Table`](Table.md)\<`T`\>\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:146](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L146)
|
||||
|
||||
▸ **createTable**(`name`, `data`): `Promise`\<[`Table`](Table.md)\<`number`[]\>\>
|
||||
|
||||
Creates a new Table and initialize it with new data.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `name` | `string` | The name of the table. |
|
||||
| `data` | `Record`\<`string`, `unknown`\>[] | Non-empty Array of Records to be inserted into the table |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`\<[`Table`](Table.md)\<`number`[]\>\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:154](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L154)
|
||||
|
||||
▸ **createTable**(`name`, `data`, `options`): `Promise`\<[`Table`](Table.md)\<`number`[]\>\>
|
||||
|
||||
Creates a new Table and initialize it with new data.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `name` | `string` | The name of the table. |
|
||||
| `data` | `Record`\<`string`, `unknown`\>[] | Non-empty Array of Records to be inserted into the table |
|
||||
| `options` | [`WriteOptions`](WriteOptions.md) | The write options to use when creating the table. |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`\<[`Table`](Table.md)\<`number`[]\>\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:163](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L163)
|
||||
|
||||
▸ **createTable**\<`T`\>(`name`, `data`, `embeddings`): `Promise`\<[`Table`](Table.md)\<`T`\>\>
|
||||
|
||||
Creates a new Table and initialize it with new data.
|
||||
|
||||
@@ -53,44 +115,49 @@ Creates a new Table and initialize it with new data.
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `name` | `string` | The name of the table. |
|
||||
| `data` | `Record`<`string`, `unknown`\>[] | Non-empty Array of Records to be inserted into the table |
|
||||
| `mode?` | [`WriteMode`](../enums/WriteMode.md) | The write mode to use when creating the table. |
|
||||
| `embeddings?` | [`EmbeddingFunction`](EmbeddingFunction.md)<`T`\> | An embedding function to use on this table |
|
||||
| `data` | `Record`\<`string`, `unknown`\>[] | Non-empty Array of Records to be inserted into the table |
|
||||
| `embeddings` | [`EmbeddingFunction`](EmbeddingFunction.md)\<`T`\> | An embedding function to use on this table |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](Table.md)<`T`\>\>
|
||||
`Promise`\<[`Table`](Table.md)\<`T`\>\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:90](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L90)
|
||||
[index.ts:172](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L172)
|
||||
|
||||
___
|
||||
▸ **createTable**\<`T`\>(`name`, `data`, `embeddings`, `options`): `Promise`\<[`Table`](Table.md)\<`T`\>\>
|
||||
|
||||
### createTableArrow
|
||||
Creates a new Table and initialize it with new data.
|
||||
|
||||
▸ **createTableArrow**(`name`, `table`): `Promise`<[`Table`](Table.md)<`number`[]\>\>
|
||||
#### Type parameters
|
||||
|
||||
| Name |
|
||||
| :------ |
|
||||
| `T` |
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `name` | `string` |
|
||||
| `table` | `Table`<`any`\> |
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `name` | `string` | The name of the table. |
|
||||
| `data` | `Record`\<`string`, `unknown`\>[] | Non-empty Array of Records to be inserted into the table |
|
||||
| `embeddings` | [`EmbeddingFunction`](EmbeddingFunction.md)\<`T`\> | An embedding function to use on this table |
|
||||
| `options` | [`WriteOptions`](WriteOptions.md) | The write options to use when creating the table. |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](Table.md)<`number`[]\>\>
|
||||
`Promise`\<[`Table`](Table.md)\<`T`\>\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:92](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L92)
|
||||
[index.ts:181](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L181)
|
||||
|
||||
___
|
||||
|
||||
### dropTable
|
||||
|
||||
▸ **dropTable**(`name`): `Promise`<`void`\>
|
||||
▸ **dropTable**(`name`): `Promise`\<`void`\>
|
||||
|
||||
Drop an existing table.
|
||||
|
||||
@@ -102,17 +169,17 @@ Drop an existing table.
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`void`\>
|
||||
`Promise`\<`void`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:98](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L98)
|
||||
[index.ts:187](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L187)
|
||||
|
||||
___
|
||||
|
||||
### openTable
|
||||
|
||||
▸ **openTable**<`T`\>(`name`, `embeddings?`): `Promise`<[`Table`](Table.md)<`T`\>\>
|
||||
▸ **openTable**\<`T`\>(`name`, `embeddings?`): `Promise`\<[`Table`](Table.md)\<`T`\>\>
|
||||
|
||||
Open a table in the database.
|
||||
|
||||
@@ -127,26 +194,26 @@ Open a table in the database.
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `name` | `string` | The name of the table. |
|
||||
| `embeddings?` | [`EmbeddingFunction`](EmbeddingFunction.md)<`T`\> | An embedding function to use on this table |
|
||||
| `embeddings?` | [`EmbeddingFunction`](EmbeddingFunction.md)\<`T`\> | An embedding function to use on this table |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Table`](Table.md)<`T`\>\>
|
||||
`Promise`\<[`Table`](Table.md)\<`T`\>\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:80](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L80)
|
||||
[index.ts:135](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L135)
|
||||
|
||||
___
|
||||
|
||||
### tableNames
|
||||
|
||||
▸ **tableNames**(): `Promise`<`string`[]\>
|
||||
▸ **tableNames**(): `Promise`\<`string`[]\>
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<`string`[]\>
|
||||
`Promise`\<`string`[]\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:72](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L72)
|
||||
[index.ts:127](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L127)
|
||||
|
||||
@@ -6,18 +6,62 @@
|
||||
|
||||
### Properties
|
||||
|
||||
- [apiKey](ConnectionOptions.md#apikey)
|
||||
- [awsCredentials](ConnectionOptions.md#awscredentials)
|
||||
- [awsRegion](ConnectionOptions.md#awsregion)
|
||||
- [hostOverride](ConnectionOptions.md#hostoverride)
|
||||
- [region](ConnectionOptions.md#region)
|
||||
- [uri](ConnectionOptions.md#uri)
|
||||
|
||||
## Properties
|
||||
|
||||
### apiKey
|
||||
|
||||
• `Optional` **apiKey**: `string`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:49](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L49)
|
||||
|
||||
___
|
||||
|
||||
### awsCredentials
|
||||
|
||||
• `Optional` **awsCredentials**: [`AwsCredentials`](AwsCredentials.md)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:40](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L40)
|
||||
[index.ts:44](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L44)
|
||||
|
||||
___
|
||||
|
||||
### awsRegion
|
||||
|
||||
• `Optional` **awsRegion**: `string`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:46](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L46)
|
||||
|
||||
___
|
||||
|
||||
### hostOverride
|
||||
|
||||
• `Optional` **hostOverride**: `string`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:54](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L54)
|
||||
|
||||
___
|
||||
|
||||
### region
|
||||
|
||||
• `Optional` **region**: `string`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:51](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L51)
|
||||
|
||||
___
|
||||
|
||||
@@ -27,4 +71,4 @@ ___
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:39](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L39)
|
||||
[index.ts:42](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L42)
|
||||
|
||||
69
docs/src/javascript/interfaces/CreateTableOptions.md
Normal file
69
docs/src/javascript/interfaces/CreateTableOptions.md
Normal file
@@ -0,0 +1,69 @@
|
||||
[vectordb](../README.md) / [Exports](../modules.md) / CreateTableOptions
|
||||
|
||||
# Interface: CreateTableOptions\<T\>
|
||||
|
||||
## Type parameters
|
||||
|
||||
| Name |
|
||||
| :------ |
|
||||
| `T` |
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Properties
|
||||
|
||||
- [data](CreateTableOptions.md#data)
|
||||
- [embeddingFunction](CreateTableOptions.md#embeddingfunction)
|
||||
- [name](CreateTableOptions.md#name)
|
||||
- [schema](CreateTableOptions.md#schema)
|
||||
- [writeOptions](CreateTableOptions.md#writeoptions)
|
||||
|
||||
## Properties
|
||||
|
||||
### data
|
||||
|
||||
• `Optional` **data**: `Table`\<`any`\> \| `Record`\<`string`, `unknown`\>[]
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:79](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L79)
|
||||
|
||||
___
|
||||
|
||||
### embeddingFunction
|
||||
|
||||
• `Optional` **embeddingFunction**: [`EmbeddingFunction`](EmbeddingFunction.md)\<`T`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:85](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L85)
|
||||
|
||||
___
|
||||
|
||||
### name
|
||||
|
||||
• **name**: `string`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:76](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L76)
|
||||
|
||||
___
|
||||
|
||||
### schema
|
||||
|
||||
• `Optional` **schema**: `Schema`\<`any`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:82](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L82)
|
||||
|
||||
___
|
||||
|
||||
### writeOptions
|
||||
|
||||
• `Optional` **writeOptions**: [`WriteOptions`](WriteOptions.md)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:88](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L88)
|
||||
@@ -1,6 +1,6 @@
|
||||
[vectordb](../README.md) / [Exports](../modules.md) / EmbeddingFunction
|
||||
|
||||
# Interface: EmbeddingFunction<T\>
|
||||
# Interface: EmbeddingFunction\<T\>
|
||||
|
||||
An embedding function that automatically creates vector representation for a given column.
|
||||
|
||||
@@ -25,11 +25,11 @@ An embedding function that automatically creates vector representation for a giv
|
||||
|
||||
### embed
|
||||
|
||||
• **embed**: (`data`: `T`[]) => `Promise`<`number`[][]\>
|
||||
• **embed**: (`data`: `T`[]) => `Promise`\<`number`[][]\>
|
||||
|
||||
#### Type declaration
|
||||
|
||||
▸ (`data`): `Promise`<`number`[][]\>
|
||||
▸ (`data`): `Promise`\<`number`[][]\>
|
||||
|
||||
Creates a vector representation for the given values.
|
||||
|
||||
@@ -41,11 +41,11 @@ Creates a vector representation for the given values.
|
||||
|
||||
##### Returns
|
||||
|
||||
`Promise`<`number`[][]\>
|
||||
`Promise`\<`number`[][]\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[embedding/embedding_function.ts:27](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/embedding/embedding_function.ts#L27)
|
||||
[embedding/embedding_function.ts:27](https://github.com/lancedb/lancedb/blob/7856a94/node/src/embedding/embedding_function.ts#L27)
|
||||
|
||||
___
|
||||
|
||||
@@ -57,4 +57,4 @@ The name of the column that will be used as input for the Embedding Function.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[embedding/embedding_function.ts:22](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/embedding/embedding_function.ts#L22)
|
||||
[embedding/embedding_function.ts:22](https://github.com/lancedb/lancedb/blob/7856a94/node/src/embedding/embedding_function.ts#L22)
|
||||
|
||||
30
docs/src/javascript/interfaces/IndexStats.md
Normal file
30
docs/src/javascript/interfaces/IndexStats.md
Normal file
@@ -0,0 +1,30 @@
|
||||
[vectordb](../README.md) / [Exports](../modules.md) / IndexStats
|
||||
|
||||
# Interface: IndexStats
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Properties
|
||||
|
||||
- [numIndexedRows](IndexStats.md#numindexedrows)
|
||||
- [numUnindexedRows](IndexStats.md#numunindexedrows)
|
||||
|
||||
## Properties
|
||||
|
||||
### numIndexedRows
|
||||
|
||||
• **numIndexedRows**: ``null`` \| `number`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:344](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L344)
|
||||
|
||||
___
|
||||
|
||||
### numUnindexedRows
|
||||
|
||||
• **numUnindexedRows**: ``null`` \| `number`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:345](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L345)
|
||||
@@ -7,6 +7,7 @@
|
||||
### Properties
|
||||
|
||||
- [column](IvfPQIndexConfig.md#column)
|
||||
- [index\_cache\_size](IvfPQIndexConfig.md#index_cache_size)
|
||||
- [index\_name](IvfPQIndexConfig.md#index_name)
|
||||
- [max\_iters](IvfPQIndexConfig.md#max_iters)
|
||||
- [max\_opq\_iters](IvfPQIndexConfig.md#max_opq_iters)
|
||||
@@ -28,7 +29,19 @@ The column to be indexed
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:382](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L382)
|
||||
[index.ts:701](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L701)
|
||||
|
||||
___
|
||||
|
||||
### index\_cache\_size
|
||||
|
||||
• `Optional` **index\_cache\_size**: `number`
|
||||
|
||||
Cache size of the index
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:750](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L750)
|
||||
|
||||
___
|
||||
|
||||
@@ -40,7 +53,7 @@ A unique name for the index
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:387](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L387)
|
||||
[index.ts:706](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L706)
|
||||
|
||||
___
|
||||
|
||||
@@ -52,7 +65,7 @@ The max number of iterations for kmeans training.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:402](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L402)
|
||||
[index.ts:721](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L721)
|
||||
|
||||
___
|
||||
|
||||
@@ -64,7 +77,7 @@ Max number of iterations to train OPQ, if `use_opq` is true.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:421](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L421)
|
||||
[index.ts:740](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L740)
|
||||
|
||||
___
|
||||
|
||||
@@ -76,7 +89,7 @@ Metric type, L2 or Cosine
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:392](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L392)
|
||||
[index.ts:711](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L711)
|
||||
|
||||
___
|
||||
|
||||
@@ -88,7 +101,7 @@ The number of bits to present one PQ centroid.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:416](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L416)
|
||||
[index.ts:735](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L735)
|
||||
|
||||
___
|
||||
|
||||
@@ -100,7 +113,7 @@ The number of partitions this index
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:397](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L397)
|
||||
[index.ts:716](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L716)
|
||||
|
||||
___
|
||||
|
||||
@@ -112,7 +125,7 @@ Number of subvectors to build PQ code
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:412](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L412)
|
||||
[index.ts:731](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L731)
|
||||
|
||||
___
|
||||
|
||||
@@ -124,7 +137,7 @@ Replace an existing index with the same name if it exists.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:426](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L426)
|
||||
[index.ts:745](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L745)
|
||||
|
||||
___
|
||||
|
||||
@@ -134,7 +147,7 @@ ___
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:428](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L428)
|
||||
[index.ts:752](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L752)
|
||||
|
||||
___
|
||||
|
||||
@@ -146,4 +159,4 @@ Train as optimized product quantization.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:407](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L407)
|
||||
[index.ts:726](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L726)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[vectordb](../README.md) / [Exports](../modules.md) / Table
|
||||
|
||||
# Interface: Table<T\>
|
||||
# Interface: Table\<T\>
|
||||
|
||||
A LanceDB Table is the collection of Records. Each Record has one or more vector fields.
|
||||
|
||||
@@ -22,19 +22,22 @@ A LanceDB Table is the collection of Records. Each Record has one or more vector
|
||||
- [countRows](Table.md#countrows)
|
||||
- [createIndex](Table.md#createindex)
|
||||
- [delete](Table.md#delete)
|
||||
- [indexStats](Table.md#indexstats)
|
||||
- [listIndices](Table.md#listindices)
|
||||
- [name](Table.md#name)
|
||||
- [overwrite](Table.md#overwrite)
|
||||
- [search](Table.md#search)
|
||||
- [update](Table.md#update)
|
||||
|
||||
## Properties
|
||||
|
||||
### add
|
||||
|
||||
• **add**: (`data`: `Record`<`string`, `unknown`\>[]) => `Promise`<`number`\>
|
||||
• **add**: (`data`: `Record`\<`string`, `unknown`\>[]) => `Promise`\<`number`\>
|
||||
|
||||
#### Type declaration
|
||||
|
||||
▸ (`data`): `Promise`<`number`\>
|
||||
▸ (`data`): `Promise`\<`number`\>
|
||||
|
||||
Insert records into this Table.
|
||||
|
||||
@@ -42,54 +45,50 @@ Insert records into this Table.
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `data` | `Record`<`string`, `unknown`\>[] | Records to be inserted into the Table |
|
||||
| `data` | `Record`\<`string`, `unknown`\>[] | Records to be inserted into the Table |
|
||||
|
||||
##### Returns
|
||||
|
||||
`Promise`<`number`\>
|
||||
`Promise`\<`number`\>
|
||||
|
||||
The number of rows added to the table
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:120](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L120)
|
||||
[index.ts:209](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L209)
|
||||
|
||||
___
|
||||
|
||||
### countRows
|
||||
|
||||
• **countRows**: () => `Promise`<`number`\>
|
||||
• **countRows**: () => `Promise`\<`number`\>
|
||||
|
||||
#### Type declaration
|
||||
|
||||
▸ (): `Promise`<`number`\>
|
||||
▸ (): `Promise`\<`number`\>
|
||||
|
||||
Returns the number of rows in this table.
|
||||
|
||||
##### Returns
|
||||
|
||||
`Promise`<`number`\>
|
||||
`Promise`\<`number`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:140](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L140)
|
||||
[index.ts:229](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L229)
|
||||
|
||||
___
|
||||
|
||||
### createIndex
|
||||
|
||||
• **createIndex**: (`indexParams`: [`IvfPQIndexConfig`](IvfPQIndexConfig.md)) => `Promise`<`any`\>
|
||||
• **createIndex**: (`indexParams`: [`IvfPQIndexConfig`](IvfPQIndexConfig.md)) => `Promise`\<`any`\>
|
||||
|
||||
#### Type declaration
|
||||
|
||||
▸ (`indexParams`): `Promise`<`any`\>
|
||||
▸ (`indexParams`): `Promise`\<`any`\>
|
||||
|
||||
Create an ANN index on this Table vector index.
|
||||
|
||||
**`See`**
|
||||
|
||||
VectorIndexParams.
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
@@ -98,27 +97,41 @@ VectorIndexParams.
|
||||
|
||||
##### Returns
|
||||
|
||||
`Promise`<`any`\>
|
||||
`Promise`\<`any`\>
|
||||
|
||||
**`See`**
|
||||
|
||||
VectorIndexParams.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:135](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L135)
|
||||
[index.ts:224](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L224)
|
||||
|
||||
___
|
||||
|
||||
### delete
|
||||
|
||||
• **delete**: (`filter`: `string`) => `Promise`<`void`\>
|
||||
• **delete**: (`filter`: `string`) => `Promise`\<`void`\>
|
||||
|
||||
#### Type declaration
|
||||
|
||||
▸ (`filter`): `Promise`<`void`\>
|
||||
▸ (`filter`): `Promise`\<`void`\>
|
||||
|
||||
Delete rows from this table.
|
||||
|
||||
This can be used to delete a single row, many rows, all rows, or
|
||||
sometimes no rows (if your predicate matches nothing).
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `filter` | `string` | A filter in the same format used by a sql WHERE clause. The filter must not be empty. |
|
||||
|
||||
##### Returns
|
||||
|
||||
`Promise`\<`void`\>
|
||||
|
||||
**`Examples`**
|
||||
|
||||
```ts
|
||||
@@ -142,19 +155,55 @@ await tbl.delete(`id IN (${to_remove.join(",")})`)
|
||||
await tbl.countRows() // Returns 1
|
||||
```
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:263](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L263)
|
||||
|
||||
___
|
||||
|
||||
### indexStats
|
||||
|
||||
• **indexStats**: (`indexUuid`: `string`) => `Promise`\<[`IndexStats`](IndexStats.md)\>
|
||||
|
||||
#### Type declaration
|
||||
|
||||
▸ (`indexUuid`): `Promise`\<[`IndexStats`](IndexStats.md)\>
|
||||
|
||||
Get statistics about an index.
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `filter` | `string` | A filter in the same format used by a sql WHERE clause. The filter must not be empty. |
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `indexUuid` | `string` |
|
||||
|
||||
##### Returns
|
||||
|
||||
`Promise`<`void`\>
|
||||
`Promise`\<[`IndexStats`](IndexStats.md)\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:174](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L174)
|
||||
[index.ts:306](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L306)
|
||||
|
||||
___
|
||||
|
||||
### listIndices
|
||||
|
||||
• **listIndices**: () => `Promise`\<[`VectorIndex`](VectorIndex.md)[]\>
|
||||
|
||||
#### Type declaration
|
||||
|
||||
▸ (): `Promise`\<[`VectorIndex`](VectorIndex.md)[]\>
|
||||
|
||||
List the indicies on this table.
|
||||
|
||||
##### Returns
|
||||
|
||||
`Promise`\<[`VectorIndex`](VectorIndex.md)[]\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:301](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L301)
|
||||
|
||||
___
|
||||
|
||||
@@ -164,17 +213,17 @@ ___
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:106](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L106)
|
||||
[index.ts:195](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L195)
|
||||
|
||||
___
|
||||
|
||||
### overwrite
|
||||
|
||||
• **overwrite**: (`data`: `Record`<`string`, `unknown`\>[]) => `Promise`<`number`\>
|
||||
• **overwrite**: (`data`: `Record`\<`string`, `unknown`\>[]) => `Promise`\<`number`\>
|
||||
|
||||
#### Type declaration
|
||||
|
||||
▸ (`data`): `Promise`<`number`\>
|
||||
▸ (`data`): `Promise`\<`number`\>
|
||||
|
||||
Insert records into this Table, replacing its contents.
|
||||
|
||||
@@ -182,27 +231,27 @@ Insert records into this Table, replacing its contents.
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `data` | `Record`<`string`, `unknown`\>[] | Records to be inserted into the Table |
|
||||
| `data` | `Record`\<`string`, `unknown`\>[] | Records to be inserted into the Table |
|
||||
|
||||
##### Returns
|
||||
|
||||
`Promise`<`number`\>
|
||||
`Promise`\<`number`\>
|
||||
|
||||
The number of rows added to the table
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:128](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L128)
|
||||
[index.ts:217](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L217)
|
||||
|
||||
___
|
||||
|
||||
### search
|
||||
|
||||
• **search**: (`query`: `T`) => [`Query`](../classes/Query.md)<`T`\>
|
||||
• **search**: (`query`: `T`) => [`Query`](../classes/Query.md)\<`T`\>
|
||||
|
||||
#### Type declaration
|
||||
|
||||
▸ (`query`): [`Query`](../classes/Query.md)<`T`\>
|
||||
▸ (`query`): [`Query`](../classes/Query.md)\<`T`\>
|
||||
|
||||
Creates a search query to find the nearest neighbors of the given search term
|
||||
|
||||
@@ -214,8 +263,59 @@ Creates a search query to find the nearest neighbors of the given search term
|
||||
|
||||
##### Returns
|
||||
|
||||
[`Query`](../classes/Query.md)<`T`\>
|
||||
[`Query`](../classes/Query.md)\<`T`\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:112](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L112)
|
||||
[index.ts:201](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L201)
|
||||
|
||||
___
|
||||
|
||||
### update
|
||||
|
||||
• **update**: (`args`: [`UpdateArgs`](UpdateArgs.md) \| [`UpdateSqlArgs`](UpdateSqlArgs.md)) => `Promise`\<`void`\>
|
||||
|
||||
#### Type declaration
|
||||
|
||||
▸ (`args`): `Promise`\<`void`\>
|
||||
|
||||
Update rows in this table.
|
||||
|
||||
This can be used to update a single row, many rows, all rows, or
|
||||
sometimes no rows (if your predicate matches nothing).
|
||||
|
||||
##### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :------ | :------ |
|
||||
| `args` | [`UpdateArgs`](UpdateArgs.md) \| [`UpdateSqlArgs`](UpdateSqlArgs.md) | see [UpdateArgs](UpdateArgs.md) and [UpdateSqlArgs](UpdateSqlArgs.md) for more details |
|
||||
|
||||
##### Returns
|
||||
|
||||
`Promise`\<`void`\>
|
||||
|
||||
**`Examples`**
|
||||
|
||||
```ts
|
||||
const con = await lancedb.connect("./.lancedb")
|
||||
const data = [
|
||||
{id: 1, vector: [3, 3], name: 'Ye'},
|
||||
{id: 2, vector: [4, 4], name: 'Mike'},
|
||||
];
|
||||
const tbl = await con.createTable("my_table", data)
|
||||
|
||||
await tbl.update({
|
||||
filter: "id = 2",
|
||||
updates: { vector: [2, 2], name: "Michael" },
|
||||
})
|
||||
|
||||
let results = await tbl.search([1, 1]).execute();
|
||||
// Returns [
|
||||
// {id: 2, vector: [2, 2], name: 'Michael'}
|
||||
// {id: 1, vector: [3, 3], name: 'Ye'}
|
||||
// ]
|
||||
```
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:296](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L296)
|
||||
|
||||
36
docs/src/javascript/interfaces/UpdateArgs.md
Normal file
36
docs/src/javascript/interfaces/UpdateArgs.md
Normal file
@@ -0,0 +1,36 @@
|
||||
[vectordb](../README.md) / [Exports](../modules.md) / UpdateArgs
|
||||
|
||||
# Interface: UpdateArgs
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Properties
|
||||
|
||||
- [values](UpdateArgs.md#values)
|
||||
- [where](UpdateArgs.md#where)
|
||||
|
||||
## Properties
|
||||
|
||||
### values
|
||||
|
||||
• **values**: `Record`\<`string`, `Literal`\>
|
||||
|
||||
A key-value map of updates. The keys are the column names, and the values are the
|
||||
new values to set
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:320](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L320)
|
||||
|
||||
___
|
||||
|
||||
### where
|
||||
|
||||
• `Optional` **where**: `string`
|
||||
|
||||
A filter in the same format used by a sql WHERE clause. The filter may be empty,
|
||||
in which case all rows will be updated.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:314](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L314)
|
||||
36
docs/src/javascript/interfaces/UpdateSqlArgs.md
Normal file
36
docs/src/javascript/interfaces/UpdateSqlArgs.md
Normal file
@@ -0,0 +1,36 @@
|
||||
[vectordb](../README.md) / [Exports](../modules.md) / UpdateSqlArgs
|
||||
|
||||
# Interface: UpdateSqlArgs
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Properties
|
||||
|
||||
- [valuesSql](UpdateSqlArgs.md#valuessql)
|
||||
- [where](UpdateSqlArgs.md#where)
|
||||
|
||||
## Properties
|
||||
|
||||
### valuesSql
|
||||
|
||||
• **valuesSql**: `Record`\<`string`, `string`\>
|
||||
|
||||
A key-value map of updates. The keys are the column names, and the values are the
|
||||
new values to set as SQL expressions.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:334](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L334)
|
||||
|
||||
___
|
||||
|
||||
### where
|
||||
|
||||
• `Optional` **where**: `string`
|
||||
|
||||
A filter in the same format used by a sql WHERE clause. The filter may be empty,
|
||||
in which case all rows will be updated.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:328](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L328)
|
||||
41
docs/src/javascript/interfaces/VectorIndex.md
Normal file
41
docs/src/javascript/interfaces/VectorIndex.md
Normal file
@@ -0,0 +1,41 @@
|
||||
[vectordb](../README.md) / [Exports](../modules.md) / VectorIndex
|
||||
|
||||
# Interface: VectorIndex
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Properties
|
||||
|
||||
- [columns](VectorIndex.md#columns)
|
||||
- [name](VectorIndex.md#name)
|
||||
- [uuid](VectorIndex.md#uuid)
|
||||
|
||||
## Properties
|
||||
|
||||
### columns
|
||||
|
||||
• **columns**: `string`[]
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:338](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L338)
|
||||
|
||||
___
|
||||
|
||||
### name
|
||||
|
||||
• **name**: `string`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:339](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L339)
|
||||
|
||||
___
|
||||
|
||||
### uuid
|
||||
|
||||
• **uuid**: `string`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:340](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L340)
|
||||
27
docs/src/javascript/interfaces/WriteOptions.md
Normal file
27
docs/src/javascript/interfaces/WriteOptions.md
Normal file
@@ -0,0 +1,27 @@
|
||||
[vectordb](../README.md) / [Exports](../modules.md) / WriteOptions
|
||||
|
||||
# Interface: WriteOptions
|
||||
|
||||
Write options when creating a Table.
|
||||
|
||||
## Implemented by
|
||||
|
||||
- [`DefaultWriteOptions`](../classes/DefaultWriteOptions.md)
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Properties
|
||||
|
||||
- [writeMode](WriteOptions.md#writemode)
|
||||
|
||||
## Properties
|
||||
|
||||
### writeMode
|
||||
|
||||
• `Optional` **writeMode**: [`WriteMode`](../enums/WriteMode.md)
|
||||
|
||||
A [WriteMode](../enums/WriteMode.md) to use on this operation
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:774](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L774)
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
### Classes
|
||||
|
||||
- [DefaultWriteOptions](classes/DefaultWriteOptions.md)
|
||||
- [LocalConnection](classes/LocalConnection.md)
|
||||
- [LocalTable](classes/LocalTable.md)
|
||||
- [OpenAIEmbeddingFunction](classes/OpenAIEmbeddingFunction.md)
|
||||
@@ -19,11 +20,20 @@
|
||||
### Interfaces
|
||||
|
||||
- [AwsCredentials](interfaces/AwsCredentials.md)
|
||||
- [CleanupStats](interfaces/CleanupStats.md)
|
||||
- [CompactionMetrics](interfaces/CompactionMetrics.md)
|
||||
- [CompactionOptions](interfaces/CompactionOptions.md)
|
||||
- [Connection](interfaces/Connection.md)
|
||||
- [ConnectionOptions](interfaces/ConnectionOptions.md)
|
||||
- [CreateTableOptions](interfaces/CreateTableOptions.md)
|
||||
- [EmbeddingFunction](interfaces/EmbeddingFunction.md)
|
||||
- [IndexStats](interfaces/IndexStats.md)
|
||||
- [IvfPQIndexConfig](interfaces/IvfPQIndexConfig.md)
|
||||
- [Table](interfaces/Table.md)
|
||||
- [UpdateArgs](interfaces/UpdateArgs.md)
|
||||
- [UpdateSqlArgs](interfaces/UpdateSqlArgs.md)
|
||||
- [VectorIndex](interfaces/VectorIndex.md)
|
||||
- [WriteOptions](interfaces/WriteOptions.md)
|
||||
|
||||
### Type Aliases
|
||||
|
||||
@@ -32,6 +42,7 @@
|
||||
### Functions
|
||||
|
||||
- [connect](modules.md#connect)
|
||||
- [isWriteOptions](modules.md#iswriteoptions)
|
||||
|
||||
## Type Aliases
|
||||
|
||||
@@ -41,13 +52,13 @@
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:431](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L431)
|
||||
[index.ts:755](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L755)
|
||||
|
||||
## Functions
|
||||
|
||||
### connect
|
||||
|
||||
▸ **connect**(`uri`): `Promise`<[`Connection`](interfaces/Connection.md)\>
|
||||
▸ **connect**(`uri`): `Promise`\<[`Connection`](interfaces/Connection.md)\>
|
||||
|
||||
Connect to a LanceDB instance at the given URI
|
||||
|
||||
@@ -59,24 +70,44 @@ Connect to a LanceDB instance at the given URI
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Connection`](interfaces/Connection.md)\>
|
||||
`Promise`\<[`Connection`](interfaces/Connection.md)\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:47](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L47)
|
||||
[index.ts:95](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L95)
|
||||
|
||||
▸ **connect**(`opts`): `Promise`<[`Connection`](interfaces/Connection.md)\>
|
||||
▸ **connect**(`opts`): `Promise`\<[`Connection`](interfaces/Connection.md)\>
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `opts` | `Partial`<[`ConnectionOptions`](interfaces/ConnectionOptions.md)\> |
|
||||
| `opts` | `Partial`\<[`ConnectionOptions`](interfaces/ConnectionOptions.md)\> |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Promise`<[`Connection`](interfaces/Connection.md)\>
|
||||
`Promise`\<[`Connection`](interfaces/Connection.md)\>
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:48](https://github.com/lancedb/lancedb/blob/b1eeb90/node/src/index.ts#L48)
|
||||
[index.ts:96](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L96)
|
||||
|
||||
___
|
||||
|
||||
### isWriteOptions
|
||||
|
||||
▸ **isWriteOptions**(`value`): value is WriteOptions
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type |
|
||||
| :------ | :------ |
|
||||
| `value` | `any` |
|
||||
|
||||
#### Returns
|
||||
|
||||
value is WriteOptions
|
||||
|
||||
#### Defined in
|
||||
|
||||
[index.ts:781](https://github.com/lancedb/lancedb/blob/7856a94/node/src/index.ts#L781)
|
||||
|
||||
92
docs/src/javascript/saas-modules.md
Normal file
92
docs/src/javascript/saas-modules.md
Normal file
@@ -0,0 +1,92 @@
|
||||
# Table of contents
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install vectordb
|
||||
```
|
||||
|
||||
This will download the appropriate native library for your platform. We currently
|
||||
support x86_64 Linux, aarch64 Linux, Intel MacOS, and ARM (M1/M2) MacOS. We do not
|
||||
yet support Windows or musl-based Linux (such as Alpine Linux).
|
||||
|
||||
|
||||
## Classes
|
||||
- [RemoteConnection](classes/RemoteConnection.md)
|
||||
- [RemoteTable](classes/RemoteTable.md)
|
||||
- [RemoteQuery](classes/RemoteQuery.md)
|
||||
|
||||
|
||||
## Methods
|
||||
|
||||
- [add](classes/RemoteTable.md#add)
|
||||
- [countRows](classes/RemoteTable.md#countrows)
|
||||
- [createIndex](classes/RemoteTable.md#createindex)
|
||||
- [createTable](classes/RemoteConnection.md#createtable)
|
||||
- [delete](classes/RemoteTable.md#delete)
|
||||
- [dropTable](classes/RemoteConnection.md#droptable)
|
||||
- [listIndices](classes/RemoteTable.md#listindices)
|
||||
- [indexStats](classes/RemoteTable.md#liststats)
|
||||
- [openTable](classes/RemoteConnection.md#opentable)
|
||||
- [overwrite](classes/RemoteTable.md#overwrite)
|
||||
- [schema](classes/RemoteTable.md#schema)
|
||||
- [search](classes/RemoteTable.md#search)
|
||||
- [tableNames](classes/RemoteConnection.md#tablenames)
|
||||
- [update](classes/RemoteTable.md#update)
|
||||
|
||||
|
||||
## Example code
|
||||
```javascript
|
||||
|
||||
const lancedb = require('vectordb');
|
||||
const { Schema, Field, Int32, Float32, Utf8, FixedSizeList } = require ("apache-arrow/Arrow.node")
|
||||
|
||||
// connect to a remote DB
|
||||
const devApiKey = process.env.LANCEDB_DEV_API_KEY
|
||||
const dbURI = process.env.LANCEDB_URI
|
||||
const db = await lancedb.connect({
|
||||
uri: dbURI, // replace dbURI with your project, e.g. "db://your-project-name"
|
||||
apiKey: devApiKey, // replace dbURI with your api key
|
||||
region: "us-east-1-dev"
|
||||
});
|
||||
// create a new table
|
||||
const tableName = "my_table_000"
|
||||
const data = [
|
||||
{ id: 1, vector: [0.1, 1.0], item: "foo", price: 10.0 },
|
||||
{ id: 2, vector: [3.9, 0.5], item: "bar", price: 20.0 }
|
||||
]
|
||||
const schema = new Schema(
|
||||
[
|
||||
new Field('id', new Int32()),
|
||||
new Field('vector', new FixedSizeList(2, new Field('float32', new Float32()))),
|
||||
new Field('item', new Utf8()),
|
||||
new Field('price', new Float32())
|
||||
]
|
||||
)
|
||||
const table = await db.createTable({
|
||||
name: tableName,
|
||||
schema,
|
||||
}, data)
|
||||
|
||||
// list the table
|
||||
const tableNames_1 = await db.tableNames('')
|
||||
// add some data and search should be okay
|
||||
const newData = [
|
||||
{ id: 3, vector: [10.3, 1.9], item: "test1", price: 30.0 },
|
||||
{ id: 4, vector: [6.2, 9.2], item: "test2", price: 40.0 }
|
||||
]
|
||||
await table.add(newData)
|
||||
// create the index for the table
|
||||
await table.createIndex({
|
||||
metric_type: "L2",
|
||||
column: "vector"
|
||||
})
|
||||
let result = await table.search([2.8, 4.3]).select(["vector", "price"]).limit(1).execute()
|
||||
// update the data
|
||||
await table.update({
|
||||
where: "id == 1",
|
||||
values: { item: "foo1" }
|
||||
})
|
||||
//drop the table
|
||||
await db.dropTable(tableName)
|
||||
```
|
||||
@@ -44,15 +44,14 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import openai\n",
|
||||
"from openai import OpenAI\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# Configuring the environment variable OPENAI_API_KEY\n",
|
||||
"if \"OPENAI_API_KEY\" not in os.environ:\n",
|
||||
" # OR set the key here as a variable\n",
|
||||
" openai.api_key = \"sk-...\"\n",
|
||||
" \n",
|
||||
"assert len(openai.Model.list()[\"data\"]) > 0"
|
||||
" os.environ[\"OPENAI_API_KEY\"] = \"sk-...\"\n",
|
||||
"client = OpenAI()\n",
|
||||
"assert len(client.models.list().data) > 0"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\u001B[1m[\u001B[0m\u001B[34;49mnotice\u001B[0m\u001B[1;39;49m]\u001B[0m\u001B[39;49m A new release of pip is available: \u001B[0m\u001B[31;49m23.0\u001B[0m\u001B[39;49m -> \u001B[0m\u001B[32;49m23.1.1\u001B[0m\n",
|
||||
"\u001B[1m[\u001B[0m\u001B[34;49mnotice\u001B[0m\u001B[1;39;49m]\u001B[0m\u001B[39;49m To update, run: \u001B[0m\u001B[32;49mpip install --upgrade pip\u001B[0m\n",
|
||||
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.1.1\u001b[0m\n",
|
||||
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
|
||||
"\n",
|
||||
"\u001B[1m[\u001B[0m\u001B[34;49mnotice\u001B[0m\u001B[1;39;49m]\u001B[0m\u001B[39;49m A new release of pip is available: \u001B[0m\u001B[31;49m23.0\u001B[0m\u001B[39;49m -> \u001B[0m\u001B[32;49m23.1.1\u001B[0m\n",
|
||||
"\u001B[1m[\u001B[0m\u001B[34;49mnotice\u001B[0m\u001B[1;39;49m]\u001B[0m\u001B[39;49m To update, run: \u001B[0m\u001B[32;49mpip install --upgrade pip\u001B[0m\n"
|
||||
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.0\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.1.1\u001b[0m\n",
|
||||
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -206,15 +206,16 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import openai\n",
|
||||
"from openai import OpenAI\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# Configuring the environment variable OPENAI_API_KEY\n",
|
||||
"if \"OPENAI_API_KEY\" not in os.environ:\n",
|
||||
" # OR set the key here as a variable\n",
|
||||
" openai.api_key = \"sk-...\"\n",
|
||||
" os.environ[\"OPENAI_API_KEY\"] = \"sk-...\"\n",
|
||||
" \n",
|
||||
"assert len(openai.Model.list()[\"data\"]) > 0"
|
||||
"client = OpenAI()\n",
|
||||
"assert len(client.models.list().data) > 0"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -234,8 +235,8 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def embed_func(c): \n",
|
||||
" rs = openai.Embedding.create(input=c, engine=\"text-embedding-ada-002\")\n",
|
||||
" return [record[\"embedding\"] for record in rs[\"data\"]]"
|
||||
" rs = client.embeddings.create(input=c, model=\"text-embedding-ada-002\")\n",
|
||||
" return [rs.data[0].embedding]"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -536,9 +537,8 @@
|
||||
],
|
||||
"source": [
|
||||
"def complete(prompt):\n",
|
||||
" # query text-davinci-003\n",
|
||||
" res = openai.Completion.create(\n",
|
||||
" engine='text-davinci-003',\n",
|
||||
" res = client.completions.create(\n",
|
||||
" model='text-davinci-003',\n",
|
||||
" prompt=prompt,\n",
|
||||
" temperature=0,\n",
|
||||
" max_tokens=400,\n",
|
||||
@@ -547,7 +547,7 @@
|
||||
" presence_penalty=0,\n",
|
||||
" stop=None\n",
|
||||
" )\n",
|
||||
" return res['choices'][0]['text'].strip()\n",
|
||||
" return res.choices[0].text\n",
|
||||
"\n",
|
||||
"# check that it works\n",
|
||||
"query = \"who was the 12th person on the moon and when did they land?\"\n",
|
||||
|
||||
@@ -7,7 +7,7 @@ LanceDB integrates with Pydantic for schema inference, data ingestion, and query
|
||||
|
||||
LanceDB supports to create Apache Arrow Schema from a
|
||||
[Pydantic BaseModel](https://docs.pydantic.dev/latest/api/main/#pydantic.main.BaseModel)
|
||||
via [pydantic_to_schema()](python.md##lancedb.pydantic.pydantic_to_schema) method.
|
||||
via [pydantic_to_schema()](python.md#lancedb.pydantic.pydantic_to_schema) method.
|
||||
|
||||
::: lancedb.pydantic.pydantic_to_schema
|
||||
|
||||
|
||||
18
docs/src/python/saas-python.md
Normal file
18
docs/src/python/saas-python.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# LanceDB Python API Reference
|
||||
|
||||
## Installation
|
||||
|
||||
```shell
|
||||
pip install lancedb
|
||||
```
|
||||
|
||||
## Connection
|
||||
|
||||
::: lancedb.connect
|
||||
|
||||
::: lancedb.remote.db.RemoteDBConnection
|
||||
|
||||
## Table
|
||||
|
||||
::: lancedb.remote.table.RemoteTable
|
||||
|
||||
@@ -118,4 +118,101 @@ However, fast vector search using indices often entails making a trade-off with
|
||||
This is why it is often called **Approximate Nearest Neighbors (ANN)** search, while the Flat Search (KNN)
|
||||
always returns 100% recall.
|
||||
|
||||
See [ANN Index](ann_indexes.md) for more details.
|
||||
See [ANN Index](ann_indexes.md) for more details.
|
||||
|
||||
|
||||
### Output formats
|
||||
|
||||
LanceDB returns results in many different formats commonly used in python.
|
||||
Let's create a LanceDB table with a nested schema:
|
||||
|
||||
```python
|
||||
from datetime import datetime
|
||||
import lancedb
|
||||
from lancedb.pydantic import LanceModel, Vector
|
||||
import numpy as np
|
||||
from pydantic import BaseModel
|
||||
uri = "data/sample-lancedb-nested"
|
||||
|
||||
class Metadata(BaseModel):
|
||||
source: str
|
||||
timestamp: datetime
|
||||
|
||||
class Document(BaseModel):
|
||||
content: str
|
||||
meta: Metadata
|
||||
|
||||
class LanceSchema(LanceModel):
|
||||
id: str
|
||||
vector: Vector(1536)
|
||||
payload: Document
|
||||
|
||||
# Let's add 100 sample rows to our dataset
|
||||
data = [LanceSchema(
|
||||
id=f"id{i}",
|
||||
vector=np.random.randn(1536),
|
||||
payload=Document(
|
||||
content=f"document{i}", meta=Metadata(source=f"source{i%10}", timestamp=datetime.now())
|
||||
),
|
||||
) for i in range(100)]
|
||||
|
||||
tbl = db.create_table("documents", data=data)
|
||||
```
|
||||
|
||||
#### As a pyarrow table
|
||||
|
||||
Using `to_arrow()` we can get the results back as a pyarrow Table.
|
||||
This result table has the same columns as the LanceDB table, with
|
||||
the addition of an `_distance` column for vector search or a `score`
|
||||
column for full text search.
|
||||
|
||||
```python
|
||||
tbl.search(np.random.randn(1536)).to_arrow()
|
||||
```
|
||||
|
||||
#### As a pandas dataframe
|
||||
|
||||
You can also get the results as a pandas dataframe.
|
||||
|
||||
```python
|
||||
tbl.search(np.random.randn(1536)).to_pandas()
|
||||
```
|
||||
|
||||
While other formats like Arrow/Pydantic/Python dicts have a natural
|
||||
way to handle nested schemas, pandas can only store nested data as a
|
||||
python dict column, which makes it difficult to support nested references.
|
||||
So for convenience, you can also tell LanceDB to flatten a nested schema
|
||||
when creating the pandas dataframe.
|
||||
|
||||
```python
|
||||
tbl.search(np.random.randn(1536)).to_pandas(flatten=True)
|
||||
```
|
||||
|
||||
If your table has a deeply nested struct, you can control how many levels
|
||||
of nesting to flatten by passing in a positive integer.
|
||||
|
||||
```python
|
||||
tbl.search(np.random.randn(1536)).to_pandas(flatten=1)
|
||||
```
|
||||
|
||||
|
||||
#### As a list of python dicts
|
||||
|
||||
You can of course return results as a list of python dicts.
|
||||
|
||||
```python
|
||||
tbl.search(np.random.randn(1536)).to_list()
|
||||
```
|
||||
|
||||
#### As a list of pydantic models
|
||||
|
||||
We can add data using pydantic models, and we can certainly
|
||||
retrieve results as pydantic models
|
||||
|
||||
```python
|
||||
tbl.search(np.random.randn(1536)).to_pydantic(LanceSchema)
|
||||
```
|
||||
|
||||
Note that in this case the extra `_distance` field is discarded since
|
||||
it's not part of the LanceSchema.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# SQL filters
|
||||
|
||||
LanceDB embraces the utilization of standard SQL expressions as predicates for hybrid
|
||||
filters. It can be used during hybrid vector search and deletion operations.
|
||||
filters. It can be used during hybrid vector search, update, and deletion operations.
|
||||
|
||||
Currently, Lance supports a growing list of expressions.
|
||||
|
||||
@@ -22,7 +22,7 @@ import numpy as np
|
||||
uri = "data/sample-lancedb"
|
||||
db = lancedb.connect(uri)
|
||||
|
||||
data = [{"vector": row, "item": f"item {i}"}
|
||||
data = [{"vector": row, "item": f"item {i}", "id": i}
|
||||
for i, row in enumerate(np.random.random((10_000, 2)).astype('int'))]
|
||||
|
||||
tbl = db.create_table("my_vectors", data=data)
|
||||
@@ -35,33 +35,25 @@ const db = await vectordb.connect('data/sample-lancedb')
|
||||
|
||||
let data = []
|
||||
for (let i = 0; i < 10_000; i++) {
|
||||
data.push({vector: Array(1536).fill(i), id: `${i}`, content: "", longId: `${i}`},)
|
||||
data.push({vector: Array(1536).fill(i), id: i, item: `item ${i}`, strId: `${i}`})
|
||||
}
|
||||
const tbl = await db.createTable('my_vectors', data)
|
||||
const tbl = await db.createTable('myVectors', data)
|
||||
```
|
||||
-->
|
||||
=== "Python"
|
||||
|
||||
```python
|
||||
tbl.search([100, 102]) \
|
||||
.where("""(
|
||||
(label IN [10, 20])
|
||||
AND
|
||||
(note.email IS NOT NULL)
|
||||
) OR NOT note.created
|
||||
""")
|
||||
|
||||
.where("(item IN ('item 0', 'item 2')) AND (id > 10)") \
|
||||
.to_arrow()
|
||||
```
|
||||
|
||||
=== "Javascript"
|
||||
|
||||
```javascript
|
||||
tbl.search([100, 102])
|
||||
.where(`(
|
||||
(label IN [10, 20])
|
||||
AND
|
||||
(note.email IS NOT NULL)
|
||||
) OR NOT note.created
|
||||
`)
|
||||
await tbl.search(Array(1536).fill(0))
|
||||
.where("(item IN ('item 0', 'item 2')) AND (id > 10)")
|
||||
.execute()
|
||||
```
|
||||
|
||||
|
||||
@@ -118,3 +110,22 @@ The mapping from SQL types to Arrow types is:
|
||||
|
||||
[^1]: See precision mapping in previous table.
|
||||
|
||||
|
||||
## Filtering without Vector Search
|
||||
|
||||
You can also filter your data without search.
|
||||
|
||||
=== "Python"
|
||||
```python
|
||||
tbl.search().where("id=10").limit(10).to_arrow()
|
||||
```
|
||||
|
||||
=== "JavaScript"
|
||||
```javascript
|
||||
await tbl.where('id=10').limit(10).execute()
|
||||
```
|
||||
|
||||
!!! warning
|
||||
If your table is large, this could potentially return a very large
|
||||
amount of data. Please be sure to use a `limit` clause unless
|
||||
you're sure you want to return the whole result set.
|
||||
|
||||
@@ -9,8 +9,13 @@ npm install vectordb
|
||||
```
|
||||
|
||||
This will download the appropriate native library for your platform. We currently
|
||||
support x86_64 Linux, aarch64 Linux, Intel MacOS, and ARM (M1/M2) MacOS. We do not
|
||||
yet support musl-based Linux (such as Alpine Linux).
|
||||
support:
|
||||
|
||||
* Linux (x86_64 and aarch64)
|
||||
* MacOS (Intel and ARM/M1/M2)
|
||||
* Windows (x86_64 only)
|
||||
|
||||
We do not yet support musl-based Linux (such as Alpine Linux) or aarch64 Windows.
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
624
node/package-lock.json
generated
624
node/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "vectordb",
|
||||
"version": "0.3.8",
|
||||
"version": "0.4.3",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "vectordb",
|
||||
"version": "0.3.8",
|
||||
"version": "0.4.3",
|
||||
"cpu": [
|
||||
"x64",
|
||||
"arm64"
|
||||
@@ -18,9 +18,9 @@
|
||||
"win32"
|
||||
],
|
||||
"dependencies": {
|
||||
"@apache-arrow/ts": "^12.0.0",
|
||||
"@apache-arrow/ts": "^14.0.2",
|
||||
"@neon-rs/load": "^0.0.74",
|
||||
"apache-arrow": "^12.0.0",
|
||||
"apache-arrow": "^14.0.2",
|
||||
"axios": "^1.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -53,39 +53,59 @@
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@lancedb/vectordb-darwin-arm64": "0.3.8",
|
||||
"@lancedb/vectordb-darwin-x64": "0.3.8",
|
||||
"@lancedb/vectordb-linux-arm64-gnu": "0.3.8",
|
||||
"@lancedb/vectordb-linux-x64-gnu": "0.3.8",
|
||||
"@lancedb/vectordb-win32-x64-msvc": "0.3.8"
|
||||
"@lancedb/vectordb-darwin-arm64": "0.4.3",
|
||||
"@lancedb/vectordb-darwin-x64": "0.4.3",
|
||||
"@lancedb/vectordb-linux-arm64-gnu": "0.4.3",
|
||||
"@lancedb/vectordb-linux-x64-gnu": "0.4.3",
|
||||
"@lancedb/vectordb-win32-x64-msvc": "0.4.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@75lb/deep-merge": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.1.tgz",
|
||||
"integrity": "sha512-xvgv6pkMGBA6GwdyJbNAnDmfAIR/DfWhrj9jgWh3TY7gRm3KO46x/GPjRg6wJ0nOepwqrNxFfojebh0Df4h4Tw==",
|
||||
"dependencies": {
|
||||
"lodash.assignwith": "^4.2.0",
|
||||
"typical": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.17"
|
||||
}
|
||||
},
|
||||
"node_modules/@75lb/deep-merge/node_modules/typical": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz",
|
||||
"integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==",
|
||||
"engines": {
|
||||
"node": ">=12.17"
|
||||
}
|
||||
},
|
||||
"node_modules/@apache-arrow/ts": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@apache-arrow/ts/-/ts-12.0.0.tgz",
|
||||
"integrity": "sha512-ArJ3Fw5W9RAeNWuyCU2CdjL/nEAZSVDG1p3jz/ZtLo/q3NTz2w7HUCOJeszejH/5alGX+QirYrJ5c6BW++/P7g==",
|
||||
"version": "14.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@apache-arrow/ts/-/ts-14.0.2.tgz",
|
||||
"integrity": "sha512-CtwAvLkK0CZv7xsYeCo91ml6PvlfzAmAJZkRYuz2GNBwfYufj5SVi0iuSMwIMkcU/szVwvLdzORSLa5PlF/2ug==",
|
||||
"dependencies": {
|
||||
"@types/command-line-args": "5.2.0",
|
||||
"@types/command-line-usage": "5.0.2",
|
||||
"@types/node": "18.14.5",
|
||||
"@types/node": "20.3.0",
|
||||
"@types/pad-left": "2.1.1",
|
||||
"command-line-args": "5.2.1",
|
||||
"command-line-usage": "6.1.3",
|
||||
"flatbuffers": "23.3.3",
|
||||
"command-line-usage": "7.0.1",
|
||||
"flatbuffers": "23.5.26",
|
||||
"json-bignum": "^0.0.3",
|
||||
"pad-left": "^2.1.0",
|
||||
"tslib": "^2.5.0"
|
||||
"tslib": "^2.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@apache-arrow/ts/node_modules/@types/node": {
|
||||
"version": "18.14.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.5.tgz",
|
||||
"integrity": "sha512-CRT4tMK/DHYhw1fcCEBwME9CSaZNclxfzVMe7GsO6ULSwsttbj70wSiX6rZdIjGblu93sTJxLdhNIT85KKI7Qw=="
|
||||
"version": "20.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.0.tgz",
|
||||
"integrity": "sha512-cumHmIAf6On83X7yP+LrsEyUOf/YlociZelmpRYaGFydoaPdxdt80MAbu6vWerQT2COCp2nPvHdsbD7tHn/YlQ=="
|
||||
},
|
||||
"node_modules/@apache-arrow/ts/node_modules/tslib": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
|
||||
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"node_modules/@cargo-messages/android-arm-eabi": {
|
||||
"version": "0.0.160",
|
||||
@@ -316,6 +336,66 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@lancedb/vectordb-darwin-arm64": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-darwin-arm64/-/vectordb-darwin-arm64-0.4.3.tgz",
|
||||
"integrity": "sha512-47CvvSaV1EdUsFEpXUJApTk+hMzAhCxVizipCFUlXCgcmzpCDL86wNgJij/X9a+j6zADhIX//Lsu0qd/an/Bpw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@lancedb/vectordb-darwin-x64": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-darwin-x64/-/vectordb-darwin-x64-0.4.3.tgz",
|
||||
"integrity": "sha512-UlZZv8CmJIuRJNJG+Y1VmFsGyPR8W/72Q5EwgMMsSES6zpMQ9pNdBDWhL3UGX6nMRgnbprkwYiWJ3xHhJvtqtw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@lancedb/vectordb-linux-arm64-gnu": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-linux-arm64-gnu/-/vectordb-linux-arm64-gnu-0.4.3.tgz",
|
||||
"integrity": "sha512-L6NVJr/lKEd8+904FzZNpT8BGQMs2cHNYbGJMIaVvGnMiIJgKAFKtOyGtdDjoe1xRZoEw21yjRGksGbnRO5wHQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@lancedb/vectordb-linux-x64-gnu": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-linux-x64-gnu/-/vectordb-linux-x64-gnu-0.4.3.tgz",
|
||||
"integrity": "sha512-OBx3WF3pK0xNfFJeErmuD9R2QWLa3XdeZspyTsIrQmBDeKj3HKh8y7Scpx4NH5Y09+9JNqRRKRZN7OqWTYhITg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@lancedb/vectordb-win32-x64-msvc": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-win32-x64-msvc/-/vectordb-win32-x64-msvc-0.4.3.tgz",
|
||||
"integrity": "sha512-n9IvR81NXZKnSN91mrgeXbEyCiGM+YLJpOgbdHoEtMP04VDnS+iSU4jGOtQBKErvWeCJQaGFQ9qzdcVchpRGyw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@neon-rs/cli": {
|
||||
"version": "0.0.160",
|
||||
"resolved": "https://registry.npmjs.org/@neon-rs/cli/-/cli-0.0.160.tgz",
|
||||
@@ -806,7 +886,6 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
@@ -831,34 +910,34 @@
|
||||
}
|
||||
},
|
||||
"node_modules/apache-arrow": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-12.0.0.tgz",
|
||||
"integrity": "sha512-uI+hnZZsGfNJiR/wG8j5yPQuDjmOHx4hZpkA743G4x3TlFrCpA3MMX7KUkIOIw0e/CwZ8NYuaMzaQsblA47qVA==",
|
||||
"version": "14.0.2",
|
||||
"resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-14.0.2.tgz",
|
||||
"integrity": "sha512-EBO2xJN36/XoY81nhLcwCJgFwkboDZeyNQ+OPsG7bCoQjc2BT0aTyH/MR6SrL+LirSNz+cYqjGRlupMMlP1aEg==",
|
||||
"dependencies": {
|
||||
"@types/command-line-args": "5.2.0",
|
||||
"@types/command-line-usage": "5.0.2",
|
||||
"@types/node": "18.14.5",
|
||||
"@types/node": "20.3.0",
|
||||
"@types/pad-left": "2.1.1",
|
||||
"command-line-args": "5.2.1",
|
||||
"command-line-usage": "6.1.3",
|
||||
"flatbuffers": "23.3.3",
|
||||
"command-line-usage": "7.0.1",
|
||||
"flatbuffers": "23.5.26",
|
||||
"json-bignum": "^0.0.3",
|
||||
"pad-left": "^2.1.0",
|
||||
"tslib": "^2.5.0"
|
||||
"tslib": "^2.5.3"
|
||||
},
|
||||
"bin": {
|
||||
"arrow2csv": "bin/arrow2csv.js"
|
||||
}
|
||||
},
|
||||
"node_modules/apache-arrow/node_modules/@types/node": {
|
||||
"version": "18.14.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.5.tgz",
|
||||
"integrity": "sha512-CRT4tMK/DHYhw1fcCEBwME9CSaZNclxfzVMe7GsO6ULSwsttbj70wSiX6rZdIjGblu93sTJxLdhNIT85KKI7Qw=="
|
||||
"version": "20.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.0.tgz",
|
||||
"integrity": "sha512-cumHmIAf6On83X7yP+LrsEyUOf/YlociZelmpRYaGFydoaPdxdt80MAbu6vWerQT2COCp2nPvHdsbD7tHn/YlQ=="
|
||||
},
|
||||
"node_modules/apache-arrow/node_modules/tslib": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
|
||||
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "4.1.3",
|
||||
@@ -1110,7 +1189,6 @@
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
@@ -1122,11 +1200,24 @@
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk-template": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz",
|
||||
"integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==",
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk-template?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk/node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
@@ -1185,7 +1276,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
@@ -1196,8 +1286,7 @@
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
@@ -1225,97 +1314,33 @@
|
||||
}
|
||||
},
|
||||
"node_modules/command-line-usage": {
|
||||
"version": "6.1.3",
|
||||
"resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz",
|
||||
"integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.1.tgz",
|
||||
"integrity": "sha512-NCyznE//MuTjwi3y84QVUGEOT+P5oto1e1Pk/jFPVdPPfsG03qpTIl3yw6etR+v73d0lXsoojRpvbru2sqePxQ==",
|
||||
"dependencies": {
|
||||
"array-back": "^4.0.2",
|
||||
"chalk": "^2.4.2",
|
||||
"table-layout": "^1.0.2",
|
||||
"typical": "^5.2.0"
|
||||
"array-back": "^6.2.2",
|
||||
"chalk-template": "^0.4.0",
|
||||
"table-layout": "^3.0.0",
|
||||
"typical": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/command-line-usage/node_modules/ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dependencies": {
|
||||
"color-convert": "^1.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
"node": ">=12.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/command-line-usage/node_modules/array-back": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
|
||||
"integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz",
|
||||
"integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/command-line-usage/node_modules/chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/command-line-usage/node_modules/color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dependencies": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/command-line-usage/node_modules/color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
|
||||
},
|
||||
"node_modules/command-line-usage/node_modules/escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/command-line-usage/node_modules/has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/command-line-usage/node_modules/supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dependencies": {
|
||||
"has-flag": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
"node": ">=12.17"
|
||||
}
|
||||
},
|
||||
"node_modules/command-line-usage/node_modules/typical": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
|
||||
"integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz",
|
||||
"integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
"node": ">=12.17"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
@@ -1391,14 +1416,6 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/deep-extend": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/deep-is": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||
@@ -2177,9 +2194,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/flatbuffers": {
|
||||
"version": "23.3.3",
|
||||
"resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-23.3.3.tgz",
|
||||
"integrity": "sha512-jmreOaAT1t55keaf+Z259Tvh8tR/Srry9K8dgCgvizhKSEr6gLGgaOJI2WFL5fkOpGOGRZwxUrlFn0GCmXUy6g=="
|
||||
"version": "23.5.26",
|
||||
"resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-23.5.26.tgz",
|
||||
"integrity": "sha512-vE+SI9vrJDwi1oETtTIFldC/o9GsVKRM+s6EL0nQgxXlYV1Vc4Tk30hj4xGICftInKQKj1F3up2n8UbIVobISQ=="
|
||||
},
|
||||
"node_modules/flatted": {
|
||||
"version": "3.2.7",
|
||||
@@ -2475,7 +2492,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -2988,6 +3004,11 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash.assignwith": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz",
|
||||
"integrity": "sha512-ZznplvbvtjK2gMvnQ1BR/zqPFZmS6jbK4p+6Up4xcRYA7yMIwxHCfbTcrYxXKzzqLsQ05eJPVznEW3tuwV7k1g=="
|
||||
},
|
||||
"node_modules/lodash.camelcase": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||
@@ -3608,14 +3629,6 @@
|
||||
"node": ">=8.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/reduce-flatten": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz",
|
||||
"integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/regexp.prototype.flags": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz",
|
||||
@@ -3905,6 +3918,14 @@
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/stream-read-all": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/stream-read-all/-/stream-read-all-3.0.1.tgz",
|
||||
"integrity": "sha512-EWZT9XOceBPlVJRrYcykW8jyRSZYbkb/0ZK36uLEmoWVO5gxBOnntNTseNzfREsqxqdfEGQrD8SXQ3QWbBmq8A==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
@@ -4022,33 +4043,39 @@
|
||||
}
|
||||
},
|
||||
"node_modules/table-layout": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz",
|
||||
"integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==",
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/table-layout/-/table-layout-3.0.2.tgz",
|
||||
"integrity": "sha512-rpyNZYRw+/C+dYkcQ3Pr+rLxW4CfHpXjPDnG7lYhdRoUcZTUt+KEsX+94RGp/aVp/MQU35JCITv2T/beY4m+hw==",
|
||||
"dependencies": {
|
||||
"array-back": "^4.0.1",
|
||||
"deep-extend": "~0.6.0",
|
||||
"typical": "^5.2.0",
|
||||
"wordwrapjs": "^4.0.0"
|
||||
"@75lb/deep-merge": "^1.1.1",
|
||||
"array-back": "^6.2.2",
|
||||
"command-line-args": "^5.2.1",
|
||||
"command-line-usage": "^7.0.0",
|
||||
"stream-read-all": "^3.0.1",
|
||||
"typical": "^7.1.1",
|
||||
"wordwrapjs": "^5.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"table-layout": "bin/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
"node": ">=12.17"
|
||||
}
|
||||
},
|
||||
"node_modules/table-layout/node_modules/array-back": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
|
||||
"integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz",
|
||||
"integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
"node": ">=12.17"
|
||||
}
|
||||
},
|
||||
"node_modules/table-layout/node_modules/typical": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
|
||||
"integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz",
|
||||
"integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
"node": ">=12.17"
|
||||
}
|
||||
},
|
||||
"node_modules/temp": {
|
||||
@@ -4493,23 +4520,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/wordwrapjs": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz",
|
||||
"integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==",
|
||||
"dependencies": {
|
||||
"reduce-flatten": "^2.0.0",
|
||||
"typical": "^5.2.0"
|
||||
},
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.0.tgz",
|
||||
"integrity": "sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg==",
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wordwrapjs/node_modules/typical": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
|
||||
"integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
"node": ">=12.17"
|
||||
}
|
||||
},
|
||||
"node_modules/workerpool": {
|
||||
@@ -4630,32 +4645,48 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@75lb/deep-merge": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.1.tgz",
|
||||
"integrity": "sha512-xvgv6pkMGBA6GwdyJbNAnDmfAIR/DfWhrj9jgWh3TY7gRm3KO46x/GPjRg6wJ0nOepwqrNxFfojebh0Df4h4Tw==",
|
||||
"requires": {
|
||||
"lodash.assignwith": "^4.2.0",
|
||||
"typical": "^7.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"typical": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz",
|
||||
"integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"@apache-arrow/ts": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@apache-arrow/ts/-/ts-12.0.0.tgz",
|
||||
"integrity": "sha512-ArJ3Fw5W9RAeNWuyCU2CdjL/nEAZSVDG1p3jz/ZtLo/q3NTz2w7HUCOJeszejH/5alGX+QirYrJ5c6BW++/P7g==",
|
||||
"version": "14.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@apache-arrow/ts/-/ts-14.0.2.tgz",
|
||||
"integrity": "sha512-CtwAvLkK0CZv7xsYeCo91ml6PvlfzAmAJZkRYuz2GNBwfYufj5SVi0iuSMwIMkcU/szVwvLdzORSLa5PlF/2ug==",
|
||||
"requires": {
|
||||
"@types/command-line-args": "5.2.0",
|
||||
"@types/command-line-usage": "5.0.2",
|
||||
"@types/node": "18.14.5",
|
||||
"@types/node": "20.3.0",
|
||||
"@types/pad-left": "2.1.1",
|
||||
"command-line-args": "5.2.1",
|
||||
"command-line-usage": "6.1.3",
|
||||
"flatbuffers": "23.3.3",
|
||||
"command-line-usage": "7.0.1",
|
||||
"flatbuffers": "23.5.26",
|
||||
"json-bignum": "^0.0.3",
|
||||
"pad-left": "^2.1.0",
|
||||
"tslib": "^2.5.0"
|
||||
"tslib": "^2.5.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "18.14.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.5.tgz",
|
||||
"integrity": "sha512-CRT4tMK/DHYhw1fcCEBwME9CSaZNclxfzVMe7GsO6ULSwsttbj70wSiX6rZdIjGblu93sTJxLdhNIT85KKI7Qw=="
|
||||
"version": "20.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.0.tgz",
|
||||
"integrity": "sha512-cumHmIAf6On83X7yP+LrsEyUOf/YlociZelmpRYaGFydoaPdxdt80MAbu6vWerQT2COCp2nPvHdsbD7tHn/YlQ=="
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
|
||||
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4808,6 +4839,36 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"@lancedb/vectordb-darwin-arm64": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-darwin-arm64/-/vectordb-darwin-arm64-0.4.3.tgz",
|
||||
"integrity": "sha512-47CvvSaV1EdUsFEpXUJApTk+hMzAhCxVizipCFUlXCgcmzpCDL86wNgJij/X9a+j6zADhIX//Lsu0qd/an/Bpw==",
|
||||
"optional": true
|
||||
},
|
||||
"@lancedb/vectordb-darwin-x64": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-darwin-x64/-/vectordb-darwin-x64-0.4.3.tgz",
|
||||
"integrity": "sha512-UlZZv8CmJIuRJNJG+Y1VmFsGyPR8W/72Q5EwgMMsSES6zpMQ9pNdBDWhL3UGX6nMRgnbprkwYiWJ3xHhJvtqtw==",
|
||||
"optional": true
|
||||
},
|
||||
"@lancedb/vectordb-linux-arm64-gnu": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-linux-arm64-gnu/-/vectordb-linux-arm64-gnu-0.4.3.tgz",
|
||||
"integrity": "sha512-L6NVJr/lKEd8+904FzZNpT8BGQMs2cHNYbGJMIaVvGnMiIJgKAFKtOyGtdDjoe1xRZoEw21yjRGksGbnRO5wHQ==",
|
||||
"optional": true
|
||||
},
|
||||
"@lancedb/vectordb-linux-x64-gnu": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-linux-x64-gnu/-/vectordb-linux-x64-gnu-0.4.3.tgz",
|
||||
"integrity": "sha512-OBx3WF3pK0xNfFJeErmuD9R2QWLa3XdeZspyTsIrQmBDeKj3HKh8y7Scpx4NH5Y09+9JNqRRKRZN7OqWTYhITg==",
|
||||
"optional": true
|
||||
},
|
||||
"@lancedb/vectordb-win32-x64-msvc": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@lancedb/vectordb-win32-x64-msvc/-/vectordb-win32-x64-msvc-0.4.3.tgz",
|
||||
"integrity": "sha512-n9IvR81NXZKnSN91mrgeXbEyCiGM+YLJpOgbdHoEtMP04VDnS+iSU4jGOtQBKErvWeCJQaGFQ9qzdcVchpRGyw==",
|
||||
"optional": true
|
||||
},
|
||||
"@neon-rs/cli": {
|
||||
"version": "0.0.160",
|
||||
"resolved": "https://registry.npmjs.org/@neon-rs/cli/-/cli-0.0.160.tgz",
|
||||
@@ -5178,7 +5239,6 @@
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
@@ -5194,31 +5254,31 @@
|
||||
}
|
||||
},
|
||||
"apache-arrow": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-12.0.0.tgz",
|
||||
"integrity": "sha512-uI+hnZZsGfNJiR/wG8j5yPQuDjmOHx4hZpkA743G4x3TlFrCpA3MMX7KUkIOIw0e/CwZ8NYuaMzaQsblA47qVA==",
|
||||
"version": "14.0.2",
|
||||
"resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-14.0.2.tgz",
|
||||
"integrity": "sha512-EBO2xJN36/XoY81nhLcwCJgFwkboDZeyNQ+OPsG7bCoQjc2BT0aTyH/MR6SrL+LirSNz+cYqjGRlupMMlP1aEg==",
|
||||
"requires": {
|
||||
"@types/command-line-args": "5.2.0",
|
||||
"@types/command-line-usage": "5.0.2",
|
||||
"@types/node": "18.14.5",
|
||||
"@types/node": "20.3.0",
|
||||
"@types/pad-left": "2.1.1",
|
||||
"command-line-args": "5.2.1",
|
||||
"command-line-usage": "6.1.3",
|
||||
"flatbuffers": "23.3.3",
|
||||
"command-line-usage": "7.0.1",
|
||||
"flatbuffers": "23.5.26",
|
||||
"json-bignum": "^0.0.3",
|
||||
"pad-left": "^2.1.0",
|
||||
"tslib": "^2.5.0"
|
||||
"tslib": "^2.5.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "18.14.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.5.tgz",
|
||||
"integrity": "sha512-CRT4tMK/DHYhw1fcCEBwME9CSaZNclxfzVMe7GsO6ULSwsttbj70wSiX6rZdIjGblu93sTJxLdhNIT85KKI7Qw=="
|
||||
"version": "20.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.0.tgz",
|
||||
"integrity": "sha512-cumHmIAf6On83X7yP+LrsEyUOf/YlociZelmpRYaGFydoaPdxdt80MAbu6vWerQT2COCp2nPvHdsbD7tHn/YlQ=="
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
|
||||
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
|
||||
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -5415,7 +5475,6 @@
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
@@ -5425,13 +5484,20 @@
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"chalk-template": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz",
|
||||
"integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==",
|
||||
"requires": {
|
||||
"chalk": "^4.1.2"
|
||||
}
|
||||
},
|
||||
"check-error": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
|
||||
@@ -5469,7 +5535,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
@@ -5477,8 +5542,7 @@
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
@@ -5500,74 +5564,25 @@
|
||||
}
|
||||
},
|
||||
"command-line-usage": {
|
||||
"version": "6.1.3",
|
||||
"resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.3.tgz",
|
||||
"integrity": "sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.1.tgz",
|
||||
"integrity": "sha512-NCyznE//MuTjwi3y84QVUGEOT+P5oto1e1Pk/jFPVdPPfsG03qpTIl3yw6etR+v73d0lXsoojRpvbru2sqePxQ==",
|
||||
"requires": {
|
||||
"array-back": "^4.0.2",
|
||||
"chalk": "^2.4.2",
|
||||
"table-layout": "^1.0.2",
|
||||
"typical": "^5.2.0"
|
||||
"array-back": "^6.2.2",
|
||||
"chalk-template": "^0.4.0",
|
||||
"table-layout": "^3.0.0",
|
||||
"typical": "^7.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"array-back": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
|
||||
"integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg=="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz",
|
||||
"integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw=="
|
||||
},
|
||||
"typical": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
|
||||
"integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg=="
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz",
|
||||
"integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -5626,11 +5641,6 @@
|
||||
"type-detect": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"deep-extend": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
|
||||
},
|
||||
"deep-is": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||
@@ -6207,9 +6217,9 @@
|
||||
}
|
||||
},
|
||||
"flatbuffers": {
|
||||
"version": "23.3.3",
|
||||
"resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-23.3.3.tgz",
|
||||
"integrity": "sha512-jmreOaAT1t55keaf+Z259Tvh8tR/Srry9K8dgCgvizhKSEr6gLGgaOJI2WFL5fkOpGOGRZwxUrlFn0GCmXUy6g=="
|
||||
"version": "23.5.26",
|
||||
"resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-23.5.26.tgz",
|
||||
"integrity": "sha512-vE+SI9vrJDwi1oETtTIFldC/o9GsVKRM+s6EL0nQgxXlYV1Vc4Tk30hj4xGICftInKQKj1F3up2n8UbIVobISQ=="
|
||||
},
|
||||
"flatted": {
|
||||
"version": "3.2.7",
|
||||
@@ -6412,8 +6422,7 @@
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||
},
|
||||
"has-property-descriptors": {
|
||||
"version": "1.0.0",
|
||||
@@ -6766,6 +6775,11 @@
|
||||
"p-locate": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"lodash.assignwith": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz",
|
||||
"integrity": "sha512-ZznplvbvtjK2gMvnQ1BR/zqPFZmS6jbK4p+6Up4xcRYA7yMIwxHCfbTcrYxXKzzqLsQ05eJPVznEW3tuwV7k1g=="
|
||||
},
|
||||
"lodash.camelcase": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||
@@ -7233,11 +7247,6 @@
|
||||
"picomatch": "^2.2.1"
|
||||
}
|
||||
},
|
||||
"reduce-flatten": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz",
|
||||
"integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w=="
|
||||
},
|
||||
"regexp.prototype.flags": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz",
|
||||
@@ -7433,6 +7442,11 @@
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"stream-read-all": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/stream-read-all/-/stream-read-all-3.0.1.tgz",
|
||||
"integrity": "sha512-EWZT9XOceBPlVJRrYcykW8jyRSZYbkb/0ZK36uLEmoWVO5gxBOnntNTseNzfREsqxqdfEGQrD8SXQ3QWbBmq8A=="
|
||||
},
|
||||
"string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
@@ -7514,25 +7528,28 @@
|
||||
"dev": true
|
||||
},
|
||||
"table-layout": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz",
|
||||
"integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==",
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/table-layout/-/table-layout-3.0.2.tgz",
|
||||
"integrity": "sha512-rpyNZYRw+/C+dYkcQ3Pr+rLxW4CfHpXjPDnG7lYhdRoUcZTUt+KEsX+94RGp/aVp/MQU35JCITv2T/beY4m+hw==",
|
||||
"requires": {
|
||||
"array-back": "^4.0.1",
|
||||
"deep-extend": "~0.6.0",
|
||||
"typical": "^5.2.0",
|
||||
"wordwrapjs": "^4.0.0"
|
||||
"@75lb/deep-merge": "^1.1.1",
|
||||
"array-back": "^6.2.2",
|
||||
"command-line-args": "^5.2.1",
|
||||
"command-line-usage": "^7.0.0",
|
||||
"stream-read-all": "^3.0.1",
|
||||
"typical": "^7.1.1",
|
||||
"wordwrapjs": "^5.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"array-back": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
|
||||
"integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg=="
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz",
|
||||
"integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw=="
|
||||
},
|
||||
"typical": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
|
||||
"integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg=="
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/typical/-/typical-7.1.1.tgz",
|
||||
"integrity": "sha512-T+tKVNs6Wu7IWiAce5BgMd7OZfNYUndHwc5MknN+UHOudi7sGZzuHdCadllRuqJ3fPtgFtIH9+lt9qRv6lmpfA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -7850,20 +7867,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"wordwrapjs": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz",
|
||||
"integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==",
|
||||
"requires": {
|
||||
"reduce-flatten": "^2.0.0",
|
||||
"typical": "^5.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"typical": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
|
||||
"integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg=="
|
||||
}
|
||||
}
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.0.tgz",
|
||||
"integrity": "sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg=="
|
||||
},
|
||||
"workerpool": {
|
||||
"version": "6.2.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vectordb",
|
||||
"version": "0.3.8",
|
||||
"version": "0.4.3",
|
||||
"description": " Serverless, low-latency vector database for AI applications",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
@@ -57,9 +57,9 @@
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apache-arrow/ts": "^12.0.0",
|
||||
"@apache-arrow/ts": "^14.0.2",
|
||||
"@neon-rs/load": "^0.0.74",
|
||||
"apache-arrow": "^12.0.0",
|
||||
"apache-arrow": "^14.0.2",
|
||||
"axios": "^1.4.0"
|
||||
},
|
||||
"os": [
|
||||
@@ -81,10 +81,10 @@
|
||||
}
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@lancedb/vectordb-darwin-arm64": "0.3.8",
|
||||
"@lancedb/vectordb-darwin-x64": "0.3.8",
|
||||
"@lancedb/vectordb-linux-arm64-gnu": "0.3.8",
|
||||
"@lancedb/vectordb-linux-x64-gnu": "0.3.8",
|
||||
"@lancedb/vectordb-win32-x64-msvc": "0.3.8"
|
||||
"@lancedb/vectordb-darwin-arm64": "0.4.3",
|
||||
"@lancedb/vectordb-darwin-x64": "0.4.3",
|
||||
"@lancedb/vectordb-linux-arm64-gnu": "0.4.3",
|
||||
"@lancedb/vectordb-linux-x64-gnu": "0.4.3",
|
||||
"@lancedb/vectordb-win32-x64-msvc": "0.4.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,9 @@ import {
|
||||
Float32,
|
||||
makeBuilder,
|
||||
RecordBatchFileWriter,
|
||||
Utf8,
|
||||
type Vector,
|
||||
Utf8, type Vector,
|
||||
FixedSizeList,
|
||||
vectorFromArray, type Schema, Table as ArrowTable, RecordBatchStreamWriter
|
||||
vectorFromArray, type Schema, Table as ArrowTable, RecordBatchStreamWriter, List, Float64, RecordBatch, makeData, Struct
|
||||
} from 'apache-arrow'
|
||||
import { type EmbeddingFunction } from './index'
|
||||
|
||||
@@ -59,7 +58,26 @@ export async function convertToTable<T> (data: Array<Record<string, unknown>>, e
|
||||
if (typeof values[0] === 'string') {
|
||||
// `vectorFromArray` converts strings into dictionary vectors, forcing it back to a string column
|
||||
records[columnsKey] = vectorFromArray(values, new Utf8())
|
||||
} else if (Array.isArray(values[0])) {
|
||||
const elementType = getElementType(values[0])
|
||||
let innerType
|
||||
if (elementType === 'string') {
|
||||
innerType = new Utf8()
|
||||
} else if (elementType === 'number') {
|
||||
innerType = new Float64()
|
||||
} else {
|
||||
// TODO: pass in schema if it exists, else keep going to the next element
|
||||
throw new Error(`Unsupported array element type ${elementType}`)
|
||||
}
|
||||
const listBuilder = makeBuilder({
|
||||
type: new List(new Field('item', innerType, true))
|
||||
})
|
||||
for (const value of values) {
|
||||
listBuilder.append(value)
|
||||
}
|
||||
records[columnsKey] = listBuilder.finish().toVector()
|
||||
} else {
|
||||
// TODO if this is a struct field then recursively align the subfields
|
||||
records[columnsKey] = vectorFromArray(values)
|
||||
}
|
||||
}
|
||||
@@ -68,6 +86,14 @@ export async function convertToTable<T> (data: Array<Record<string, unknown>>, e
|
||||
return new ArrowTable(records)
|
||||
}
|
||||
|
||||
function getElementType (arr: any[]): string {
|
||||
if (arr.length === 0) {
|
||||
return 'undefined'
|
||||
}
|
||||
|
||||
return typeof arr[0]
|
||||
}
|
||||
|
||||
// Creates a new Arrow ListBuilder that stores a Vector column
|
||||
function newVectorBuilder (dim: number): FixedSizeListBuilder<Float32> {
|
||||
return makeBuilder({
|
||||
@@ -84,21 +110,27 @@ function newVectorType (dim: number): FixedSizeList<Float32> {
|
||||
}
|
||||
|
||||
// Converts an Array of records into Arrow IPC format
|
||||
export async function fromRecordsToBuffer<T> (data: Array<Record<string, unknown>>, embeddings?: EmbeddingFunction<T>): Promise<Buffer> {
|
||||
const table = await convertToTable(data, embeddings)
|
||||
export async function fromRecordsToBuffer<T> (data: Array<Record<string, unknown>>, embeddings?: EmbeddingFunction<T>, schema?: Schema): Promise<Buffer> {
|
||||
let table = await convertToTable(data, embeddings)
|
||||
if (schema !== undefined) {
|
||||
table = alignTable(table, schema)
|
||||
}
|
||||
const writer = RecordBatchFileWriter.writeAll(table)
|
||||
return Buffer.from(await writer.toUint8Array())
|
||||
}
|
||||
|
||||
// Converts an Array of records into Arrow IPC stream format
|
||||
export async function fromRecordsToStreamBuffer<T> (data: Array<Record<string, unknown>>, embeddings?: EmbeddingFunction<T>): Promise<Buffer> {
|
||||
const table = await convertToTable(data, embeddings)
|
||||
export async function fromRecordsToStreamBuffer<T> (data: Array<Record<string, unknown>>, embeddings?: EmbeddingFunction<T>, schema?: Schema): Promise<Buffer> {
|
||||
let table = await convertToTable(data, embeddings)
|
||||
if (schema !== undefined) {
|
||||
table = alignTable(table, schema)
|
||||
}
|
||||
const writer = RecordBatchStreamWriter.writeAll(table)
|
||||
return Buffer.from(await writer.toUint8Array())
|
||||
}
|
||||
|
||||
// Converts an Arrow Table into Arrow IPC format
|
||||
export async function fromTableToBuffer<T> (table: ArrowTable, embeddings?: EmbeddingFunction<T>): Promise<Buffer> {
|
||||
export async function fromTableToBuffer<T> (table: ArrowTable, embeddings?: EmbeddingFunction<T>, schema?: Schema): Promise<Buffer> {
|
||||
if (embeddings !== undefined) {
|
||||
const source = table.getChild(embeddings.sourceColumn)
|
||||
|
||||
@@ -110,12 +142,15 @@ export async function fromTableToBuffer<T> (table: ArrowTable, embeddings?: Embe
|
||||
const column = vectorFromArray(vectors, newVectorType(vectors[0].length))
|
||||
table = table.assign(new ArrowTable({ vector: column }))
|
||||
}
|
||||
if (schema !== undefined) {
|
||||
table = alignTable(table, schema)
|
||||
}
|
||||
const writer = RecordBatchFileWriter.writeAll(table)
|
||||
return Buffer.from(await writer.toUint8Array())
|
||||
}
|
||||
|
||||
// Converts an Arrow Table into Arrow IPC stream format
|
||||
export async function fromTableToStreamBuffer<T> (table: ArrowTable, embeddings?: EmbeddingFunction<T>): Promise<Buffer> {
|
||||
export async function fromTableToStreamBuffer<T> (table: ArrowTable, embeddings?: EmbeddingFunction<T>, schema?: Schema): Promise<Buffer> {
|
||||
if (embeddings !== undefined) {
|
||||
const source = table.getChild(embeddings.sourceColumn)
|
||||
|
||||
@@ -127,10 +162,36 @@ export async function fromTableToStreamBuffer<T> (table: ArrowTable, embeddings?
|
||||
const column = vectorFromArray(vectors, newVectorType(vectors[0].length))
|
||||
table = table.assign(new ArrowTable({ vector: column }))
|
||||
}
|
||||
if (schema !== undefined) {
|
||||
table = alignTable(table, schema)
|
||||
}
|
||||
const writer = RecordBatchStreamWriter.writeAll(table)
|
||||
return Buffer.from(await writer.toUint8Array())
|
||||
}
|
||||
|
||||
function alignBatch (batch: RecordBatch, schema: Schema): RecordBatch {
|
||||
const alignedChildren = []
|
||||
for (const field of schema.fields) {
|
||||
const indexInBatch = batch.schema.fields?.findIndex((f) => f.name === field.name)
|
||||
if (indexInBatch < 0) {
|
||||
throw new Error(`The column ${field.name} was not found in the Arrow Table`)
|
||||
}
|
||||
alignedChildren.push(batch.data.children[indexInBatch])
|
||||
}
|
||||
const newData = makeData({
|
||||
type: new Struct(schema.fields),
|
||||
length: batch.numRows,
|
||||
nullCount: batch.nullCount,
|
||||
children: alignedChildren
|
||||
})
|
||||
return new RecordBatch(schema, newData)
|
||||
}
|
||||
|
||||
function alignTable (table: ArrowTable, schema: Schema): ArrowTable {
|
||||
const alignedBatches = table.batches.map(batch => alignBatch(batch, schema))
|
||||
return new ArrowTable(schema, alignedBatches)
|
||||
}
|
||||
|
||||
// Creates an empty Arrow Table
|
||||
export function createEmptyTable (schema: Schema): ArrowTable {
|
||||
return new ArrowTable(schema)
|
||||
|
||||
@@ -14,16 +14,18 @@
|
||||
|
||||
import {
|
||||
type Schema,
|
||||
Table as ArrowTable
|
||||
Table as ArrowTable,
|
||||
tableFromIPC
|
||||
} from 'apache-arrow'
|
||||
import { createEmptyTable, fromRecordsToBuffer, fromTableToBuffer } from './arrow'
|
||||
import type { EmbeddingFunction } from './embedding/embedding_function'
|
||||
import { RemoteConnection } from './remote'
|
||||
import { Query } from './query'
|
||||
import { isEmbeddingFunction } from './embedding/embedding_function'
|
||||
import { type Literal, toSQL } from './util'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { databaseNew, databaseTableNames, databaseOpenTable, databaseDropTable, tableCreate, tableAdd, tableCreateVectorIndex, tableCountRows, tableDelete, tableCleanupOldVersions, tableCompactFiles, tableListIndices, tableIndexStats } = require('../native.js')
|
||||
const { databaseNew, databaseTableNames, databaseOpenTable, databaseDropTable, tableCreate, tableAdd, tableCreateScalarIndex, tableCreateVectorIndex, tableCountRows, tableDelete, tableUpdate, tableCleanupOldVersions, tableCompactFiles, tableListIndices, tableIndexStats, tableSchema } = require('../native.js')
|
||||
|
||||
export { Query }
|
||||
export type { EmbeddingFunction }
|
||||
@@ -222,6 +224,56 @@ export interface Table<T = number[]> {
|
||||
*/
|
||||
createIndex: (indexParams: VectorIndexParams) => Promise<any>
|
||||
|
||||
/**
|
||||
* Create a scalar index on this Table for the given column
|
||||
*
|
||||
* @param column The column to index
|
||||
* @param replace If false, fail if an index already exists on the column
|
||||
*
|
||||
* Scalar indices, like vector indices, can be used to speed up scans. A scalar
|
||||
* index can speed up scans that contain filter expressions on the indexed column.
|
||||
* For example, the following scan will be faster if the column `my_col` has
|
||||
* a scalar index:
|
||||
*
|
||||
* ```ts
|
||||
* const con = await lancedb.connect('./.lancedb');
|
||||
* const table = await con.openTable('images');
|
||||
* const results = await table.where('my_col = 7').execute();
|
||||
* ```
|
||||
*
|
||||
* Scalar indices can also speed up scans containing a vector search and a
|
||||
* prefilter:
|
||||
*
|
||||
* ```ts
|
||||
* const con = await lancedb.connect('././lancedb');
|
||||
* const table = await con.openTable('images');
|
||||
* const results = await table.search([1.0, 2.0]).where('my_col != 7').prefilter(true);
|
||||
* ```
|
||||
*
|
||||
* Scalar indices can only speed up scans for basic filters using
|
||||
* equality, comparison, range (e.g. `my_col BETWEEN 0 AND 100`), and set
|
||||
* membership (e.g. `my_col IN (0, 1, 2)`)
|
||||
*
|
||||
* Scalar indices can be used if the filter contains multiple indexed columns and
|
||||
* the filter criteria are AND'd or OR'd together
|
||||
* (e.g. `my_col < 0 AND other_col> 100`)
|
||||
*
|
||||
* Scalar indices may be used if the filter contains non-indexed columns but,
|
||||
* depending on the structure of the filter, they may not be usable. For example,
|
||||
* if the column `not_indexed` does not have a scalar index then the filter
|
||||
* `my_col = 0 OR not_indexed = 1` will not be able to use any scalar index on
|
||||
* `my_col`.
|
||||
*
|
||||
* @examples
|
||||
*
|
||||
* ```ts
|
||||
* const con = await lancedb.connect('././lancedb')
|
||||
* const table = await con.openTable('images')
|
||||
* await table.createScalarIndex('my_col')
|
||||
* ```
|
||||
*/
|
||||
createScalarIndex: (column: string, replace: boolean) => Promise<void>
|
||||
|
||||
/**
|
||||
* Returns the number of rows in this table.
|
||||
*/
|
||||
@@ -261,6 +313,39 @@ export interface Table<T = number[]> {
|
||||
*/
|
||||
delete: (filter: string) => Promise<void>
|
||||
|
||||
/**
|
||||
* Update rows in this table.
|
||||
*
|
||||
* This can be used to update a single row, many rows, all rows, or
|
||||
* sometimes no rows (if your predicate matches nothing).
|
||||
*
|
||||
* @param args see {@link UpdateArgs} and {@link UpdateSqlArgs} for more details
|
||||
*
|
||||
* @examples
|
||||
*
|
||||
* ```ts
|
||||
* const con = await lancedb.connect("./.lancedb")
|
||||
* const data = [
|
||||
* {id: 1, vector: [3, 3], name: 'Ye'},
|
||||
* {id: 2, vector: [4, 4], name: 'Mike'},
|
||||
* ];
|
||||
* const tbl = await con.createTable("my_table", data)
|
||||
*
|
||||
* await tbl.update({
|
||||
* where: "id = 2",
|
||||
* values: { vector: [2, 2], name: "Michael" },
|
||||
* })
|
||||
*
|
||||
* let results = await tbl.search([1, 1]).execute();
|
||||
* // Returns [
|
||||
* // {id: 2, vector: [2, 2], name: 'Michael'}
|
||||
* // {id: 1, vector: [3, 3], name: 'Ye'}
|
||||
* // ]
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
update: (args: UpdateArgs | UpdateSqlArgs) => Promise<void>
|
||||
|
||||
/**
|
||||
* List the indicies on this table.
|
||||
*/
|
||||
@@ -270,6 +355,36 @@ export interface Table<T = number[]> {
|
||||
* Get statistics about an index.
|
||||
*/
|
||||
indexStats: (indexUuid: string) => Promise<IndexStats>
|
||||
|
||||
schema: Promise<Schema>
|
||||
}
|
||||
|
||||
export interface UpdateArgs {
|
||||
/**
|
||||
* A filter in the same format used by a sql WHERE clause. The filter may be empty,
|
||||
* in which case all rows will be updated.
|
||||
*/
|
||||
where?: string
|
||||
|
||||
/**
|
||||
* A key-value map of updates. The keys are the column names, and the values are the
|
||||
* new values to set
|
||||
*/
|
||||
values: Record<string, Literal>
|
||||
}
|
||||
|
||||
export interface UpdateSqlArgs {
|
||||
/**
|
||||
* A filter in the same format used by a sql WHERE clause. The filter may be empty,
|
||||
* in which case all rows will be updated.
|
||||
*/
|
||||
where?: string
|
||||
|
||||
/**
|
||||
* A key-value map of updates. The keys are the column names, and the values are the
|
||||
* new values to set as SQL expressions.
|
||||
*/
|
||||
valuesSql: Record<string, string>
|
||||
}
|
||||
|
||||
export interface VectorIndex {
|
||||
@@ -370,10 +485,10 @@ export class LocalConnection implements Connection {
|
||||
}
|
||||
buffer = await fromTableToBuffer(createEmptyTable(schema))
|
||||
} else if (data instanceof ArrowTable) {
|
||||
buffer = await fromTableToBuffer(data, embeddingFunction)
|
||||
buffer = await fromTableToBuffer(data, embeddingFunction, schema)
|
||||
} else {
|
||||
// data is Array<Record<...>>
|
||||
buffer = await fromRecordsToBuffer(data, embeddingFunction)
|
||||
buffer = await fromRecordsToBuffer(data, embeddingFunction, schema)
|
||||
}
|
||||
|
||||
const tbl = await tableCreate.call(this._db, name, buffer, writeOptions?.writeMode?.toString(), ...getAwsArgs(this._options()))
|
||||
@@ -396,6 +511,7 @@ export class LocalConnection implements Connection {
|
||||
export class LocalTable<T = number[]> implements Table<T> {
|
||||
private _tbl: any
|
||||
private readonly _name: string
|
||||
private readonly _isElectron: boolean
|
||||
private readonly _embeddings?: EmbeddingFunction<T>
|
||||
private readonly _options: () => ConnectionOptions
|
||||
|
||||
@@ -412,6 +528,7 @@ export class LocalTable<T = number[]> implements Table<T> {
|
||||
this._name = name
|
||||
this._embeddings = embeddings
|
||||
this._options = () => options
|
||||
this._isElectron = this.checkElectron()
|
||||
}
|
||||
|
||||
get name (): string {
|
||||
@@ -426,6 +543,16 @@ export class LocalTable<T = number[]> implements Table<T> {
|
||||
return new Query(query, this._tbl, this._embeddings)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a filter query to find all rows matching the specified criteria
|
||||
* @param value The filter criteria (like SQL where clause syntax)
|
||||
*/
|
||||
filter (value: string): Query<T> {
|
||||
return new Query(undefined, this._tbl, this._embeddings).filter(value)
|
||||
}
|
||||
|
||||
where = this.filter
|
||||
|
||||
/**
|
||||
* Insert records into this Table.
|
||||
*
|
||||
@@ -433,9 +560,10 @@ export class LocalTable<T = number[]> implements Table<T> {
|
||||
* @return The number of rows added to the table
|
||||
*/
|
||||
async add (data: Array<Record<string, unknown>>): Promise<number> {
|
||||
const schema = await this.schema
|
||||
return tableAdd.call(
|
||||
this._tbl,
|
||||
await fromRecordsToBuffer(data, this._embeddings),
|
||||
await fromRecordsToBuffer(data, this._embeddings, schema),
|
||||
WriteMode.Append.toString(),
|
||||
...getAwsArgs(this._options())
|
||||
).then((newTable: any) => { this._tbl = newTable })
|
||||
@@ -465,6 +593,10 @@ export class LocalTable<T = number[]> implements Table<T> {
|
||||
return tableCreateVectorIndex.call(this._tbl, indexParams).then((newTable: any) => { this._tbl = newTable })
|
||||
}
|
||||
|
||||
async createScalarIndex (column: string, replace: boolean): Promise<void> {
|
||||
return tableCreateScalarIndex.call(this._tbl, column, replace)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of rows in this table.
|
||||
*/
|
||||
@@ -481,6 +613,31 @@ export class LocalTable<T = number[]> implements Table<T> {
|
||||
return tableDelete.call(this._tbl, filter).then((newTable: any) => { this._tbl = newTable })
|
||||
}
|
||||
|
||||
/**
|
||||
* Update rows in this table.
|
||||
*
|
||||
* @param args see {@link UpdateArgs} and {@link UpdateSqlArgs} for more details
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
async update (args: UpdateArgs | UpdateSqlArgs): Promise<void> {
|
||||
let filter: string | null
|
||||
let updates: Record<string, string>
|
||||
|
||||
if ('valuesSql' in args) {
|
||||
filter = args.where ?? null
|
||||
updates = args.valuesSql
|
||||
} else {
|
||||
filter = args.where ?? null
|
||||
updates = {}
|
||||
for (const [key, value] of Object.entries(args.values)) {
|
||||
updates[key] = toSQL(value)
|
||||
}
|
||||
}
|
||||
|
||||
return tableUpdate.call(this._tbl, filter, updates).then((newTable: any) => { this._tbl = newTable })
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up old versions of the table, freeing disk space.
|
||||
*
|
||||
@@ -531,6 +688,27 @@ export class LocalTable<T = number[]> implements Table<T> {
|
||||
async indexStats (indexUuid: string): Promise<IndexStats> {
|
||||
return tableIndexStats.call(this._tbl, indexUuid)
|
||||
}
|
||||
|
||||
get schema (): Promise<Schema> {
|
||||
// empty table
|
||||
return this.getSchema()
|
||||
}
|
||||
|
||||
private async getSchema (): Promise<Schema> {
|
||||
const buffer = await tableSchema.call(this._tbl, this._isElectron)
|
||||
const table = tableFromIPC(buffer)
|
||||
return table.schema
|
||||
}
|
||||
|
||||
// See https://github.com/electron/electron/issues/2288
|
||||
private checkElectron (): boolean {
|
||||
try {
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
return (process?.versions?.hasOwnProperty('electron') || navigator?.userAgent?.toLowerCase()?.includes(' electron'))
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface CleanupStats {
|
||||
@@ -647,6 +825,11 @@ export interface IvfPQIndexConfig {
|
||||
*/
|
||||
replace?: boolean
|
||||
|
||||
/**
|
||||
* Cache size of the index
|
||||
*/
|
||||
index_cache_size?: number
|
||||
|
||||
type: 'ivf_pq'
|
||||
}
|
||||
|
||||
|
||||
@@ -23,27 +23,29 @@ const { tableSearch } = require('../native.js')
|
||||
* A builder for nearest neighbor queries for LanceDB.
|
||||
*/
|
||||
export class Query<T = number[]> {
|
||||
private readonly _query: T
|
||||
private readonly _query?: T
|
||||
private readonly _tbl?: any
|
||||
private _queryVector?: number[]
|
||||
private _limit: number
|
||||
private _limit?: number
|
||||
private _refineFactor?: number
|
||||
private _nprobes: number
|
||||
private _select?: string[]
|
||||
private _filter?: string
|
||||
private _metricType?: MetricType
|
||||
private _prefilter: boolean
|
||||
protected readonly _embeddings?: EmbeddingFunction<T>
|
||||
|
||||
constructor (query: T, tbl?: any, embeddings?: EmbeddingFunction<T>) {
|
||||
constructor (query?: T, tbl?: any, embeddings?: EmbeddingFunction<T>) {
|
||||
this._tbl = tbl
|
||||
this._query = query
|
||||
this._limit = 10
|
||||
this._limit = undefined
|
||||
this._nprobes = 20
|
||||
this._refineFactor = undefined
|
||||
this._select = undefined
|
||||
this._filter = undefined
|
||||
this._metricType = undefined
|
||||
this._embeddings = embeddings
|
||||
this._prefilter = false
|
||||
}
|
||||
|
||||
/***
|
||||
@@ -102,14 +104,21 @@ export class Query<T = number[]> {
|
||||
return this
|
||||
}
|
||||
|
||||
prefilter (value: boolean): Query<T> {
|
||||
this._prefilter = value
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the query and return the results as an Array of Objects
|
||||
*/
|
||||
async execute<T = Record<string, unknown>> (): Promise<T[]> {
|
||||
if (this._embeddings !== undefined) {
|
||||
this._queryVector = (await this._embeddings.embed([this._query]))[0]
|
||||
} else {
|
||||
this._queryVector = this._query as number[]
|
||||
if (this._query !== undefined) {
|
||||
if (this._embeddings !== undefined) {
|
||||
this._queryVector = (await this._embeddings.embed([this._query]))[0]
|
||||
} else {
|
||||
this._queryVector = this._query as number[]
|
||||
}
|
||||
}
|
||||
|
||||
const isElectron = this.isElectron()
|
||||
|
||||
@@ -38,6 +38,7 @@ export class HttpLancedbClient {
|
||||
vector: number[],
|
||||
k: number,
|
||||
nprobes: number,
|
||||
prefilter: boolean,
|
||||
refineFactor?: number,
|
||||
columns?: string[],
|
||||
filter?: string
|
||||
@@ -50,7 +51,8 @@ export class HttpLancedbClient {
|
||||
nprobes,
|
||||
refineFactor,
|
||||
columns,
|
||||
filter
|
||||
filter,
|
||||
prefilter
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
|
||||
@@ -16,7 +16,8 @@ import {
|
||||
type EmbeddingFunction, type Table, type VectorIndexParams, type Connection,
|
||||
type ConnectionOptions, type CreateTableOptions, type VectorIndex,
|
||||
type WriteOptions,
|
||||
type IndexStats
|
||||
type IndexStats,
|
||||
type UpdateArgs, type UpdateSqlArgs
|
||||
} from '../index'
|
||||
import { Query } from '../query'
|
||||
|
||||
@@ -24,6 +25,7 @@ import { Vector, Table as ArrowTable } from 'apache-arrow'
|
||||
import { HttpLancedbClient } from './client'
|
||||
import { isEmbeddingFunction } from '../embedding/embedding_function'
|
||||
import { createEmptyTable, fromRecordsToStreamBuffer, fromTableToStreamBuffer } from '../arrow'
|
||||
import { toSQL } from '../util'
|
||||
|
||||
/**
|
||||
* Remote connection.
|
||||
@@ -55,8 +57,8 @@ export class RemoteConnection implements Connection {
|
||||
return 'db://' + this._client.uri
|
||||
}
|
||||
|
||||
async tableNames (): Promise<string[]> {
|
||||
const response = await this._client.get('/v1/table/')
|
||||
async tableNames (pageToken: string = '', limit: number = 10): Promise<string[]> {
|
||||
const response = await this._client.get('/v1/table/', { limit, page_token: pageToken })
|
||||
return response.data.tables
|
||||
}
|
||||
|
||||
@@ -154,6 +156,7 @@ export class RemoteQuery<T = number[]> extends Query<T> {
|
||||
queryVector,
|
||||
(this as any)._limit,
|
||||
(this as any)._nprobes,
|
||||
(this as any)._prefilter,
|
||||
(this as any)._refineFactor,
|
||||
(this as any)._select,
|
||||
(this as any)._filter
|
||||
@@ -192,6 +195,17 @@ export class RemoteTable<T = number[]> implements Table<T> {
|
||||
return this._name
|
||||
}
|
||||
|
||||
get schema (): Promise<any> {
|
||||
return this._client.post(`/v1/table/${this._name}/describe/`).then(res => {
|
||||
if (res.status !== 200) {
|
||||
throw new Error(`Server Error, status: ${res.status}, ` +
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
`message: ${res.statusText}: ${res.data}`)
|
||||
}
|
||||
return res.data?.schema
|
||||
})
|
||||
}
|
||||
|
||||
search (query: T): Query<T> {
|
||||
return new RemoteQuery(query, this._client, this._name)//, this._embeddings_new)
|
||||
}
|
||||
@@ -232,7 +246,44 @@ export class RemoteTable<T = number[]> implements Table<T> {
|
||||
return data.length
|
||||
}
|
||||
|
||||
async createIndex (indexParams: VectorIndexParams): Promise<any> {
|
||||
async createIndex (indexParams: VectorIndexParams): Promise<void> {
|
||||
const unsupportedParams = [
|
||||
'index_name',
|
||||
'num_partitions',
|
||||
'max_iters',
|
||||
'use_opq',
|
||||
'num_sub_vectors',
|
||||
'num_bits',
|
||||
'max_opq_iters',
|
||||
'replace'
|
||||
]
|
||||
for (const param of unsupportedParams) {
|
||||
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
||||
if (indexParams[param as keyof VectorIndexParams]) {
|
||||
throw new Error(`${param} is not supported for remote connections`)
|
||||
}
|
||||
}
|
||||
|
||||
const column = indexParams.column ?? 'vector'
|
||||
const indexType = 'vector' // only vector index is supported for remote connections
|
||||
const metricType = indexParams.metric_type ?? 'L2'
|
||||
const indexCacheSize = indexParams.index_cache_size ?? null
|
||||
|
||||
const data = {
|
||||
column,
|
||||
index_type: indexType,
|
||||
metric_type: metricType,
|
||||
index_cache_size: indexCacheSize
|
||||
}
|
||||
const res = await this._client.post(`/v1/table/${this._name}/create_index/`, data)
|
||||
if (res.status !== 200) {
|
||||
throw new Error(`Server Error, status: ${res.status}, ` +
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
`message: ${res.statusText}: ${res.data}`)
|
||||
}
|
||||
}
|
||||
|
||||
async createScalarIndex (column: string, replace: boolean): Promise<void> {
|
||||
throw new Error('Not implemented')
|
||||
}
|
||||
|
||||
@@ -245,6 +296,26 @@ export class RemoteTable<T = number[]> implements Table<T> {
|
||||
await this._client.post(`/v1/table/${this._name}/delete/`, { predicate: filter })
|
||||
}
|
||||
|
||||
async update (args: UpdateArgs | UpdateSqlArgs): Promise<void> {
|
||||
let filter: string | null
|
||||
let updates: Record<string, string>
|
||||
|
||||
if ('valuesSql' in args) {
|
||||
filter = args.where ?? null
|
||||
updates = args.valuesSql
|
||||
} else {
|
||||
filter = args.where ?? null
|
||||
updates = {}
|
||||
for (const [key, value] of Object.entries(args.values)) {
|
||||
updates[key] = toSQL(value)
|
||||
}
|
||||
}
|
||||
await this._client.post(`/v1/table/${this._name}/update/`, {
|
||||
predicate: filter,
|
||||
updates: Object.entries(updates).map(([key, value]) => [key, value])
|
||||
})
|
||||
}
|
||||
|
||||
async listIndices (): Promise<VectorIndex[]> {
|
||||
const results = await this._client.post(`/v1/table/${this._name}/index/list/`)
|
||||
return results.data.indexes?.map((index: any) => ({
|
||||
|
||||
@@ -78,12 +78,31 @@ describe('LanceDB client', function () {
|
||||
})
|
||||
|
||||
it('limits # of results', async function () {
|
||||
const uri = await createTestDB()
|
||||
const uri = await createTestDB(2, 100)
|
||||
const con = await lancedb.connect(uri)
|
||||
const table = await con.openTable('vectors')
|
||||
const results = await table.search([0.1, 0.3]).limit(1).execute()
|
||||
let results = await table.search([0.1, 0.3]).limit(1).execute()
|
||||
assert.equal(results.length, 1)
|
||||
assert.equal(results[0].id, 1)
|
||||
|
||||
// there is a default limit if unspecified
|
||||
results = await table.search([0.1, 0.3]).execute()
|
||||
assert.equal(results.length, 10)
|
||||
})
|
||||
|
||||
it('uses a filter / where clause without vector search', async function () {
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
const assertResults = (results: Array<Record<string, unknown>>) => {
|
||||
assert.equal(results.length, 50)
|
||||
}
|
||||
|
||||
const uri = await createTestDB(2, 100)
|
||||
const con = await lancedb.connect(uri)
|
||||
const table = (await con.openTable('vectors')) as LocalTable
|
||||
let results = await table.filter('id % 2 = 0').execute()
|
||||
assertResults(results)
|
||||
results = await table.where('id % 2 = 0').execute()
|
||||
assertResults(results)
|
||||
})
|
||||
|
||||
it('uses a filter / where clause', async function () {
|
||||
@@ -102,6 +121,31 @@ describe('LanceDB client', function () {
|
||||
assertResults(results)
|
||||
})
|
||||
|
||||
it('should correctly process prefilter/postfilter', async function () {
|
||||
const uri = await createTestDB(16, 300)
|
||||
const con = await lancedb.connect(uri)
|
||||
const table = await con.openTable('vectors')
|
||||
await table.createIndex({ type: 'ivf_pq', column: 'vector', num_partitions: 2, max_iters: 2, num_sub_vectors: 2 })
|
||||
// post filter should return less than the limit
|
||||
let results = await table.search(new Array(16).fill(0.1)).limit(10).filter('id >= 10').prefilter(false).execute()
|
||||
assert.isTrue(results.length < 10)
|
||||
|
||||
// pre filter should return exactly the limit
|
||||
results = await table.search(new Array(16).fill(0.1)).limit(10).filter('id >= 10').prefilter(true).execute()
|
||||
assert.isTrue(results.length === 10)
|
||||
})
|
||||
|
||||
it('should allow creation and use of scalar indices', async function () {
|
||||
const uri = await createTestDB(16, 300)
|
||||
const con = await lancedb.connect(uri)
|
||||
const table = await con.openTable('vectors')
|
||||
await table.createScalarIndex('id', true)
|
||||
|
||||
// Prefiltering should still work the same
|
||||
const results = await table.search(new Array(16).fill(0.1)).limit(10).filter('id >= 10').prefilter(true).execute()
|
||||
assert.isTrue(results.length === 10)
|
||||
})
|
||||
|
||||
it('select only a subset of columns', async function () {
|
||||
const uri = await createTestDB()
|
||||
const con = await lancedb.connect(uri)
|
||||
@@ -132,6 +176,26 @@ describe('LanceDB client', function () {
|
||||
assert.deepEqual(await con.tableNames(), ['vectors'])
|
||||
})
|
||||
|
||||
it('create a table with a schema and records', async function () {
|
||||
const dir = await track().mkdir('lancejs')
|
||||
const con = await lancedb.connect(dir)
|
||||
|
||||
const schema = new Schema(
|
||||
[new Field('id', new Int32()),
|
||||
new Field('name', new Utf8()),
|
||||
new Field('vector', new FixedSizeList(2, new Field('item', new Float32(), true)), false)
|
||||
]
|
||||
)
|
||||
const data = [
|
||||
{ vector: [0.5, 0.2], name: 'foo', id: 0 },
|
||||
{ vector: [0.3, 0.1], name: 'bar', id: 1 }
|
||||
]
|
||||
// even thought the keys in data is out of order it should still work
|
||||
const table = await con.createTable({ name: 'vectors', data, schema })
|
||||
assert.equal(table.name, 'vectors')
|
||||
assert.deepEqual(await con.tableNames(), ['vectors'])
|
||||
})
|
||||
|
||||
it('create a table with a empty data array', async function () {
|
||||
const dir = await track().mkdir('lancejs')
|
||||
const con = await lancedb.connect(dir)
|
||||
@@ -174,6 +238,25 @@ describe('LanceDB client', function () {
|
||||
assert.equal(await table.countRows(), 2)
|
||||
})
|
||||
|
||||
it('creates a new table from javascript objects with variable sized list', async function () {
|
||||
const dir = await track().mkdir('lancejs')
|
||||
const con = await lancedb.connect(dir)
|
||||
|
||||
const data = [
|
||||
{ id: 1, vector: [0.1, 0.2], list_of_str: ['a', 'b', 'c'], list_of_num: [1, 2, 3] },
|
||||
{ id: 2, vector: [1.1, 1.2], list_of_str: ['x', 'y'], list_of_num: [4, 5, 6] }
|
||||
]
|
||||
|
||||
const tableName = 'with_variable_sized_list'
|
||||
const table = await con.createTable(tableName, data) as LocalTable
|
||||
assert.equal(table.name, tableName)
|
||||
assert.equal(await table.countRows(), 2)
|
||||
const rs = await table.filter('id>1').execute()
|
||||
assert.equal(rs.length, 1)
|
||||
assert.deepEqual(rs[0].list_of_str, ['x', 'y'])
|
||||
assert.isTrue(rs[0].list_of_num instanceof Float64Array)
|
||||
})
|
||||
|
||||
it('fails to create a new table when the vector column is missing', async function () {
|
||||
const dir = await track().mkdir('lancejs')
|
||||
const con = await lancedb.connect(dir)
|
||||
@@ -231,6 +314,25 @@ describe('LanceDB client', function () {
|
||||
assert.equal(await table.countRows(), 4)
|
||||
})
|
||||
|
||||
it('appends records with fields in a different order', async function () {
|
||||
const dir = await track().mkdir('lancejs')
|
||||
const con = await lancedb.connect(dir)
|
||||
|
||||
const data = [
|
||||
{ id: 1, vector: [0.1, 0.2], price: 10, name: 'a' },
|
||||
{ id: 2, vector: [1.1, 1.2], price: 50, name: 'b' }
|
||||
]
|
||||
|
||||
const table = await con.createTable('vectors', data)
|
||||
|
||||
const dataAdd = [
|
||||
{ id: 3, vector: [2.1, 2.2], name: 'c', price: 10 },
|
||||
{ id: 4, vector: [3.1, 3.2], name: 'd', price: 50 }
|
||||
]
|
||||
await table.add(dataAdd)
|
||||
assert.equal(await table.countRows(), 4)
|
||||
})
|
||||
|
||||
it('overwrite all records in a table', async function () {
|
||||
const uri = await createTestDB()
|
||||
const con = await lancedb.connect(uri)
|
||||
@@ -246,6 +348,46 @@ describe('LanceDB client', function () {
|
||||
assert.equal(await table.countRows(), 2)
|
||||
})
|
||||
|
||||
it('can update records in the table', async function () {
|
||||
const uri = await createTestDB()
|
||||
const con = await lancedb.connect(uri)
|
||||
|
||||
const table = await con.openTable('vectors')
|
||||
assert.equal(await table.countRows(), 2)
|
||||
|
||||
await table.update({ where: 'price = 10', valuesSql: { price: '100' } })
|
||||
const results = await table.search([0.1, 0.2]).execute()
|
||||
assert.equal(results[0].price, 100)
|
||||
assert.equal(results[1].price, 11)
|
||||
})
|
||||
|
||||
it('can update the records using a literal value', async function () {
|
||||
const uri = await createTestDB()
|
||||
const con = await lancedb.connect(uri)
|
||||
|
||||
const table = await con.openTable('vectors')
|
||||
assert.equal(await table.countRows(), 2)
|
||||
|
||||
await table.update({ where: 'price = 10', values: { price: 100 } })
|
||||
const results = await table.search([0.1, 0.2]).execute()
|
||||
assert.equal(results[0].price, 100)
|
||||
assert.equal(results[1].price, 11)
|
||||
})
|
||||
|
||||
it('can update every record in the table', async function () {
|
||||
const uri = await createTestDB()
|
||||
const con = await lancedb.connect(uri)
|
||||
|
||||
const table = await con.openTable('vectors')
|
||||
assert.equal(await table.countRows(), 2)
|
||||
|
||||
await table.update({ valuesSql: { price: '100' } })
|
||||
const results = await table.search([0.1, 0.2]).execute()
|
||||
|
||||
assert.equal(results[0].price, 100)
|
||||
assert.equal(results[1].price, 100)
|
||||
})
|
||||
|
||||
it('can delete records from a table', async function () {
|
||||
const uri = await createTestDB()
|
||||
const con = await lancedb.connect(uri)
|
||||
@@ -395,6 +537,27 @@ describe('LanceDB client', function () {
|
||||
assert.equal(results.length, 2)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when inspecting the schema', function () {
|
||||
it('should return the schema', async function () {
|
||||
const uri = await createTestDB()
|
||||
const db = await lancedb.connect(uri)
|
||||
// the fsl inner field must be named 'item' and be nullable
|
||||
const expectedSchema = new Schema(
|
||||
[
|
||||
new Field('id', new Int32()),
|
||||
new Field('vector', new FixedSizeList(128, new Field('item', new Float32(), true))),
|
||||
new Field('s', new Utf8())
|
||||
]
|
||||
)
|
||||
const table = await db.createTable({
|
||||
name: 'some_table',
|
||||
schema: expectedSchema
|
||||
})
|
||||
const schema = await table.schema
|
||||
assert.deepEqual(expectedSchema, schema)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Remote LanceDB client', function () {
|
||||
@@ -528,7 +691,7 @@ describe('Compact and cleanup', function () {
|
||||
|
||||
// should have no effect, but this validates the arguments are parsed.
|
||||
await table.compactFiles({
|
||||
targetRowsPerFragment: 1024 * 10,
|
||||
targetRowsPerFragment: 102410,
|
||||
maxRowsPerGroup: 1024,
|
||||
materializeDeletions: true,
|
||||
materializeDeletionsThreshold: 0.5,
|
||||
|
||||
45
node/src/test/util.ts
Normal file
45
node/src/test/util.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2023 LanceDB 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.
|
||||
|
||||
import { toSQL } from '../util'
|
||||
import * as chai from 'chai'
|
||||
|
||||
const expect = chai.expect
|
||||
|
||||
describe('toSQL', function () {
|
||||
it('should turn string to SQL expression', function () {
|
||||
expect(toSQL('foo')).to.equal("'foo'")
|
||||
})
|
||||
|
||||
it('should turn number to SQL expression', function () {
|
||||
expect(toSQL(123)).to.equal('123')
|
||||
})
|
||||
|
||||
it('should turn boolean to SQL expression', function () {
|
||||
expect(toSQL(true)).to.equal('TRUE')
|
||||
})
|
||||
|
||||
it('should turn null to SQL expression', function () {
|
||||
expect(toSQL(null)).to.equal('NULL')
|
||||
})
|
||||
|
||||
it('should turn Date to SQL expression', function () {
|
||||
const date = new Date('05 October 2011 14:48 UTC')
|
||||
expect(toSQL(date)).to.equal("'2011-10-05T14:48:00.000Z'")
|
||||
})
|
||||
|
||||
it('should turn array to SQL expression', function () {
|
||||
expect(toSQL(['foo', 'bar', true, 1])).to.equal("['foo', 'bar', TRUE, 1]")
|
||||
})
|
||||
})
|
||||
44
node/src/util.ts
Normal file
44
node/src/util.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright 2023 LanceDB 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.
|
||||
|
||||
export type Literal = string | number | boolean | null | Date | Literal[]
|
||||
|
||||
export function toSQL (value: Literal): string {
|
||||
if (typeof value === 'string') {
|
||||
return `'${value}'`
|
||||
}
|
||||
|
||||
if (typeof value === 'number') {
|
||||
return value.toString()
|
||||
}
|
||||
|
||||
if (typeof value === 'boolean') {
|
||||
return value ? 'TRUE' : 'FALSE'
|
||||
}
|
||||
|
||||
if (value === null) {
|
||||
return 'NULL'
|
||||
}
|
||||
|
||||
if (value instanceof Date) {
|
||||
return `'${value.toISOString()}'`
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
return `[${value.map(toSQL).join(', ')}]`
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
throw new Error(`Unsupported value type: ${typeof value} value: (${value})`)
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
[bumpversion]
|
||||
current_version = 0.3.4
|
||||
current_version = 0.5.0
|
||||
commit = True
|
||||
message = [python] Bump version: {current_version} → {new_version}
|
||||
tag = True
|
||||
|
||||
@@ -45,8 +45,8 @@ pytest
|
||||
To run linter and automatically fix all errors:
|
||||
|
||||
```bash
|
||||
black .
|
||||
isort .
|
||||
ruff format python
|
||||
ruff --fix python
|
||||
```
|
||||
|
||||
If any packages are missing, install them with:
|
||||
@@ -82,4 +82,4 @@ pip install tantivy
|
||||
To run the unit tests:
|
||||
```bash
|
||||
pytest
|
||||
```
|
||||
```
|
||||
|
||||
@@ -27,7 +27,7 @@ def connect(
|
||||
uri: URI,
|
||||
*,
|
||||
api_key: Optional[str] = None,
|
||||
region: str = "us-west-2",
|
||||
region: str = "us-east-1",
|
||||
host_override: Optional[str] = None,
|
||||
) -> DBConnection:
|
||||
"""Connect to a LanceDB database.
|
||||
@@ -39,7 +39,7 @@ def connect(
|
||||
api_key: str, optional
|
||||
If presented, connect to LanceDB cloud.
|
||||
Otherwise, connect to a database on file system or cloud storage.
|
||||
region: str, default "us-west-2"
|
||||
region: str, default "us-east-1"
|
||||
The region to use for LanceDB Cloud.
|
||||
host_override: str, optional
|
||||
The override url for LanceDB Cloud.
|
||||
|
||||
@@ -23,7 +23,7 @@ from overrides import EnforceOverrides, override
|
||||
from pyarrow import fs
|
||||
|
||||
from .table import LanceTable, Table
|
||||
from .util import fs_from_uri, get_uri_location, get_uri_scheme
|
||||
from .util import fs_from_uri, get_uri_location, get_uri_scheme, join_uri
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .common import DATA, URI
|
||||
@@ -56,6 +56,7 @@ class DBConnection(EnforceOverrides):
|
||||
data: Optional[DATA] = None,
|
||||
schema: Optional[Union[pa.Schema, LanceModel]] = None,
|
||||
mode: str = "create",
|
||||
exist_ok: bool = False,
|
||||
on_bad_vectors: str = "error",
|
||||
fill_value: float = 0.0,
|
||||
embedding_functions: Optional[List[EmbeddingFunctionConfig]] = None,
|
||||
@@ -86,6 +87,11 @@ class DBConnection(EnforceOverrides):
|
||||
Can be either "create" or "overwrite".
|
||||
By default, if the table already exists, an exception is raised.
|
||||
If you want to overwrite the table, use mode="overwrite".
|
||||
exist_ok: bool, default False
|
||||
If a table by the same name already exists, then raise an exception
|
||||
if exist_ok=False. If exist_ok=True, then open the existing table;
|
||||
it will not add the provided data but will validate against any
|
||||
schema that's specified.
|
||||
on_bad_vectors: str, default "error"
|
||||
What to do if any of the vectors are not the same size or contains NaNs.
|
||||
One of "error", "drop", "fill".
|
||||
@@ -288,14 +294,13 @@ class LanceDBConnection(DBConnection):
|
||||
A list of table names.
|
||||
"""
|
||||
try:
|
||||
filesystem, path = fs_from_uri(self.uri)
|
||||
filesystem = fs_from_uri(self.uri)[0]
|
||||
except pa.ArrowInvalid:
|
||||
raise NotImplementedError("Unsupported scheme: " + self.uri)
|
||||
|
||||
try:
|
||||
paths = filesystem.get_file_info(
|
||||
fs.FileSelector(get_uri_location(self.uri))
|
||||
)
|
||||
loc = get_uri_location(self.uri)
|
||||
paths = filesystem.get_file_info(fs.FileSelector(loc))
|
||||
except FileNotFoundError:
|
||||
# It is ok if the file does not exist since it will be created
|
||||
paths = []
|
||||
@@ -320,6 +325,7 @@ class LanceDBConnection(DBConnection):
|
||||
data: Optional[DATA] = None,
|
||||
schema: Optional[Union[pa.Schema, LanceModel]] = None,
|
||||
mode: str = "create",
|
||||
exist_ok: bool = False,
|
||||
on_bad_vectors: str = "error",
|
||||
fill_value: float = 0.0,
|
||||
embedding_functions: Optional[List[EmbeddingFunctionConfig]] = None,
|
||||
@@ -339,6 +345,7 @@ class LanceDBConnection(DBConnection):
|
||||
data,
|
||||
schema,
|
||||
mode=mode,
|
||||
exist_ok=exist_ok,
|
||||
on_bad_vectors=on_bad_vectors,
|
||||
fill_value=fill_value,
|
||||
embedding_functions=embedding_functions,
|
||||
@@ -373,7 +380,7 @@ class LanceDBConnection(DBConnection):
|
||||
"""
|
||||
try:
|
||||
filesystem, path = fs_from_uri(self.uri)
|
||||
table_path = os.path.join(path, name + ".lance")
|
||||
table_path = join_uri(path, name + ".lance")
|
||||
filesystem.delete_dir(table_path)
|
||||
except FileNotFoundError:
|
||||
if not ignore_missing:
|
||||
|
||||
@@ -19,4 +19,5 @@ from .open_clip import OpenClipEmbeddings
|
||||
from .openai import OpenAIEmbeddings
|
||||
from .registry import EmbeddingFunctionRegistry, get_registry
|
||||
from .sentence_transformers import SentenceTransformerEmbeddings
|
||||
from .gemini_text import GeminiText
|
||||
from .utils import with_embeddings
|
||||
|
||||
131
python/lancedb/embeddings/gemini_text.py
Normal file
131
python/lancedb/embeddings/gemini_text.py
Normal file
@@ -0,0 +1,131 @@
|
||||
# Copyright (c) 2023. LanceDB 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.
|
||||
|
||||
import os
|
||||
from functools import cached_property
|
||||
from typing import List, Union, Any
|
||||
|
||||
import numpy as np
|
||||
|
||||
from .base import TextEmbeddingFunction
|
||||
from .registry import register
|
||||
from .utils import api_key_not_found_help, TEXT
|
||||
from lancedb.pydantic import PYDANTIC_VERSION
|
||||
|
||||
|
||||
@register("gemini-text")
|
||||
class GeminiText(TextEmbeddingFunction):
|
||||
"""
|
||||
An embedding function that uses the Google's Gemini API. Requires GOOGLE_API_KEY to be set.
|
||||
|
||||
https://ai.google.dev/docs/embeddings_guide
|
||||
|
||||
Supports various tasks types:
|
||||
| Task Type | Description |
|
||||
|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| "`retrieval_query`" | Specifies the given text is a query in a search/retrieval setting. |
|
||||
| "`retrieval_document`" | Specifies the given text is a document in a search/retrieval setting. Using this task type requires a title but is automatically proided by Embeddings API |
|
||||
| "`semantic_similarity`" | Specifies the given text will be used for Semantic Textual Similarity (STS). |
|
||||
| "`classification`" | Specifies that the embeddings will be used for classification. |
|
||||
| "`clusering`" | Specifies that the embeddings will be used for clustering. |
|
||||
|
||||
|
||||
Note: The supported task types might change in the Gemini API, but as long as a supported task type and its argument set is provided,
|
||||
those will be delegated to the API calls.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
name: str, default "models/embedding-001"
|
||||
The name of the model to use. See the Gemini documentation for a list of available models.
|
||||
|
||||
query_task_type: str, default "retrieval_query"
|
||||
Sets the task type for the queries.
|
||||
source_task_type: str, default "retrieval_document"
|
||||
Sets the task type for ingestion.
|
||||
|
||||
Examples
|
||||
--------
|
||||
import lancedb
|
||||
import pandas as pd
|
||||
from lancedb.pydantic import LanceModel, Vector
|
||||
from lancedb.embeddings import get_registry
|
||||
|
||||
model = get_registry().get("gemini-text").create()
|
||||
|
||||
class TextModel(LanceModel):
|
||||
text: str = model.SourceField()
|
||||
vector: Vector(model.ndims()) = model.VectorField()
|
||||
|
||||
df = pd.DataFrame({"text": ["hello world", "goodbye world"]})
|
||||
db = lancedb.connect("~/.lancedb")
|
||||
tbl = db.create_table("test", schema=TextModel, mode="overwrite")
|
||||
|
||||
tbl.add(df)
|
||||
rs = tbl.search("hello").limit(1).to_pandas()
|
||||
|
||||
"""
|
||||
|
||||
name: str = "models/embedding-001"
|
||||
query_task_type: str = "retrieval_query"
|
||||
source_task_type: str = "retrieval_document"
|
||||
|
||||
if PYDANTIC_VERSION < (2, 0): # Pydantic 1.x compat
|
||||
|
||||
class Config:
|
||||
keep_untouched = (cached_property,)
|
||||
|
||||
def ndims(self):
|
||||
# TODO: fix hardcoding
|
||||
return 768
|
||||
|
||||
def compute_query_embeddings(self, query: str, *args, **kwargs) -> List[np.array]:
|
||||
return self.compute_source_embeddings(query, task_type=self.query_task_type)
|
||||
|
||||
def compute_source_embeddings(self, texts: TEXT, *args, **kwargs) -> List[np.array]:
|
||||
texts = self.sanitize_input(texts)
|
||||
task_type = (
|
||||
kwargs.get("task_type") or self.source_task_type
|
||||
) # assume source task type if not passed by `compute_query_embeddings`
|
||||
return self.generate_embeddings(texts, task_type=task_type)
|
||||
|
||||
def generate_embeddings(
|
||||
self, texts: Union[List[str], np.ndarray], *args, **kwargs
|
||||
) -> List[np.array]:
|
||||
"""
|
||||
Get the embeddings for the given texts
|
||||
|
||||
Parameters
|
||||
----------
|
||||
texts: list[str] or np.ndarray (of str)
|
||||
The texts to embed
|
||||
"""
|
||||
if (
|
||||
kwargs.get("task_type") == "retrieval_document"
|
||||
): # Provide a title to use existing API design
|
||||
title = "Embedding of a document"
|
||||
kwargs["title"] = title
|
||||
|
||||
return [
|
||||
self.client.embed_content(model=self.name, content=text, **kwargs)[
|
||||
"embedding"
|
||||
]
|
||||
for text in texts
|
||||
]
|
||||
|
||||
@cached_property
|
||||
def client(self):
|
||||
genai = self.safe_import("google.generativeai", "google.generativeai")
|
||||
|
||||
if not os.environ.get("GOOGLE_API_KEY"):
|
||||
api_key_not_found_help("google")
|
||||
return genai
|
||||
@@ -10,12 +10,15 @@
|
||||
# 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.
|
||||
import os
|
||||
from functools import cached_property
|
||||
from typing import List, Union
|
||||
|
||||
import numpy as np
|
||||
|
||||
from .base import TextEmbeddingFunction
|
||||
from .registry import register
|
||||
from .utils import api_key_not_found_help
|
||||
|
||||
|
||||
@register("openai")
|
||||
@@ -44,6 +47,13 @@ class OpenAIEmbeddings(TextEmbeddingFunction):
|
||||
The texts to embed
|
||||
"""
|
||||
# TODO retry, rate limit, token limit
|
||||
rs = self._openai_client.embeddings.create(input=texts, model=self.name)
|
||||
return [v.embedding for v in rs.data]
|
||||
|
||||
@cached_property
|
||||
def _openai_client(self):
|
||||
openai = self.safe_import("openai")
|
||||
rs = openai.Embedding.create(input=texts, model=self.name)["data"]
|
||||
return [v["embedding"] for v in rs]
|
||||
|
||||
if not os.environ.get("OPENAI_API_KEY"):
|
||||
api_key_not_found_help("openai")
|
||||
return openai.OpenAI()
|
||||
|
||||
@@ -216,7 +216,6 @@ def retry_with_exponential_backoff(
|
||||
exponential_base: float = 2,
|
||||
jitter: bool = True,
|
||||
max_retries: int = 7,
|
||||
# errors: tuple = (),
|
||||
):
|
||||
"""Retry a function with exponential backoff.
|
||||
|
||||
@@ -226,7 +225,6 @@ def retry_with_exponential_backoff(
|
||||
exponential_base (float): The base for exponential backoff (default is 2).
|
||||
jitter (bool): Whether to add jitter to the delay (default is True).
|
||||
max_retries (int): Maximum number of retries (default is 10).
|
||||
errors (tuple): Tuple of specific exceptions to retry on (default is (openai.error.RateLimitError,)).
|
||||
|
||||
Returns:
|
||||
function: The decorated function.
|
||||
@@ -249,7 +247,7 @@ def retry_with_exponential_backoff(
|
||||
|
||||
if num_retries > max_retries:
|
||||
raise Exception(
|
||||
f"Maximum number of retries ({max_retries}) exceeded."
|
||||
f"Maximum number of retries ({max_retries}) exceeded.", e
|
||||
)
|
||||
|
||||
delay *= exponential_base * (1 + jitter * random.random())
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
"""Full text search index using tantivy-py"""
|
||||
import os
|
||||
from typing import List, Tuple
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
import pyarrow as pa
|
||||
|
||||
@@ -56,7 +56,12 @@ def create_index(index_path: str, text_fields: List[str]) -> tantivy.Index:
|
||||
return index
|
||||
|
||||
|
||||
def populate_index(index: tantivy.Index, table: LanceTable, fields: List[str]) -> int:
|
||||
def populate_index(
|
||||
index: tantivy.Index,
|
||||
table: LanceTable,
|
||||
fields: List[str],
|
||||
writer_heap_size: int = 1024 * 1024 * 1024,
|
||||
) -> int:
|
||||
"""
|
||||
Populate an index with data from a LanceTable
|
||||
|
||||
@@ -68,6 +73,8 @@ def populate_index(index: tantivy.Index, table: LanceTable, fields: List[str]) -
|
||||
The table to index
|
||||
fields : List[str]
|
||||
List of fields to index
|
||||
writer_heap_size : int
|
||||
The writer heap size in bytes, defaults to 1GB
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -75,29 +82,71 @@ def populate_index(index: tantivy.Index, table: LanceTable, fields: List[str]) -
|
||||
The number of rows indexed
|
||||
"""
|
||||
# first check the fields exist and are string or large string type
|
||||
nested = []
|
||||
for name in fields:
|
||||
f = table.schema.field(name) # raises KeyError if not found
|
||||
try:
|
||||
f = table.schema.field(name) # raises KeyError if not found
|
||||
except KeyError:
|
||||
f = resolve_path(table.schema, name)
|
||||
nested.append(name)
|
||||
|
||||
if not pa.types.is_string(f.type) and not pa.types.is_large_string(f.type):
|
||||
raise TypeError(f"Field {name} is not a string type")
|
||||
|
||||
# create a tantivy writer
|
||||
writer = index.writer()
|
||||
writer = index.writer(heap_size=writer_heap_size)
|
||||
# write data into index
|
||||
dataset = table.to_lance()
|
||||
row_id = 0
|
||||
|
||||
max_nested_level = 0
|
||||
if len(nested) > 0:
|
||||
max_nested_level = max([len(name.split(".")) for name in nested])
|
||||
|
||||
for b in dataset.to_batches(columns=fields):
|
||||
if max_nested_level > 0:
|
||||
b = pa.Table.from_batches([b])
|
||||
for _ in range(max_nested_level - 1):
|
||||
b = b.flatten()
|
||||
for i in range(b.num_rows):
|
||||
doc = tantivy.Document()
|
||||
doc.add_integer("doc_id", row_id)
|
||||
for name in fields:
|
||||
doc.add_text(name, b[name][i].as_py())
|
||||
writer.add_document(doc)
|
||||
value = b[name][i].as_py()
|
||||
if value is not None:
|
||||
doc.add_text(name, value)
|
||||
if not doc.is_empty:
|
||||
doc.add_integer("doc_id", row_id)
|
||||
writer.add_document(doc)
|
||||
row_id += 1
|
||||
# commit changes
|
||||
writer.commit()
|
||||
return row_id
|
||||
|
||||
|
||||
def resolve_path(schema, field_name: str) -> pa.Field:
|
||||
"""
|
||||
Resolve a nested field path to a list of field names
|
||||
|
||||
Parameters
|
||||
----------
|
||||
field_name : str
|
||||
The field name to resolve
|
||||
|
||||
Returns
|
||||
-------
|
||||
List[str]
|
||||
The resolved path
|
||||
"""
|
||||
path = field_name.split(".")
|
||||
field = schema.field(path.pop(0))
|
||||
for segment in path:
|
||||
if pa.types.is_struct(field.type):
|
||||
field = field.type.field(segment)
|
||||
else:
|
||||
raise KeyError(f"field {field_name} not found in schema {schema}")
|
||||
return field
|
||||
|
||||
|
||||
def search_index(
|
||||
index: tantivy.Index, query: str, limit: int = 10
|
||||
) -> Tuple[Tuple[int], Tuple[float]]:
|
||||
|
||||
@@ -26,6 +26,7 @@ import numpy as np
|
||||
import pyarrow as pa
|
||||
import pydantic
|
||||
import semver
|
||||
from pydantic.fields import FieldInfo
|
||||
|
||||
from .embeddings import EmbeddingFunctionRegistry
|
||||
|
||||
@@ -142,8 +143,8 @@ def Vector(
|
||||
return FixedSizeList
|
||||
|
||||
|
||||
def _py_type_to_arrow_type(py_type: Type[Any]) -> pa.DataType:
|
||||
"""Convert Python Type to Arrow DataType.
|
||||
def _py_type_to_arrow_type(py_type: Type[Any], field: FieldInfo) -> pa.DataType:
|
||||
"""Convert a field with native Python type to Arrow data type.
|
||||
|
||||
Raises
|
||||
------
|
||||
@@ -163,9 +164,13 @@ def _py_type_to_arrow_type(py_type: Type[Any]) -> pa.DataType:
|
||||
elif py_type == date:
|
||||
return pa.date32()
|
||||
elif py_type == datetime:
|
||||
return pa.timestamp("us")
|
||||
tz = get_extras(field, "tz")
|
||||
return pa.timestamp("us", tz=tz)
|
||||
elif getattr(py_type, "__origin__", None) in (list, tuple):
|
||||
child = py_type.__args__[0]
|
||||
return pa.list_(_py_type_to_arrow_type(child, field))
|
||||
raise TypeError(
|
||||
f"Converting Pydantic type to Arrow Type: unsupported type {py_type}"
|
||||
f"Converting Pydantic type to Arrow Type: unsupported type {py_type}."
|
||||
)
|
||||
|
||||
|
||||
@@ -187,6 +192,7 @@ else:
|
||||
|
||||
def _pydantic_to_arrow_type(field: pydantic.fields.FieldInfo) -> pa.DataType:
|
||||
"""Convert a Pydantic FieldInfo to Arrow DataType"""
|
||||
|
||||
if isinstance(field.annotation, _GenericAlias) or (
|
||||
sys.version_info > (3, 9) and isinstance(field.annotation, types.GenericAlias)
|
||||
):
|
||||
@@ -194,10 +200,17 @@ def _pydantic_to_arrow_type(field: pydantic.fields.FieldInfo) -> pa.DataType:
|
||||
args = field.annotation.__args__
|
||||
if origin == list:
|
||||
child = args[0]
|
||||
return pa.list_(_py_type_to_arrow_type(child))
|
||||
return pa.list_(_py_type_to_arrow_type(child, field))
|
||||
elif origin == Union:
|
||||
if len(args) == 2 and args[1] == type(None):
|
||||
return _py_type_to_arrow_type(args[0])
|
||||
return _py_type_to_arrow_type(args[0], field)
|
||||
elif sys.version_info >= (3, 10) and isinstance(field.annotation, types.UnionType):
|
||||
args = field.annotation.__args__
|
||||
if len(args) == 2:
|
||||
for typ in args:
|
||||
if typ == type(None):
|
||||
continue
|
||||
return _py_type_to_arrow_type(typ, field)
|
||||
elif inspect.isclass(field.annotation):
|
||||
if issubclass(field.annotation, pydantic.BaseModel):
|
||||
# Struct
|
||||
@@ -205,7 +218,7 @@ def _pydantic_to_arrow_type(field: pydantic.fields.FieldInfo) -> pa.DataType:
|
||||
return pa.struct(fields)
|
||||
elif issubclass(field.annotation, FixedSizeListMixin):
|
||||
return pa.list_(field.annotation.value_arrow_type(), field.annotation.dim())
|
||||
return _py_type_to_arrow_type(field.annotation)
|
||||
return _py_type_to_arrow_type(field.annotation, field)
|
||||
|
||||
|
||||
def is_nullable(field: pydantic.fields.FieldInfo) -> bool:
|
||||
@@ -216,6 +229,11 @@ def is_nullable(field: pydantic.fields.FieldInfo) -> bool:
|
||||
if origin == Union:
|
||||
if len(args) == 2 and args[1] == type(None):
|
||||
return True
|
||||
elif sys.version_info >= (3, 10) and isinstance(field.annotation, types.UnionType):
|
||||
args = field.annotation.__args__
|
||||
for typ in args:
|
||||
if typ == type(None):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@@ -348,3 +366,20 @@ def get_extras(field_info: pydantic.fields.FieldInfo, key: str) -> Any:
|
||||
if PYDANTIC_VERSION.major >= 2:
|
||||
return (field_info.json_schema_extra or {}).get(key)
|
||||
return (field_info.field_info.extra or {}).get("json_schema_extra", {}).get(key)
|
||||
|
||||
|
||||
if PYDANTIC_VERSION.major < 2:
|
||||
|
||||
def model_to_dict(model: pydantic.BaseModel) -> Dict[str, Any]:
|
||||
"""
|
||||
Convert a Pydantic model to a dictionary.
|
||||
"""
|
||||
return model.dict()
|
||||
|
||||
else:
|
||||
|
||||
def model_to_dict(model: pydantic.BaseModel) -> Dict[str, Any]:
|
||||
"""
|
||||
Convert a Pydantic model to a dictionary.
|
||||
"""
|
||||
return model.model_dump()
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, List, Literal, Optional, Type, Union
|
||||
|
||||
import deprecation
|
||||
@@ -70,7 +71,7 @@ class Query(pydantic.BaseModel):
|
||||
vector_column: str = VECTOR_COLUMN_NAME
|
||||
|
||||
# vector to search for
|
||||
vector: List[float]
|
||||
vector: Union[List[float], List[List[float]]]
|
||||
|
||||
# sql filter to refine the query with
|
||||
filter: Optional[str] = None
|
||||
@@ -185,14 +186,40 @@ class LanceQueryBuilder(ABC):
|
||||
"""
|
||||
return self.to_pandas()
|
||||
|
||||
def to_pandas(self) -> "pd.DataFrame":
|
||||
def to_pandas(self, flatten: Optional[Union[int, bool]] = None) -> "pd.DataFrame":
|
||||
"""
|
||||
Execute the query and return the results as a pandas DataFrame.
|
||||
In addition to the selected columns, LanceDB also returns a vector
|
||||
and also the "_distance" column which is the distance between the query
|
||||
vector and the returned vector.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
flatten: Optional[Union[int, bool]]
|
||||
If flatten is True, flatten all nested columns.
|
||||
If flatten is an integer, flatten the nested columns up to the
|
||||
specified depth.
|
||||
If unspecified, do not flatten the nested columns.
|
||||
"""
|
||||
return self.to_arrow().to_pandas()
|
||||
tbl = self.to_arrow()
|
||||
if flatten is True:
|
||||
while True:
|
||||
tbl = tbl.flatten()
|
||||
has_struct = False
|
||||
# loop through all columns to check if there is any struct column
|
||||
if any(pa.types.is_struct(col.type) for col in tbl.schema):
|
||||
continue
|
||||
else:
|
||||
break
|
||||
elif isinstance(flatten, int):
|
||||
if flatten <= 0:
|
||||
raise ValueError(
|
||||
"Please specify a positive integer for flatten or the boolean value `True`"
|
||||
)
|
||||
while flatten > 0:
|
||||
tbl = tbl.flatten()
|
||||
flatten -= 1
|
||||
return tbl.to_pandas()
|
||||
|
||||
@abstractmethod
|
||||
def to_arrow(self) -> pa.Table:
|
||||
@@ -233,20 +260,41 @@ class LanceQueryBuilder(ABC):
|
||||
for row in self.to_arrow().to_pylist()
|
||||
]
|
||||
|
||||
def limit(self, limit: int) -> LanceQueryBuilder:
|
||||
def to_polars(self) -> "pl.DataFrame":
|
||||
"""
|
||||
Execute the query and return the results as a Polars DataFrame.
|
||||
In addition to the selected columns, LanceDB also returns a vector
|
||||
and also the "_distance" column which is the distance between the query
|
||||
vector and the returned vector.
|
||||
"""
|
||||
import polars as pl
|
||||
|
||||
return pl.from_arrow(self.to_arrow())
|
||||
|
||||
def limit(self, limit: Union[int, None]) -> LanceQueryBuilder:
|
||||
"""Set the maximum number of results to return.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
limit: int
|
||||
The maximum number of results to return.
|
||||
By default the query is limited to the first 10.
|
||||
Call this method and pass 0, a negative value,
|
||||
or None to remove the limit.
|
||||
*WARNING* if you have a large dataset, removing
|
||||
the limit can potentially result in reading a
|
||||
large amount of data into memory and cause
|
||||
out of memory issues.
|
||||
|
||||
Returns
|
||||
-------
|
||||
LanceQueryBuilder
|
||||
The LanceQueryBuilder object.
|
||||
"""
|
||||
self._limit = limit
|
||||
if limit is None or limit <= 0:
|
||||
self._limit = None
|
||||
else:
|
||||
self._limit = limit
|
||||
return self
|
||||
|
||||
def select(self, columns: list) -> LanceQueryBuilder:
|
||||
@@ -395,6 +443,8 @@ class LanceVectorQueryBuilder(LanceQueryBuilder):
|
||||
vector and the returned vectors.
|
||||
"""
|
||||
vector = self._query if isinstance(self._query, list) else self._query.tolist()
|
||||
if isinstance(vector[0], np.ndarray):
|
||||
vector = [v.tolist() for v in vector]
|
||||
query = Query(
|
||||
vector=vector,
|
||||
filter=self._where,
|
||||
@@ -439,6 +489,24 @@ class LanceFtsQueryBuilder(LanceQueryBuilder):
|
||||
def __init__(self, table: "lancedb.table.Table", query: str):
|
||||
super().__init__(table)
|
||||
self._query = query
|
||||
self._phrase_query = False
|
||||
|
||||
def phrase_query(self, phrase_query: bool = True) -> LanceFtsQueryBuilder:
|
||||
"""Set whether to use phrase query.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
phrase_query: bool, default True
|
||||
If True, then the query will be wrapped in quotes and
|
||||
double quotes replaced by single quotes.
|
||||
|
||||
Returns
|
||||
-------
|
||||
LanceFtsQueryBuilder
|
||||
The LanceFtsQueryBuilder object.
|
||||
"""
|
||||
self._phrase_query = phrase_query
|
||||
return self
|
||||
|
||||
def to_arrow(self) -> pa.Table:
|
||||
try:
|
||||
@@ -452,16 +520,47 @@ class LanceFtsQueryBuilder(LanceQueryBuilder):
|
||||
|
||||
# get the index path
|
||||
index_path = self._table._get_fts_index_path()
|
||||
# check if the index exist
|
||||
if not Path(index_path).exists():
|
||||
raise FileNotFoundError(
|
||||
"Fts index does not exist."
|
||||
f"Please first call table.create_fts_index(['<field_names>']) to create the fts index."
|
||||
)
|
||||
# open the index
|
||||
index = tantivy.Index.open(index_path)
|
||||
# get the scores and doc ids
|
||||
row_ids, scores = search_index(index, self._query, self._limit)
|
||||
query = self._query
|
||||
if self._phrase_query:
|
||||
query = query.replace('"', "'")
|
||||
query = f'"{query}"'
|
||||
row_ids, scores = search_index(index, query, self._limit)
|
||||
if len(row_ids) == 0:
|
||||
empty_schema = pa.schema([pa.field("score", pa.float32())])
|
||||
return pa.Table.from_pylist([], schema=empty_schema)
|
||||
scores = pa.array(scores)
|
||||
output_tbl = self._table.to_lance().take(row_ids, columns=self._columns)
|
||||
output_tbl = output_tbl.append_column("score", scores)
|
||||
|
||||
if self._where is not None:
|
||||
try:
|
||||
# TODO would be great to have Substrait generate pyarrow compute expressions
|
||||
# or conversely have pyarrow support SQL expressions using Substrait
|
||||
import duckdb
|
||||
|
||||
output_tbl = (
|
||||
duckdb.sql(f"SELECT * FROM output_tbl")
|
||||
.filter(self._where)
|
||||
.to_arrow_table()
|
||||
)
|
||||
except ImportError:
|
||||
import lance
|
||||
import tempfile
|
||||
|
||||
# TODO Use "memory://" instead once that's supported
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
ds = lance.write_dataset(output_tbl, tmp)
|
||||
output_tbl = ds.to_table(filter=self._where)
|
||||
|
||||
return output_tbl
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ import attrs
|
||||
import pyarrow as pa
|
||||
from pydantic import BaseModel
|
||||
|
||||
from lancedb.common import VECTOR_COLUMN_NAME
|
||||
|
||||
__all__ = ["LanceDBClient", "VectorQuery", "VectorQueryResult"]
|
||||
|
||||
|
||||
@@ -43,6 +45,8 @@ class VectorQuery(BaseModel):
|
||||
|
||||
refine_factor: Optional[int] = None
|
||||
|
||||
vector_column: str = VECTOR_COLUMN_NAME
|
||||
|
||||
|
||||
@attrs.define
|
||||
class VectorQueryResult:
|
||||
|
||||
@@ -13,9 +13,10 @@
|
||||
|
||||
|
||||
import functools
|
||||
from typing import Any, Callable, Dict, Iterable, Optional, Union
|
||||
from typing import Any, Callable, Dict, Iterable, List, Optional, Union
|
||||
from urllib.parse import urljoin
|
||||
|
||||
import aiohttp
|
||||
import requests
|
||||
import attrs
|
||||
import pyarrow as pa
|
||||
from pydantic import BaseModel
|
||||
@@ -37,8 +38,8 @@ def _check_not_closed(f):
|
||||
return wrapped
|
||||
|
||||
|
||||
async def _read_ipc(resp: aiohttp.ClientResponse) -> pa.Table:
|
||||
resp_body = await resp.read()
|
||||
def _read_ipc(resp: requests.Response) -> pa.Table:
|
||||
resp_body = resp.content
|
||||
with pa.ipc.open_file(pa.BufferReader(resp_body)) as reader:
|
||||
return reader.read_all()
|
||||
|
||||
@@ -53,15 +54,18 @@ class RestfulLanceDBClient:
|
||||
closed: bool = attrs.field(default=False, init=False)
|
||||
|
||||
@functools.cached_property
|
||||
def session(self) -> aiohttp.ClientSession:
|
||||
url = (
|
||||
def session(self) -> requests.Session:
|
||||
return requests.Session()
|
||||
|
||||
@property
|
||||
def url(self) -> str:
|
||||
return (
|
||||
self.host_override
|
||||
or f"https://{self.db_name}.{self.region}.api.lancedb.com"
|
||||
)
|
||||
return aiohttp.ClientSession(url)
|
||||
|
||||
async def close(self):
|
||||
await self.session.close()
|
||||
def close(self):
|
||||
self.session.close()
|
||||
self.closed = True
|
||||
|
||||
@functools.cached_property
|
||||
@@ -76,38 +80,38 @@ class RestfulLanceDBClient:
|
||||
return headers
|
||||
|
||||
@staticmethod
|
||||
async def _check_status(resp: aiohttp.ClientResponse):
|
||||
if resp.status == 404:
|
||||
raise LanceDBClientError(f"Not found: {await resp.text()}")
|
||||
elif 400 <= resp.status < 500:
|
||||
def _check_status(resp: requests.Response):
|
||||
if resp.status_code == 404:
|
||||
raise LanceDBClientError(f"Not found: {resp.text}")
|
||||
elif 400 <= resp.status_code < 500:
|
||||
raise LanceDBClientError(
|
||||
f"Bad Request: {resp.status}, error: {await resp.text()}"
|
||||
f"Bad Request: {resp.status_code}, error: {resp.text}"
|
||||
)
|
||||
elif 500 <= resp.status < 600:
|
||||
elif 500 <= resp.status_code < 600:
|
||||
raise LanceDBClientError(
|
||||
f"Internal Server Error: {resp.status}, error: {await resp.text()}"
|
||||
f"Internal Server Error: {resp.status_code}, error: {resp.text}"
|
||||
)
|
||||
elif resp.status != 200:
|
||||
elif resp.status_code != 200:
|
||||
raise LanceDBClientError(
|
||||
f"Unknown Error: {resp.status}, error: {await resp.text()}"
|
||||
f"Unknown Error: {resp.status_code}, error: {resp.text}"
|
||||
)
|
||||
|
||||
@_check_not_closed
|
||||
async def get(self, uri: str, params: Union[Dict[str, Any], BaseModel] = None):
|
||||
def get(self, uri: str, params: Union[Dict[str, Any], BaseModel] = None):
|
||||
"""Send a GET request and returns the deserialized response payload."""
|
||||
if isinstance(params, BaseModel):
|
||||
params: Dict[str, Any] = params.dict(exclude_none=True)
|
||||
async with self.session.get(
|
||||
uri,
|
||||
with self.session.get(
|
||||
urljoin(self.url, uri),
|
||||
params=params,
|
||||
headers=self.headers,
|
||||
timeout=aiohttp.ClientTimeout(total=30),
|
||||
timeout=(5.0, 30.0),
|
||||
) as resp:
|
||||
await self._check_status(resp)
|
||||
return await resp.json()
|
||||
self._check_status(resp)
|
||||
return resp.json()
|
||||
|
||||
@_check_not_closed
|
||||
async def post(
|
||||
def post(
|
||||
self,
|
||||
uri: str,
|
||||
data: Optional[Union[Dict[str, Any], BaseModel, bytes]] = None,
|
||||
@@ -139,31 +143,26 @@ class RestfulLanceDBClient:
|
||||
headers["content-type"] = content_type
|
||||
if request_id is not None:
|
||||
headers["x-request-id"] = request_id
|
||||
async with self.session.post(
|
||||
uri,
|
||||
with self.session.post(
|
||||
urljoin(self.url, uri),
|
||||
headers=headers,
|
||||
params=params,
|
||||
timeout=aiohttp.ClientTimeout(total=30),
|
||||
timeout=(5.0, 30.0),
|
||||
**req_kwargs,
|
||||
) as resp:
|
||||
resp: aiohttp.ClientResponse = resp
|
||||
await self._check_status(resp)
|
||||
return await deserialize(resp)
|
||||
self._check_status(resp)
|
||||
return deserialize(resp)
|
||||
|
||||
@_check_not_closed
|
||||
async def list_tables(
|
||||
self, limit: int, page_token: Optional[str] = None
|
||||
) -> Iterable[str]:
|
||||
def list_tables(self, limit: int, page_token: Optional[str] = None) -> List[str]:
|
||||
"""List all tables in the database."""
|
||||
if page_token is None:
|
||||
page_token = ""
|
||||
json = await self.get("/v1/table/", {"limit": limit, "page_token": page_token})
|
||||
json = self.get("/v1/table/", {"limit": limit, "page_token": page_token})
|
||||
return json["tables"]
|
||||
|
||||
@_check_not_closed
|
||||
async def query(self, table_name: str, query: VectorQuery) -> VectorQueryResult:
|
||||
def query(self, table_name: str, query: VectorQuery) -> VectorQueryResult:
|
||||
"""Query a table."""
|
||||
tbl = await self.post(
|
||||
f"/v1/table/{table_name}/query/", query, deserialize=_read_ipc
|
||||
)
|
||||
tbl = self.post(f"/v1/table/{table_name}/query/", query, deserialize=_read_ipc)
|
||||
return VectorQueryResult(tbl)
|
||||
|
||||
@@ -28,6 +28,7 @@ from ..pydantic import LanceModel
|
||||
from ..table import Table, _sanitize_data
|
||||
from .arrow import to_ipc_binary
|
||||
from .client import ARROW_STREAM_CONTENT_TYPE, RestfulLanceDBClient
|
||||
from .errors import LanceDBClientError
|
||||
|
||||
|
||||
class RemoteDBConnection(DBConnection):
|
||||
@@ -49,31 +50,30 @@ class RemoteDBConnection(DBConnection):
|
||||
self._client = RestfulLanceDBClient(
|
||||
self.db_name, region, api_key, host_override
|
||||
)
|
||||
try:
|
||||
self._loop = asyncio.get_running_loop()
|
||||
except RuntimeError:
|
||||
self._loop = asyncio.get_event_loop()
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"RemoveConnect(name={self.db_name})"
|
||||
return f"RemoteConnect(name={self.db_name})"
|
||||
|
||||
@override
|
||||
def table_names(self, page_token: Optional[str] = None, limit=10) -> Iterable[str]:
|
||||
def table_names(
|
||||
self, page_token: Optional[str] = None, limit: int = 10
|
||||
) -> Iterable[str]:
|
||||
"""List the names of all tables in the database.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
page_token: str
|
||||
The last token to start the new page.
|
||||
limit: int, default 10
|
||||
The maximum number of tables to return for each page.
|
||||
|
||||
Returns
|
||||
-------
|
||||
An iterator of table names.
|
||||
"""
|
||||
while True:
|
||||
result = self._loop.run_until_complete(
|
||||
self._client.list_tables(limit, page_token)
|
||||
)
|
||||
result = self._client.list_tables(limit, page_token)
|
||||
|
||||
if len(result) > 0:
|
||||
page_token = result[len(result) - 1]
|
||||
else:
|
||||
@@ -98,14 +98,13 @@ class RemoteDBConnection(DBConnection):
|
||||
|
||||
# check if table exists
|
||||
try:
|
||||
self._loop.run_until_complete(
|
||||
self._client.post(f"/v1/table/{name}/describe/")
|
||||
)
|
||||
except Exception:
|
||||
logging.error(
|
||||
"Table {name} does not exist."
|
||||
"Please first call db.create_table({name}, data)"
|
||||
)
|
||||
self._client.post(f"/v1/table/{name}/describe/")
|
||||
except LanceDBClientError as err:
|
||||
if str(err).startswith("Not found"):
|
||||
logging.error(
|
||||
f"Table {name} does not exist. "
|
||||
f"Please first call db.create_table({name}, data)"
|
||||
)
|
||||
return RemoteTable(self, name)
|
||||
|
||||
@override
|
||||
@@ -118,6 +117,97 @@ class RemoteDBConnection(DBConnection):
|
||||
fill_value: float = 0.0,
|
||||
embedding_functions: Optional[List[EmbeddingFunctionConfig]] = None,
|
||||
) -> Table:
|
||||
"""Create a [Table][lancedb.table.Table] in the database.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
name: str
|
||||
The name of the table.
|
||||
data: The data to initialize the table, *optional*
|
||||
User must provide at least one of `data` or `schema`.
|
||||
Acceptable types are:
|
||||
|
||||
- dict or list-of-dict
|
||||
|
||||
- pandas.DataFrame
|
||||
|
||||
- pyarrow.Table or pyarrow.RecordBatch
|
||||
schema: The schema of the table, *optional*
|
||||
Acceptable types are:
|
||||
|
||||
- pyarrow.Schema
|
||||
|
||||
- [LanceModel][lancedb.pydantic.LanceModel]
|
||||
on_bad_vectors: str, default "error"
|
||||
What to do if any of the vectors are not the same size or contains NaNs.
|
||||
One of "error", "drop", "fill".
|
||||
fill_value: float
|
||||
The value to use when filling vectors. Only used if on_bad_vectors="fill".
|
||||
|
||||
Returns
|
||||
-------
|
||||
LanceTable
|
||||
A reference to the newly created table.
|
||||
|
||||
!!! note
|
||||
|
||||
The vector index won't be created by default.
|
||||
To create the index, call the `create_index` method on the table.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Can create with list of tuples or dictionaries:
|
||||
|
||||
>>> import lancedb
|
||||
>>> db = lancedb.connect("db://...", api_key="...", region="...") # doctest: +SKIP
|
||||
>>> data = [{"vector": [1.1, 1.2], "lat": 45.5, "long": -122.7},
|
||||
... {"vector": [0.2, 1.8], "lat": 40.1, "long": -74.1}]
|
||||
>>> db.create_table("my_table", data) # doctest: +SKIP
|
||||
LanceTable(my_table)
|
||||
|
||||
You can also pass a pandas DataFrame:
|
||||
|
||||
>>> import pandas as pd
|
||||
>>> data = pd.DataFrame({
|
||||
... "vector": [[1.1, 1.2], [0.2, 1.8]],
|
||||
... "lat": [45.5, 40.1],
|
||||
... "long": [-122.7, -74.1]
|
||||
... })
|
||||
>>> db.create_table("table2", data) # doctest: +SKIP
|
||||
LanceTable(table2)
|
||||
|
||||
>>> custom_schema = pa.schema([
|
||||
... pa.field("vector", pa.list_(pa.float32(), 2)),
|
||||
... pa.field("lat", pa.float32()),
|
||||
... pa.field("long", pa.float32())
|
||||
... ])
|
||||
>>> db.create_table("table3", data, schema = custom_schema) # doctest: +SKIP
|
||||
LanceTable(table3)
|
||||
|
||||
It is also possible to create an table from `[Iterable[pa.RecordBatch]]`:
|
||||
|
||||
>>> import pyarrow as pa
|
||||
>>> 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("table4", make_batches(), schema=schema) # doctest: +SKIP
|
||||
LanceTable(table4)
|
||||
|
||||
"""
|
||||
if data is None and schema is None:
|
||||
raise ValueError("Either data or schema must be provided.")
|
||||
if embedding_functions is not None:
|
||||
@@ -151,14 +241,13 @@ class RemoteDBConnection(DBConnection):
|
||||
data = to_ipc_binary(data)
|
||||
request_id = uuid.uuid4().hex
|
||||
|
||||
self._loop.run_until_complete(
|
||||
self._client.post(
|
||||
f"/v1/table/{name}/create/",
|
||||
data=data,
|
||||
request_id=request_id,
|
||||
content_type=ARROW_STREAM_CONTENT_TYPE,
|
||||
)
|
||||
self._client.post(
|
||||
f"/v1/table/{name}/create/",
|
||||
data=data,
|
||||
request_id=request_id,
|
||||
content_type=ARROW_STREAM_CONTENT_TYPE,
|
||||
)
|
||||
|
||||
return RemoteTable(self, name)
|
||||
|
||||
@override
|
||||
@@ -170,13 +259,11 @@ class RemoteDBConnection(DBConnection):
|
||||
name: str
|
||||
The name of the table.
|
||||
"""
|
||||
self._loop.run_until_complete(
|
||||
self._client.post(
|
||||
f"/v1/table/{name}/drop/",
|
||||
)
|
||||
|
||||
self._client.post(
|
||||
f"/v1/table/{name}/drop/",
|
||||
)
|
||||
|
||||
async def close(self):
|
||||
"""Close the connection to the database."""
|
||||
self._loop.close()
|
||||
await self._client.close()
|
||||
self._client.close()
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import asyncio
|
||||
import uuid
|
||||
from functools import cached_property
|
||||
from typing import Optional, Union
|
||||
from typing import Dict, Optional, Union
|
||||
|
||||
import pyarrow as pa
|
||||
from lance import json_to_schema
|
||||
@@ -22,6 +23,7 @@ from lancedb.common import DATA, VEC, VECTOR_COLUMN_NAME
|
||||
|
||||
from ..query import LanceVectorQueryBuilder
|
||||
from ..table import Query, Table, _sanitize_data
|
||||
from ..util import value_to_sql
|
||||
from .arrow import to_ipc_binary
|
||||
from .client import ARROW_STREAM_CONTENT_TYPE
|
||||
from .db import RemoteDBConnection
|
||||
@@ -37,40 +39,38 @@ class RemoteTable(Table):
|
||||
|
||||
@cached_property
|
||||
def schema(self) -> pa.Schema:
|
||||
"""Return the schema of the table."""
|
||||
resp = self._conn._loop.run_until_complete(
|
||||
self._conn._client.post(f"/v1/table/{self._name}/describe/")
|
||||
)
|
||||
"""The [Arrow Schema](https://arrow.apache.org/docs/python/api/datatypes.html#)
|
||||
of this Table
|
||||
|
||||
"""
|
||||
resp = self._conn._client.post(f"/v1/table/{self._name}/describe/")
|
||||
schema = json_to_schema(resp["schema"])
|
||||
return schema
|
||||
|
||||
@property
|
||||
def version(self) -> int:
|
||||
"""Get the current version of the table"""
|
||||
resp = self._conn._loop.run_until_complete(
|
||||
self._conn._client.post(f"/v1/table/{self._name}/describe/")
|
||||
)
|
||||
resp = self._conn._client.post(f"/v1/table/{self._name}/describe/")
|
||||
return resp["version"]
|
||||
|
||||
def to_arrow(self) -> pa.Table:
|
||||
"""Return the table as an Arrow table."""
|
||||
"""to_arrow() is not supported on the LanceDB cloud"""
|
||||
raise NotImplementedError("to_arrow() is not supported on the LanceDB cloud")
|
||||
|
||||
def to_pandas(self):
|
||||
"""Return the table as a Pandas DataFrame.
|
||||
|
||||
Intercept `to_arrow()` for better error message.
|
||||
"""
|
||||
"""to_pandas() is not supported on the LanceDB cloud"""
|
||||
return NotImplementedError("to_pandas() is not supported on the LanceDB cloud")
|
||||
|
||||
def create_scalar_index(self, *args, **kwargs):
|
||||
"""Creates a scalar index"""
|
||||
return NotImplementedError(
|
||||
"create_scalar_index() is not supported on the LanceDB cloud"
|
||||
)
|
||||
|
||||
def create_index(
|
||||
self,
|
||||
metric="L2",
|
||||
num_partitions=256,
|
||||
num_sub_vectors=96,
|
||||
vector_column_name: str = VECTOR_COLUMN_NAME,
|
||||
replace: bool = True,
|
||||
accelerator: Optional[str] = None,
|
||||
index_cache_size: Optional[int] = None,
|
||||
):
|
||||
"""Create an index on the table.
|
||||
@@ -81,39 +81,28 @@ class RemoteTable(Table):
|
||||
----------
|
||||
metric : str
|
||||
The metric to use for the index. Default is "L2".
|
||||
num_partitions : int
|
||||
The number of partitions to use for the index. Default is 256.
|
||||
num_sub_vectors : int
|
||||
The number of sub-vectors to use for the index. Default is 96.
|
||||
vector_column_name : str
|
||||
The name of the vector column. Default is "vector".
|
||||
replace : bool
|
||||
Whether to replace the existing index. Default is True.
|
||||
accelerator : str, optional
|
||||
If set, use the given accelerator to create the index.
|
||||
Default is None. Currently not supported.
|
||||
index_cache_size : int, optional
|
||||
The size of the index cache in number of entries. Default value is 256.
|
||||
|
||||
Examples
|
||||
--------
|
||||
import lancedb
|
||||
import uuid
|
||||
from lancedb.schema import vector
|
||||
conn = lancedb.connect("db://...", api_key="...", region="...")
|
||||
table_name = uuid.uuid4().hex
|
||||
schema = pa.schema(
|
||||
[
|
||||
pa.field("id", pa.uint32(), False),
|
||||
pa.field("vector", vector(128), False),
|
||||
pa.field("s", pa.string(), False),
|
||||
]
|
||||
)
|
||||
table = conn.create_table(
|
||||
table_name,
|
||||
schema=schema,
|
||||
)
|
||||
table.create_index()
|
||||
>>> import lancedb
|
||||
>>> import uuid
|
||||
>>> from lancedb.schema import vector
|
||||
>>> db = lancedb.connect("db://...", api_key="...", region="...") # doctest: +SKIP
|
||||
>>> table_name = uuid.uuid4().hex
|
||||
>>> schema = pa.schema(
|
||||
... [
|
||||
... pa.field("id", pa.uint32(), False),
|
||||
... pa.field("vector", vector(128), False),
|
||||
... pa.field("s", pa.string(), False),
|
||||
... ]
|
||||
... )
|
||||
>>> table = db.create_table( # doctest: +SKIP
|
||||
... table_name, # doctest: +SKIP
|
||||
... schema=schema, # doctest: +SKIP
|
||||
... )
|
||||
>>> table.create_index("L2", "vector") # doctest: +SKIP
|
||||
"""
|
||||
index_type = "vector"
|
||||
|
||||
@@ -123,9 +112,10 @@ class RemoteTable(Table):
|
||||
"metric_type": metric,
|
||||
"index_cache_size": index_cache_size,
|
||||
}
|
||||
resp = self._conn._loop.run_until_complete(
|
||||
self._conn._client.post(f"/v1/table/{self._name}/create_index/", data=data)
|
||||
resp = self._conn._client.post(
|
||||
f"/v1/table/{self._name}/create_index/", data=data
|
||||
)
|
||||
|
||||
return resp
|
||||
|
||||
def add(
|
||||
@@ -135,6 +125,28 @@ class RemoteTable(Table):
|
||||
on_bad_vectors: str = "error",
|
||||
fill_value: float = 0.0,
|
||||
) -> int:
|
||||
"""Add more data to the [Table](Table). It has the same API signature as the OSS version.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
data: DATA
|
||||
The data to insert into the table. Acceptable types are:
|
||||
|
||||
- dict or list-of-dict
|
||||
|
||||
- pandas.DataFrame
|
||||
|
||||
- pyarrow.Table or pyarrow.RecordBatch
|
||||
mode: str
|
||||
The mode to use when writing the data. Valid values are
|
||||
"append" and "overwrite".
|
||||
on_bad_vectors: str, default "error"
|
||||
What to do if any of the vectors are not the same size or contains NaNs.
|
||||
One of "error", "drop", "fill".
|
||||
fill_value: float, default 0.
|
||||
The value to use when filling vectors. Only used if on_bad_vectors="fill".
|
||||
|
||||
"""
|
||||
data = _sanitize_data(
|
||||
data,
|
||||
self.schema,
|
||||
@@ -146,27 +158,203 @@ class RemoteTable(Table):
|
||||
|
||||
request_id = uuid.uuid4().hex
|
||||
|
||||
self._conn._loop.run_until_complete(
|
||||
self._conn._client.post(
|
||||
f"/v1/table/{self._name}/insert/",
|
||||
data=payload,
|
||||
params={"request_id": request_id, "mode": mode},
|
||||
content_type=ARROW_STREAM_CONTENT_TYPE,
|
||||
)
|
||||
self._conn._client.post(
|
||||
f"/v1/table/{self._name}/insert/",
|
||||
data=payload,
|
||||
params={"request_id": request_id, "mode": mode},
|
||||
content_type=ARROW_STREAM_CONTENT_TYPE,
|
||||
)
|
||||
|
||||
def search(
|
||||
self, query: Union[VEC, str], vector_column_name: str = VECTOR_COLUMN_NAME
|
||||
) -> LanceVectorQueryBuilder:
|
||||
"""Create a search query to find the nearest neighbors
|
||||
of the given query vector. We currently support [vector search][search]
|
||||
|
||||
All query options are defined in [Query][lancedb.query.Query].
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import lancedb
|
||||
>>> db = lancedb.connect("db://...", api_key="...", region="...") # doctest: +SKIP
|
||||
>>> data = [
|
||||
... {"original_width": 100, "caption": "bar", "vector": [0.1, 2.3, 4.5]},
|
||||
... {"original_width": 2000, "caption": "foo", "vector": [0.5, 3.4, 1.3]},
|
||||
... {"original_width": 3000, "caption": "test", "vector": [0.3, 6.2, 2.6]}
|
||||
... ]
|
||||
>>> table = db.create_table("my_table", data) # doctest: +SKIP
|
||||
>>> query = [0.4, 1.4, 2.4]
|
||||
>>> (table.search(query, vector_column_name="vector") # doctest: +SKIP
|
||||
... .where("original_width > 1000", prefilter=True) # doctest: +SKIP
|
||||
... .select(["caption", "original_width"]) # doctest: +SKIP
|
||||
... .limit(2) # doctest: +SKIP
|
||||
... .to_pandas()) # doctest: +SKIP
|
||||
caption original_width vector _distance # doctest: +SKIP
|
||||
0 foo 2000 [0.5, 3.4, 1.3] 5.220000 # doctest: +SKIP
|
||||
1 test 3000 [0.3, 6.2, 2.6] 23.089996 # doctest: +SKIP
|
||||
|
||||
Parameters
|
||||
----------
|
||||
query: list/np.ndarray/str/PIL.Image.Image, default None
|
||||
The targetted vector to search for.
|
||||
|
||||
- *default None*.
|
||||
Acceptable types are: list, np.ndarray, PIL.Image.Image
|
||||
|
||||
- If None then the select/where/limit clauses are applied to filter
|
||||
the table
|
||||
vector_column_name: str
|
||||
The name of the vector column to search.
|
||||
*default "vector"*
|
||||
|
||||
Returns
|
||||
-------
|
||||
LanceQueryBuilder
|
||||
A query builder object representing the query.
|
||||
Once executed, the query returns
|
||||
|
||||
- selected columns
|
||||
|
||||
- the vector
|
||||
|
||||
- and also the "_distance" column which is the distance between the query
|
||||
vector and the returned vector.
|
||||
"""
|
||||
return LanceVectorQueryBuilder(self, query, vector_column_name)
|
||||
|
||||
def _execute_query(self, query: Query) -> pa.Table:
|
||||
result = self._conn._client.query(self._name, query)
|
||||
return self._conn._loop.run_until_complete(result).to_arrow()
|
||||
if (
|
||||
query.vector is not None
|
||||
and len(query.vector) > 0
|
||||
and not isinstance(query.vector[0], float)
|
||||
):
|
||||
results = []
|
||||
for v in query.vector:
|
||||
v = list(v)
|
||||
q = query.copy()
|
||||
q.vector = v
|
||||
results.append(self._conn._client.query(self._name, q))
|
||||
|
||||
return pa.concat_tables(
|
||||
[add_index(r.to_arrow(), i) for i, r in enumerate(results)]
|
||||
)
|
||||
else:
|
||||
result = self._conn._client.query(self._name, query)
|
||||
return result.to_arrow()
|
||||
|
||||
def delete(self, predicate: str):
|
||||
"""Delete rows from the table."""
|
||||
"""Delete rows from the table.
|
||||
|
||||
This can be used to delete a single row, many rows, all rows, or
|
||||
sometimes no rows (if your predicate matches nothing).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
predicate: str
|
||||
The SQL where clause to use when deleting rows.
|
||||
|
||||
- For example, 'x = 2' or 'x IN (1, 2, 3)'.
|
||||
|
||||
The filter must not be empty, or it will error.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import lancedb
|
||||
>>> data = [
|
||||
... {"x": 1, "vector": [1, 2]},
|
||||
... {"x": 2, "vector": [3, 4]},
|
||||
... {"x": 3, "vector": [5, 6]}
|
||||
... ]
|
||||
>>> db = lancedb.connect("db://...", api_key="...", region="...") # doctest: +SKIP
|
||||
>>> table = db.create_table("my_table", data) # doctest: +SKIP
|
||||
>>> table.search([10,10]).to_pandas() # doctest: +SKIP
|
||||
x vector _distance # doctest: +SKIP
|
||||
0 3 [5.0, 6.0] 41.0 # doctest: +SKIP
|
||||
1 2 [3.0, 4.0] 85.0 # doctest: +SKIP
|
||||
2 1 [1.0, 2.0] 145.0 # doctest: +SKIP
|
||||
>>> table.delete("x = 2") # doctest: +SKIP
|
||||
>>> table.search([10,10]).to_pandas() # doctest: +SKIP
|
||||
x vector _distance # doctest: +SKIP
|
||||
0 3 [5.0, 6.0] 41.0 # doctest: +SKIP
|
||||
1 1 [1.0, 2.0] 145.0 # doctest: +SKIP
|
||||
|
||||
If you have a list of values to delete, you can combine them into a
|
||||
stringified list and use the `IN` operator:
|
||||
|
||||
>>> to_remove = [1, 3] # doctest: +SKIP
|
||||
>>> to_remove = ", ".join([str(v) for v in to_remove]) # doctest: +SKIP
|
||||
>>> table.delete(f"x IN ({to_remove})") # doctest: +SKIP
|
||||
>>> table.search([10,10]).to_pandas() # doctest: +SKIP
|
||||
x vector _distance # doctest: +SKIP
|
||||
0 2 [3.0, 4.0] 85.0 # doctest: +SKIP
|
||||
"""
|
||||
payload = {"predicate": predicate}
|
||||
self._conn._loop.run_until_complete(
|
||||
self._conn._client.post(f"/v1/table/{self._name}/delete/", data=payload)
|
||||
)
|
||||
self._conn._client.post(f"/v1/table/{self._name}/delete/", data=payload)
|
||||
|
||||
def update(
|
||||
self,
|
||||
where: Optional[str] = None,
|
||||
values: Optional[dict] = None,
|
||||
*,
|
||||
values_sql: Optional[Dict[str, str]] = None,
|
||||
):
|
||||
"""
|
||||
This can be used to update zero to all rows depending on how many
|
||||
rows match the where clause.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
where: str, optional
|
||||
The SQL where clause to use when updating rows. For example, 'x = 2'
|
||||
or 'x IN (1, 2, 3)'. The filter must not be empty, or it will error.
|
||||
values: dict, optional
|
||||
The values to update. The keys are the column names and the values
|
||||
are the values to set.
|
||||
values_sql: dict, optional
|
||||
The values to update, expressed as SQL expression strings. These can
|
||||
reference existing columns. For example, {"x": "x + 1"} will increment
|
||||
the x column by 1.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import lancedb
|
||||
>>> data = [
|
||||
... {"x": 1, "vector": [1, 2]},
|
||||
... {"x": 2, "vector": [3, 4]},
|
||||
... {"x": 3, "vector": [5, 6]}
|
||||
... ]
|
||||
>>> db = lancedb.connect("db://...", api_key="...", region="...") # doctest: +SKIP
|
||||
>>> table = db.create_table("my_table", data) # doctest: +SKIP
|
||||
>>> table.to_pandas() # doctest: +SKIP
|
||||
x vector # doctest: +SKIP
|
||||
0 1 [1.0, 2.0] # doctest: +SKIP
|
||||
1 2 [3.0, 4.0] # doctest: +SKIP
|
||||
2 3 [5.0, 6.0] # doctest: +SKIP
|
||||
>>> table.update(where="x = 2", values={"vector": [10, 10]}) # doctest: +SKIP
|
||||
>>> table.to_pandas() # doctest: +SKIP
|
||||
x vector # doctest: +SKIP
|
||||
0 1 [1.0, 2.0] # doctest: +SKIP
|
||||
1 3 [5.0, 6.0] # doctest: +SKIP
|
||||
2 2 [10.0, 10.0] # doctest: +SKIP
|
||||
|
||||
"""
|
||||
if values is not None and values_sql is not None:
|
||||
raise ValueError("Only one of values or values_sql can be provided")
|
||||
if values is None and values_sql is None:
|
||||
raise ValueError("Either values or values_sql must be provided")
|
||||
|
||||
if values is not None:
|
||||
updates = [[k, value_to_sql(v)] for k, v in values.items()]
|
||||
else:
|
||||
updates = [[k, v] for k, v in values_sql.items()]
|
||||
|
||||
payload = {"predicate": where, "updates": updates}
|
||||
self._conn._client.post(f"/v1/table/{self._name}/update/", data=payload)
|
||||
|
||||
|
||||
def add_index(tbl: pa.Table, i: int) -> pa.Table:
|
||||
return tbl.add_column(
|
||||
0,
|
||||
pa.field("query_index", pa.uint32()),
|
||||
pa.array([i] * len(tbl), pa.uint32()),
|
||||
)
|
||||
|
||||
@@ -17,20 +17,27 @@ import inspect
|
||||
import os
|
||||
from abc import ABC, abstractmethod
|
||||
from functools import cached_property
|
||||
from typing import TYPE_CHECKING, Any, Iterable, List, Optional, Union
|
||||
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Union
|
||||
|
||||
import lance
|
||||
import numpy as np
|
||||
import pyarrow as pa
|
||||
import pyarrow.compute as pc
|
||||
import pyarrow.fs as pa_fs
|
||||
from lance import LanceDataset
|
||||
from lance.vector import vec_to_table
|
||||
|
||||
from .common import DATA, VEC, VECTOR_COLUMN_NAME
|
||||
from .embeddings import EmbeddingFunctionConfig, EmbeddingFunctionRegistry
|
||||
from .pydantic import LanceModel
|
||||
from .pydantic import LanceModel, model_to_dict
|
||||
from .query import LanceQueryBuilder, Query
|
||||
from .util import fs_from_uri, safe_import_pandas
|
||||
from .util import (
|
||||
fs_from_uri,
|
||||
safe_import_pandas,
|
||||
safe_import_polars,
|
||||
value_to_sql,
|
||||
join_uri,
|
||||
)
|
||||
from .utils.events import register_event
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -40,6 +47,7 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
pd = safe_import_pandas()
|
||||
pl = safe_import_polars()
|
||||
|
||||
|
||||
def _sanitize_data(
|
||||
@@ -53,8 +61,10 @@ def _sanitize_data(
|
||||
# convert to list of dict if data is a bunch of LanceModels
|
||||
if isinstance(data[0], LanceModel):
|
||||
schema = data[0].__class__.to_arrow_schema()
|
||||
data = [dict(d) for d in data]
|
||||
data = pa.Table.from_pylist(data)
|
||||
data = [model_to_dict(d) for d in data]
|
||||
data = pa.Table.from_pylist(data, schema=schema)
|
||||
else:
|
||||
data = pa.Table.from_pylist(data)
|
||||
elif isinstance(data, dict):
|
||||
data = vec_to_table(data)
|
||||
elif pd is not None and isinstance(data, pd.DataFrame):
|
||||
@@ -63,6 +73,8 @@ def _sanitize_data(
|
||||
meta = data.schema.metadata if data.schema.metadata is not None else {}
|
||||
meta = {k: v for k, v in meta.items() if k != b"pandas"}
|
||||
data = data.replace_schema_metadata(meta)
|
||||
elif pl is not None and isinstance(data, pl.DataFrame):
|
||||
data = data.to_arrow()
|
||||
|
||||
if isinstance(data, pa.Table):
|
||||
if metadata:
|
||||
@@ -218,6 +230,77 @@ class Table(ABC):
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def create_scalar_index(
|
||||
self,
|
||||
column: str,
|
||||
*,
|
||||
replace: bool = True,
|
||||
):
|
||||
"""Create a scalar index on a column.
|
||||
|
||||
Scalar indices, like vector indices, can be used to speed up scans. A scalar
|
||||
index can speed up scans that contain filter expressions on the indexed column.
|
||||
For example, the following scan will be faster if the column ``my_col`` has
|
||||
a scalar index:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import lancedb
|
||||
|
||||
db = lancedb.connect("/data/lance")
|
||||
img_table = db.open_table("images")
|
||||
my_df = img_table.search().where("my_col = 7", prefilter=True).to_pandas()
|
||||
|
||||
Scalar indices can also speed up scans containing a vector search and a
|
||||
prefilter:
|
||||
|
||||
.. code-block::python
|
||||
|
||||
import lancedb
|
||||
|
||||
db = lancedb.connect("/data/lance")
|
||||
img_table = db.open_table("images")
|
||||
img_table.search([1, 2, 3, 4], vector_column_name="vector")
|
||||
.where("my_col != 7", prefilter=True)
|
||||
.to_pandas()
|
||||
|
||||
Scalar indices can only speed up scans for basic filters using
|
||||
equality, comparison, range (e.g. ``my_col BETWEEN 0 AND 100``), and set
|
||||
membership (e.g. `my_col IN (0, 1, 2)`)
|
||||
|
||||
Scalar indices can be used if the filter contains multiple indexed columns and
|
||||
the filter criteria are AND'd or OR'd together
|
||||
(e.g. ``my_col < 0 AND other_col> 100``)
|
||||
|
||||
Scalar indices may be used if the filter contains non-indexed columns but,
|
||||
depending on the structure of the filter, they may not be usable. For example,
|
||||
if the column ``not_indexed`` does not have a scalar index then the filter
|
||||
``my_col = 0 OR not_indexed = 1`` will not be able to use any scalar index on
|
||||
``my_col``.
|
||||
|
||||
**Experimental API**
|
||||
|
||||
Parameters
|
||||
----------
|
||||
column : str
|
||||
The column to be indexed. Must be a boolean, integer, float,
|
||||
or string column.
|
||||
replace : bool, default True
|
||||
Replace the existing index if it exists.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import lance
|
||||
|
||||
dataset = lance.dataset("/tmp/images.lance")
|
||||
dataset.create_scalar_index("category")
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def add(
|
||||
self,
|
||||
@@ -381,6 +464,62 @@ class Table(ABC):
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def update(
|
||||
self,
|
||||
where: Optional[str] = None,
|
||||
values: Optional[dict] = None,
|
||||
*,
|
||||
values_sql: Optional[Dict[str, str]] = None,
|
||||
):
|
||||
"""
|
||||
This can be used to update zero to all rows depending on how many
|
||||
rows match the where clause. If no where clause is provided, then
|
||||
all rows will be updated.
|
||||
|
||||
Either `values` or `values_sql` must be provided. You cannot provide
|
||||
both.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
where: str, optional
|
||||
The SQL where clause to use when updating rows. For example, 'x = 2'
|
||||
or 'x IN (1, 2, 3)'. The filter must not be empty, or it will error.
|
||||
values: dict, optional
|
||||
The values to update. The keys are the column names and the values
|
||||
are the values to set.
|
||||
values_sql: dict, optional
|
||||
The values to update, expressed as SQL expression strings. These can
|
||||
reference existing columns. For example, {"x": "x + 1"} will increment
|
||||
the x column by 1.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import lancedb
|
||||
>>> import pandas as pd
|
||||
>>> data = pd.DataFrame({"x": [1, 2, 3], "vector": [[1, 2], [3, 4], [5, 6]]})
|
||||
>>> db = lancedb.connect("./.lancedb")
|
||||
>>> table = db.create_table("my_table", data)
|
||||
>>> table.to_pandas()
|
||||
x vector
|
||||
0 1 [1.0, 2.0]
|
||||
1 2 [3.0, 4.0]
|
||||
2 3 [5.0, 6.0]
|
||||
>>> table.update(where="x = 2", values={"vector": [10, 10]})
|
||||
>>> table.to_pandas()
|
||||
x vector
|
||||
0 1 [1.0, 2.0]
|
||||
1 3 [5.0, 6.0]
|
||||
2 2 [10.0, 10.0]
|
||||
>>> table.update(values_sql={"x": "x + 1"})
|
||||
>>> table.to_pandas()
|
||||
x vector
|
||||
0 2 [1.0, 2.0]
|
||||
1 4 [5.0, 6.0]
|
||||
2 3 [10.0, 10.0]
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class LanceTable(Table):
|
||||
"""
|
||||
@@ -517,8 +656,19 @@ class LanceTable(Table):
|
||||
self._dataset.restore()
|
||||
self._reset_dataset()
|
||||
|
||||
def count_rows(self, filter: Optional[str] = None) -> int:
|
||||
"""
|
||||
Count the number of rows in the table.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
filter: str, optional
|
||||
A SQL where clause to filter the rows to count.
|
||||
"""
|
||||
return self._dataset.count_rows(filter)
|
||||
|
||||
def __len__(self):
|
||||
return self._dataset.count_rows()
|
||||
return self.count_rows()
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"LanceTable({self.name})"
|
||||
@@ -547,9 +697,33 @@ class LanceTable(Table):
|
||||
pa.Table"""
|
||||
return self._dataset.to_table()
|
||||
|
||||
def to_polars(self, batch_size=None) -> "pl.LazyFrame":
|
||||
"""Return the table as a polars LazyFrame.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
batch_size: int, optional
|
||||
Passed to polars. This is the maximum row count for
|
||||
scanned pyarrow record batches
|
||||
|
||||
Note
|
||||
----
|
||||
1. This requires polars to be installed separately
|
||||
2. Currently we've disabled push-down of the filters from polars
|
||||
because polars pushdown into pyarrow uses pyarrow compute
|
||||
expressions rather than SQl strings (which LanceDB supports)
|
||||
|
||||
Returns
|
||||
-------
|
||||
pl.LazyFrame
|
||||
"""
|
||||
return pl.scan_pyarrow_dataset(
|
||||
self.to_lance(), allow_pyarrow_filter=False, batch_size=batch_size
|
||||
)
|
||||
|
||||
@property
|
||||
def _dataset_uri(self) -> str:
|
||||
return os.path.join(self._conn.uri, f"{self.name}.lance")
|
||||
return join_uri(self._conn.uri, f"{self.name}.lance")
|
||||
|
||||
def create_index(
|
||||
self,
|
||||
@@ -575,7 +749,16 @@ class LanceTable(Table):
|
||||
self._reset_dataset()
|
||||
register_event("create_index")
|
||||
|
||||
def create_fts_index(self, field_names: Union[str, List[str]]):
|
||||
def create_scalar_index(self, column: str, *, replace: bool = True):
|
||||
self._dataset.create_scalar_index(column, index_type="BTREE", replace=replace)
|
||||
|
||||
def create_fts_index(
|
||||
self,
|
||||
field_names: Union[str, List[str]],
|
||||
*,
|
||||
replace: bool = False,
|
||||
writer_heap_size: Optional[int] = 1024 * 1024 * 1024,
|
||||
):
|
||||
"""Create a full-text search index on the table.
|
||||
|
||||
Warning - this API is highly experimental and is highly likely to change
|
||||
@@ -585,17 +768,32 @@ class LanceTable(Table):
|
||||
----------
|
||||
field_names: str or list of str
|
||||
The name(s) of the field to index.
|
||||
replace: bool, default False
|
||||
If True, replace the existing index if it exists. Note that this is
|
||||
not yet an atomic operation; the index will be temporarily
|
||||
unavailable while the new index is being created.
|
||||
writer_heap_size: int, default 1GB
|
||||
"""
|
||||
from .fts import create_index, populate_index
|
||||
|
||||
if isinstance(field_names, str):
|
||||
field_names = [field_names]
|
||||
|
||||
fs, path = fs_from_uri(self._get_fts_index_path())
|
||||
index_exists = fs.get_file_info(path).type != pa_fs.FileType.NotFound
|
||||
if index_exists:
|
||||
if not replace:
|
||||
raise ValueError(
|
||||
f"Index already exists. Use replace=True to overwrite."
|
||||
)
|
||||
fs.delete_dir(path)
|
||||
|
||||
index = create_index(self._get_fts_index_path(), field_names)
|
||||
populate_index(index, self, field_names)
|
||||
populate_index(index, self, field_names, writer_heap_size=writer_heap_size)
|
||||
register_event("create_fts_index")
|
||||
|
||||
def _get_fts_index_path(self):
|
||||
return os.path.join(self._dataset_uri, "_indices", "tantivy")
|
||||
return join_uri(self._dataset_uri, "_indices", "tantivy")
|
||||
|
||||
@cached_property
|
||||
def _dataset(self) -> LanceDataset:
|
||||
@@ -785,7 +983,7 @@ class LanceTable(Table):
|
||||
and also the "_distance" column which is the distance between the query
|
||||
vector and the returned vector.
|
||||
"""
|
||||
register_event("search")
|
||||
register_event("search_table")
|
||||
return LanceQueryBuilder.create(
|
||||
self, query, query_type, vector_column_name=vector_column_name
|
||||
)
|
||||
@@ -798,6 +996,7 @@ class LanceTable(Table):
|
||||
data=None,
|
||||
schema=None,
|
||||
mode="create",
|
||||
exist_ok=False,
|
||||
on_bad_vectors: str = "error",
|
||||
fill_value: float = 0.0,
|
||||
embedding_functions: List[EmbeddingFunctionConfig] = None,
|
||||
@@ -837,6 +1036,10 @@ class LanceTable(Table):
|
||||
mode: str, default "create"
|
||||
The mode to use when writing the data. Valid values are
|
||||
"create", "overwrite", and "append".
|
||||
exist_ok: bool, default False
|
||||
If the table already exists then raise an error if False,
|
||||
otherwise just open the table, it will not add the provided
|
||||
data but will validate against any schema that's specified.
|
||||
on_bad_vectors: str, default "error"
|
||||
What to do if any of the vectors are not the same size or contains NaNs.
|
||||
One of "error", "drop", "fill".
|
||||
@@ -887,14 +1090,24 @@ class LanceTable(Table):
|
||||
schema = schema.with_metadata(metadata)
|
||||
|
||||
empty = pa.Table.from_pylist([], schema=schema)
|
||||
lance.write_dataset(empty, tbl._dataset_uri, schema=schema, mode=mode)
|
||||
table = LanceTable(db, name)
|
||||
try:
|
||||
lance.write_dataset(empty, tbl._dataset_uri, schema=schema, mode=mode)
|
||||
except OSError as err:
|
||||
if "Dataset already exists" in str(err) and exist_ok:
|
||||
if tbl.schema != schema:
|
||||
raise ValueError(
|
||||
f"Table {name} already exists with a different schema"
|
||||
)
|
||||
return tbl
|
||||
raise
|
||||
|
||||
new_table = LanceTable(db, name)
|
||||
|
||||
if data is not None:
|
||||
table.add(data)
|
||||
new_table.add(data)
|
||||
|
||||
register_event("create_table")
|
||||
return table
|
||||
return new_table
|
||||
|
||||
@classmethod
|
||||
def open(cls, db, name):
|
||||
@@ -906,35 +1119,42 @@ class LanceTable(Table):
|
||||
f"Table {name} does not exist."
|
||||
f"Please first call db.create_table({name}, data)"
|
||||
)
|
||||
register_event("open_table")
|
||||
|
||||
return tbl
|
||||
|
||||
def delete(self, where: str):
|
||||
self._dataset.delete(where)
|
||||
|
||||
def update(self, where: str, values: dict):
|
||||
def update(
|
||||
self,
|
||||
where: Optional[str] = None,
|
||||
values: Optional[dict] = None,
|
||||
*,
|
||||
values_sql: Optional[Dict[str, str]] = None,
|
||||
):
|
||||
"""
|
||||
EXPERIMENTAL: Update rows in the table (not threadsafe).
|
||||
|
||||
This can be used to update zero to all rows depending on how many
|
||||
rows match the where clause.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
where: str
|
||||
where: str, optional
|
||||
The SQL where clause to use when updating rows. For example, 'x = 2'
|
||||
or 'x IN (1, 2, 3)'. The filter must not be empty, or it will error.
|
||||
values: dict
|
||||
values: dict, optional
|
||||
The values to update. The keys are the column names and the values
|
||||
are the values to set.
|
||||
values_sql: dict, optional
|
||||
The values to update, expressed as SQL expression strings. These can
|
||||
reference existing columns. For example, {"x": "x + 1"} will increment
|
||||
the x column by 1.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> import lancedb
|
||||
>>> data = [
|
||||
... {"x": 1, "vector": [1, 2]},
|
||||
... {"x": 2, "vector": [3, 4]},
|
||||
... {"x": 3, "vector": [5, 6]}
|
||||
... ]
|
||||
>>> import pandas as pd
|
||||
>>> data = pd.DataFrame({"x": [1, 2, 3], "vector": [[1, 2], [3, 4], [5, 6]]})
|
||||
>>> db = lancedb.connect("./.lancedb")
|
||||
>>> table = db.create_table("my_table", data)
|
||||
>>> table.to_pandas()
|
||||
@@ -950,18 +1170,15 @@ class LanceTable(Table):
|
||||
2 2 [10.0, 10.0]
|
||||
|
||||
"""
|
||||
orig_data = self._dataset.to_table(filter=where).combine_chunks()
|
||||
if len(orig_data) == 0:
|
||||
return
|
||||
for col, val in values.items():
|
||||
i = orig_data.column_names.index(col)
|
||||
if i < 0:
|
||||
raise ValueError(f"Column {col} does not exist")
|
||||
orig_data = orig_data.set_column(
|
||||
i, col, pa.array([val] * len(orig_data), type=orig_data[col].type)
|
||||
)
|
||||
self.delete(where)
|
||||
self.add(orig_data, mode="append")
|
||||
if values is not None and values_sql is not None:
|
||||
raise ValueError("Only one of values or values_sql can be provided")
|
||||
if values is None and values_sql is None:
|
||||
raise ValueError("Either values or values_sql must be provided")
|
||||
|
||||
if values is not None:
|
||||
values_sql = {k: value_to_sql(v) for k, v in values.items()}
|
||||
|
||||
self.to_lance().update(values_sql, where)
|
||||
self._reset_dataset()
|
||||
register_event("update")
|
||||
|
||||
@@ -1107,7 +1324,8 @@ def _sanitize_vector_column(
|
||||
"""
|
||||
# ChunkedArray is annoying to work with, so we combine chunks here
|
||||
vec_arr = data[vector_column_name].combine_chunks()
|
||||
if pa.types.is_list(data[vector_column_name].type):
|
||||
typ = data[vector_column_name].type
|
||||
if pa.types.is_list(typ) or pa.types.is_large_list(typ):
|
||||
# if it's a variable size list array,
|
||||
# we make sure the dimensions are all the same
|
||||
has_jagged_ndims = len(vec_arr.values) % len(data) != 0
|
||||
|
||||
@@ -12,9 +12,13 @@
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
from typing import Tuple
|
||||
from datetime import date, datetime
|
||||
from functools import singledispatch
|
||||
import pathlib
|
||||
from typing import Tuple, Union
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import numpy as np
|
||||
import pyarrow.fs as pa_fs
|
||||
|
||||
|
||||
@@ -59,6 +63,12 @@ def get_uri_location(uri: str) -> str:
|
||||
str: Location part of the URL, without scheme
|
||||
"""
|
||||
parsed = urlparse(uri)
|
||||
if len(parsed.scheme) == 1:
|
||||
# Windows drive names are parsed as the scheme
|
||||
# e.g. "c:\path" -> ParseResult(scheme="c", netloc="", path="/path", ...)
|
||||
# So we add special handling here for schemes that are a single character
|
||||
return uri
|
||||
|
||||
if not parsed.netloc:
|
||||
return parsed.path
|
||||
else:
|
||||
@@ -81,6 +91,29 @@ def fs_from_uri(uri: str) -> Tuple[pa_fs.FileSystem, str]:
|
||||
return pa_fs.FileSystem.from_uri(uri)
|
||||
|
||||
|
||||
def join_uri(base: Union[str, pathlib.Path], *parts: str) -> str:
|
||||
"""
|
||||
Join a URI with multiple parts, handles both local and remote paths
|
||||
|
||||
Parameters
|
||||
----------
|
||||
base : str
|
||||
The base URI
|
||||
parts : str
|
||||
The parts to join to the base URI, each separated by the
|
||||
appropriate path separator for the URI scheme and OS
|
||||
"""
|
||||
if isinstance(base, pathlib.Path):
|
||||
return base.joinpath(*parts)
|
||||
base = str(base)
|
||||
if get_uri_scheme(base) == "file":
|
||||
# using pathlib for local paths make this windows compatible
|
||||
# `get_uri_scheme` returns `file` for windows drive names (e.g. `c:\path`)
|
||||
return str(pathlib.Path(base, *parts))
|
||||
# for remote paths, just use os.path.join
|
||||
return "/".join([p.rstrip("/") for p in [base, *parts]])
|
||||
|
||||
|
||||
def safe_import_pandas():
|
||||
try:
|
||||
import pandas as pd
|
||||
@@ -88,3 +121,62 @@ def safe_import_pandas():
|
||||
return pd
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
|
||||
def safe_import_polars():
|
||||
try:
|
||||
import polars as pl
|
||||
|
||||
return pl
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
|
||||
@singledispatch
|
||||
def value_to_sql(value):
|
||||
raise NotImplementedError("SQL conversion is not implemented for this type")
|
||||
|
||||
|
||||
@value_to_sql.register(str)
|
||||
def _(value: str):
|
||||
return f"'{value}'"
|
||||
|
||||
|
||||
@value_to_sql.register(int)
|
||||
def _(value: int):
|
||||
return str(value)
|
||||
|
||||
|
||||
@value_to_sql.register(float)
|
||||
def _(value: float):
|
||||
return str(value)
|
||||
|
||||
|
||||
@value_to_sql.register(bool)
|
||||
def _(value: bool):
|
||||
return str(value).upper()
|
||||
|
||||
|
||||
@value_to_sql.register(type(None))
|
||||
def _(value: type(None)):
|
||||
return "NULL"
|
||||
|
||||
|
||||
@value_to_sql.register(datetime)
|
||||
def _(value: datetime):
|
||||
return f"'{value.isoformat()}'"
|
||||
|
||||
|
||||
@value_to_sql.register(date)
|
||||
def _(value: date):
|
||||
return f"'{value.isoformat()}'"
|
||||
|
||||
|
||||
@value_to_sql.register(list)
|
||||
def _(value: list):
|
||||
return "[" + ", ".join(map(value_to_sql, value)) + "]"
|
||||
|
||||
|
||||
@value_to_sql.register(np.ndarray)
|
||||
def _(value: np.ndarray):
|
||||
return value_to_sql(value.tolist())
|
||||
|
||||
@@ -64,8 +64,10 @@ class _Events:
|
||||
Initializes the Events object with default values for events, rate_limit, and metadata.
|
||||
"""
|
||||
self.events = [] # events list
|
||||
self.max_events = 25 # max events to store in memory
|
||||
self.rate_limit = 60.0 # rate limit (seconds)
|
||||
self.throttled_event_names = ["search_table"]
|
||||
self.throttled_events = set()
|
||||
self.max_events = 5 # max events to store in memory
|
||||
self.rate_limit = 60.0 * 5 # rate limit (seconds)
|
||||
self.time = 0.0
|
||||
|
||||
if is_git_dir():
|
||||
@@ -112,18 +114,21 @@ class _Events:
|
||||
return
|
||||
if (
|
||||
len(self.events) < self.max_events
|
||||
): # Events list limited to 25 events (drop any events past this)
|
||||
): # Events list limited to self.max_events (drop any events past this)
|
||||
params.update(self.metadata)
|
||||
self.events.append(
|
||||
{
|
||||
"event": event_name,
|
||||
"properties": params,
|
||||
"timestamp": datetime.datetime.now(
|
||||
tz=datetime.timezone.utc
|
||||
).isoformat(),
|
||||
"distinct_id": CONFIG["uuid"],
|
||||
}
|
||||
)
|
||||
event = {
|
||||
"event": event_name,
|
||||
"properties": params,
|
||||
"timestamp": datetime.datetime.now(
|
||||
tz=datetime.timezone.utc
|
||||
).isoformat(),
|
||||
"distinct_id": CONFIG["uuid"],
|
||||
}
|
||||
if event_name not in self.throttled_event_names:
|
||||
self.events.append(event)
|
||||
elif event_name not in self.throttled_events:
|
||||
self.throttled_events.add(event_name)
|
||||
self.events.append(event)
|
||||
|
||||
# Check rate limit
|
||||
t = time.time()
|
||||
@@ -135,7 +140,6 @@ class _Events:
|
||||
"distinct_id": CONFIG["uuid"], # posthog needs this to accepts the event
|
||||
"batch": self.events,
|
||||
}
|
||||
|
||||
# POST equivalent to requests.post(self.url, json=data).
|
||||
# threaded request is used to avoid blocking, retries are disabled, and verbose is disabled
|
||||
# to avoid any possible disruption in the console.
|
||||
@@ -150,6 +154,7 @@ class _Events:
|
||||
|
||||
# Flush & Reset
|
||||
self.events = []
|
||||
self.throttled_events = set()
|
||||
self.time = t
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
[project]
|
||||
name = "lancedb"
|
||||
version = "0.3.4"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"deprecation",
|
||||
"pylance==0.8.17",
|
||||
"pylance==0.9.6",
|
||||
"ratelimiter~=1.0",
|
||||
"retry>=0.9.2",
|
||||
"tqdm>=4.1.0",
|
||||
"aiohttp",
|
||||
"tqdm>=4.27.0",
|
||||
"pydantic>=1.10",
|
||||
"attrs>=21.3.0",
|
||||
"semver>=3.0",
|
||||
@@ -49,11 +48,11 @@ classifiers = [
|
||||
repository = "https://github.com/lancedb/lancedb"
|
||||
|
||||
[project.optional-dependencies]
|
||||
tests = ["pandas>=1.4", "pytest", "pytest-mock", "pytest-asyncio", "requests"]
|
||||
dev = ["ruff", "pre-commit", "black"]
|
||||
tests = ["aiohttp", "pandas>=1.4", "pytest", "pytest-mock", "pytest-asyncio", "duckdb", "pytz", "polars"]
|
||||
dev = ["ruff", "pre-commit"]
|
||||
docs = ["mkdocs", "mkdocs-jupyter", "mkdocs-material", "mkdocstrings[python]"]
|
||||
clip = ["torch", "pillow", "open-clip"]
|
||||
embeddings = ["openai", "sentence-transformers", "torch", "pillow", "open-clip-torch", "cohere", "InstructorEmbedding"]
|
||||
embeddings = ["openai>=1.6.1", "sentence-transformers", "torch", "pillow", "open-clip-torch", "cohere", "InstructorEmbedding"]
|
||||
|
||||
[project.scripts]
|
||||
lancedb = "lancedb.cli.cli:cli"
|
||||
@@ -62,9 +61,6 @@ lancedb = "lancedb.cli.cli:cli"
|
||||
requires = ["setuptools", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.isort]
|
||||
profile = "black"
|
||||
|
||||
[tool.ruff]
|
||||
select = ["F", "E", "W", "I", "G", "TCH", "PERF"]
|
||||
|
||||
|
||||
@@ -190,6 +190,48 @@ def test_create_mode(tmp_path):
|
||||
assert tbl.to_pandas().item.tolist() == ["fizz", "buzz"]
|
||||
|
||||
|
||||
def test_create_exist_ok(tmp_path):
|
||||
db = lancedb.connect(tmp_path)
|
||||
data = pd.DataFrame(
|
||||
{
|
||||
"vector": [[3.1, 4.1], [5.9, 26.5]],
|
||||
"item": ["foo", "bar"],
|
||||
"price": [10.0, 20.0],
|
||||
}
|
||||
)
|
||||
tbl = db.create_table("test", data=data)
|
||||
|
||||
with pytest.raises(OSError):
|
||||
db.create_table("test", data=data)
|
||||
|
||||
# open the table but don't add more rows
|
||||
tbl2 = db.create_table("test", data=data, exist_ok=True)
|
||||
assert tbl.name == tbl2.name
|
||||
assert tbl.schema == tbl2.schema
|
||||
assert len(tbl) == len(tbl2)
|
||||
|
||||
schema = pa.schema(
|
||||
[
|
||||
pa.field("vector", pa.list_(pa.float32(), list_size=2)),
|
||||
pa.field("item", pa.utf8()),
|
||||
pa.field("price", pa.float64()),
|
||||
]
|
||||
)
|
||||
tbl3 = db.create_table("test", schema=schema, exist_ok=True)
|
||||
assert tbl3.schema == schema
|
||||
|
||||
bad_schema = pa.schema(
|
||||
[
|
||||
pa.field("vector", pa.list_(pa.float32(), list_size=2)),
|
||||
pa.field("item", pa.utf8()),
|
||||
pa.field("price", pa.float64()),
|
||||
pa.field("extra", pa.float32()),
|
||||
]
|
||||
)
|
||||
with pytest.raises(ValueError):
|
||||
db.create_table("test", schema=bad_schema, exist_ok=True)
|
||||
|
||||
|
||||
def test_delete_table(tmp_path):
|
||||
db = lancedb.connect(tmp_path)
|
||||
data = pd.DataFrame(
|
||||
|
||||
@@ -29,7 +29,7 @@ from lancedb.pydantic import LanceModel, Vector
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.parametrize("alias", ["sentence-transformers", "openai"])
|
||||
def test_sentence_transformer(alias, tmp_path):
|
||||
def test_basic_text_embeddings(alias, tmp_path):
|
||||
db = lancedb.connect(tmp_path)
|
||||
registry = get_registry()
|
||||
func = registry.get(alias).create(max_retries=0)
|
||||
@@ -89,7 +89,7 @@ def test_openclip(tmp_path):
|
||||
|
||||
db = lancedb.connect(tmp_path)
|
||||
registry = get_registry()
|
||||
func = registry.get("open-clip").create()
|
||||
func = registry.get("open-clip").create(max_retries=0)
|
||||
|
||||
class Images(LanceModel):
|
||||
label: str
|
||||
@@ -170,7 +170,7 @@ def test_cohere_embedding_function():
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_instructor_embedding(tmp_path):
|
||||
model = get_registry().get("instructor").create()
|
||||
model = get_registry().get("instructor").create(max_retries=0)
|
||||
|
||||
class TextModel(LanceModel):
|
||||
text: str = model.SourceField()
|
||||
@@ -182,3 +182,23 @@ def test_instructor_embedding(tmp_path):
|
||||
|
||||
tbl.add(df)
|
||||
assert len(tbl.to_pandas()["vector"][0]) == model.ndims()
|
||||
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.skipif(
|
||||
os.environ.get("GOOGLE_API_KEY") is None, reason="GOOGLE_API_KEY not set"
|
||||
)
|
||||
def test_gemini_embedding(tmp_path):
|
||||
model = get_registry().get("gemini-text").create(max_retries=0)
|
||||
|
||||
class TextModel(LanceModel):
|
||||
text: str = model.SourceField()
|
||||
vector: Vector(model.ndims()) = model.VectorField()
|
||||
|
||||
df = pd.DataFrame({"text": ["hello world", "goodbye world"]})
|
||||
db = lancedb.connect(tmp_path)
|
||||
tbl = db.create_table("test", schema=TextModel, mode="overwrite")
|
||||
|
||||
tbl.add(df)
|
||||
assert len(tbl.to_pandas()["vector"][0]) == model.ndims()
|
||||
assert tbl.search("hello").limit(1).to_pandas()["text"][0] == "hello world"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
# limitations under the License.
|
||||
import os
|
||||
import random
|
||||
from unittest import mock
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
@@ -43,7 +44,16 @@ def table(tmp_path) -> ldb.table.LanceTable:
|
||||
for _ in range(100)
|
||||
]
|
||||
table = db.create_table(
|
||||
"test", data=pd.DataFrame({"vector": vectors, "text": text, "text2": text})
|
||||
"test",
|
||||
data=pd.DataFrame(
|
||||
{
|
||||
"vector": vectors,
|
||||
"id": [i % 2 for i in range(100)],
|
||||
"text": text,
|
||||
"text2": text,
|
||||
"nested": [{"text": t} for t in text],
|
||||
}
|
||||
),
|
||||
)
|
||||
return table
|
||||
|
||||
@@ -72,9 +82,28 @@ def test_search_index(tmp_path, table):
|
||||
def test_create_index_from_table(tmp_path, table):
|
||||
table.create_fts_index("text")
|
||||
df = table.search("puppy").limit(10).select(["text"]).to_pandas()
|
||||
assert len(df) == 10
|
||||
assert len(df) <= 10
|
||||
assert "text" in df.columns
|
||||
|
||||
# Check whether it can be updated
|
||||
table.add(
|
||||
[
|
||||
{
|
||||
"vector": np.random.randn(128),
|
||||
"id": 101,
|
||||
"text": "gorilla",
|
||||
"text2": "gorilla",
|
||||
"nested": {"text": "gorilla"},
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError, match="already exists"):
|
||||
table.create_fts_index("text")
|
||||
|
||||
table.create_fts_index("text", replace=True)
|
||||
assert len(table.search("gorilla").limit(1).to_pandas()) == 1
|
||||
|
||||
|
||||
def test_create_index_multiple_columns(tmp_path, table):
|
||||
table.create_fts_index(["text", "text2"])
|
||||
@@ -89,3 +118,67 @@ def test_empty_rs(tmp_path, table, mocker):
|
||||
mocker.patch("lancedb.fts.search_index", return_value=([], []))
|
||||
df = table.search("puppy").limit(10).to_pandas()
|
||||
assert len(df) == 0
|
||||
|
||||
|
||||
def test_nested_schema(tmp_path, table):
|
||||
table.create_fts_index("nested.text")
|
||||
rs = table.search("puppy").limit(10).to_list()
|
||||
assert len(rs) == 10
|
||||
|
||||
|
||||
def test_search_index_with_filter(table):
|
||||
table.create_fts_index("text")
|
||||
orig_import = __import__
|
||||
|
||||
def import_mock(name, *args):
|
||||
if name == "duckdb":
|
||||
raise ImportError
|
||||
return orig_import(name, *args)
|
||||
|
||||
# no duckdb
|
||||
with mock.patch("builtins.__import__", side_effect=import_mock):
|
||||
rs = table.search("puppy").where("id=1").limit(10).to_list()
|
||||
for r in rs:
|
||||
assert r["id"] == 1
|
||||
|
||||
# yes duckdb
|
||||
rs2 = table.search("puppy").where("id=1").limit(10).to_list()
|
||||
for r in rs2:
|
||||
assert r["id"] == 1
|
||||
|
||||
assert rs == rs2
|
||||
|
||||
|
||||
def test_null_input(table):
|
||||
table.add(
|
||||
[
|
||||
{
|
||||
"vector": np.random.randn(128),
|
||||
"id": 101,
|
||||
"text": None,
|
||||
"text2": None,
|
||||
"nested": {"text": None},
|
||||
}
|
||||
]
|
||||
)
|
||||
table.create_fts_index("text")
|
||||
|
||||
|
||||
def test_syntax(table):
|
||||
# https://github.com/lancedb/lancedb/issues/769
|
||||
table.create_fts_index("text")
|
||||
with pytest.raises(ValueError, match="Syntax Error"):
|
||||
table.search("they could have been dogs OR cats").limit(10).to_list()
|
||||
table.search("they could have been dogs OR cats").phrase_query().limit(10).to_list()
|
||||
# this should work
|
||||
table.search('"they could have been dogs OR cats"').limit(10).to_list()
|
||||
# this should work too
|
||||
table.search('''"the cats OR dogs were not really 'pets' at all"''').limit(
|
||||
10
|
||||
).to_list()
|
||||
table.search('the cats OR dogs were not really "pets" at all').phrase_query().limit(
|
||||
10
|
||||
).to_list()
|
||||
table.search('the cats OR dogs were not really "pets" at all').phrase_query().limit(
|
||||
10
|
||||
).to_list()
|
||||
|
||||
@@ -13,9 +13,10 @@
|
||||
|
||||
|
||||
import json
|
||||
import pytz
|
||||
import sys
|
||||
from datetime import date, datetime
|
||||
from typing import List, Optional
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
import pyarrow as pa
|
||||
import pydantic
|
||||
@@ -38,11 +39,14 @@ def test_pydantic_to_arrow():
|
||||
id: int
|
||||
s: str
|
||||
vec: list[float]
|
||||
li: List[int]
|
||||
li: list[int]
|
||||
lili: list[list[float]]
|
||||
litu: list[tuple[float, float]]
|
||||
opt: Optional[str] = None
|
||||
st: StructModel
|
||||
dt: date
|
||||
dtt: datetime
|
||||
dt_with_tz: datetime = Field(json_schema_extra={"tz": "Asia/Shanghai"})
|
||||
# d: dict
|
||||
|
||||
m = TestModel(
|
||||
@@ -50,9 +54,12 @@ def test_pydantic_to_arrow():
|
||||
s="hello",
|
||||
vec=[1.0, 2.0, 3.0],
|
||||
li=[2, 3, 4],
|
||||
lili=[[2.5, 1.5], [3.5, 4.5], [5.5, 6.5]],
|
||||
litu=[(2.5, 1.5), (3.5, 4.5), (5.5, 6.5)],
|
||||
st=StructModel(a="a", b=1.0),
|
||||
dt=date.today(),
|
||||
dtt=datetime.now(),
|
||||
dt_with_tz=datetime.now(pytz.timezone("Asia/Shanghai")),
|
||||
)
|
||||
|
||||
schema = pydantic_to_schema(TestModel)
|
||||
@@ -63,6 +70,8 @@ def test_pydantic_to_arrow():
|
||||
pa.field("s", pa.utf8(), False),
|
||||
pa.field("vec", pa.list_(pa.float64()), False),
|
||||
pa.field("li", pa.list_(pa.int64()), False),
|
||||
pa.field("lili", pa.list_(pa.list_(pa.float64())), False),
|
||||
pa.field("litu", pa.list_(pa.list_(pa.float64())), False),
|
||||
pa.field("opt", pa.utf8(), True),
|
||||
pa.field(
|
||||
"st",
|
||||
@@ -73,11 +82,38 @@ def test_pydantic_to_arrow():
|
||||
),
|
||||
pa.field("dt", pa.date32(), False),
|
||||
pa.field("dtt", pa.timestamp("us"), False),
|
||||
pa.field("dt_with_tz", pa.timestamp("us", tz="Asia/Shanghai"), False),
|
||||
]
|
||||
)
|
||||
assert schema == expect_schema
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
sys.version_info < (3, 10),
|
||||
reason="using | type syntax requires python3.10 or higher",
|
||||
)
|
||||
def test_optional_types_py310():
|
||||
class TestModel(pydantic.BaseModel):
|
||||
a: str | None
|
||||
b: None | str
|
||||
c: Optional[str]
|
||||
|
||||
schema = pydantic_to_schema(TestModel)
|
||||
|
||||
expect_schema = pa.schema(
|
||||
[
|
||||
pa.field("a", pa.utf8(), True),
|
||||
pa.field("b", pa.utf8(), True),
|
||||
pa.field("c", pa.utf8(), True),
|
||||
]
|
||||
)
|
||||
assert schema == expect_schema
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
sys.version_info > (3, 8),
|
||||
reason="using native type alias requires python3.9 or higher",
|
||||
)
|
||||
def test_pydantic_to_arrow_py38():
|
||||
class StructModel(pydantic.BaseModel):
|
||||
a: str
|
||||
@@ -88,10 +124,13 @@ def test_pydantic_to_arrow_py38():
|
||||
s: str
|
||||
vec: List[float]
|
||||
li: List[int]
|
||||
lili: List[List[float]]
|
||||
litu: List[Tuple[float, float]]
|
||||
opt: Optional[str] = None
|
||||
st: StructModel
|
||||
dt: date
|
||||
dtt: datetime
|
||||
dt_with_tz: datetime = Field(json_schema_extra={"tz": "Asia/Shanghai"})
|
||||
# d: dict
|
||||
|
||||
m = TestModel(
|
||||
@@ -99,9 +138,12 @@ def test_pydantic_to_arrow_py38():
|
||||
s="hello",
|
||||
vec=[1.0, 2.0, 3.0],
|
||||
li=[2, 3, 4],
|
||||
lili=[[2.5, 1.5], [3.5, 4.5], [5.5, 6.5]],
|
||||
litu=[(2.5, 1.5), (3.5, 4.5), (5.5, 6.5)],
|
||||
st=StructModel(a="a", b=1.0),
|
||||
dt=date.today(),
|
||||
dtt=datetime.now(),
|
||||
dt_with_tz=datetime.now(pytz.timezone("Asia/Shanghai")),
|
||||
)
|
||||
|
||||
schema = pydantic_to_schema(TestModel)
|
||||
@@ -112,6 +154,8 @@ def test_pydantic_to_arrow_py38():
|
||||
pa.field("s", pa.utf8(), False),
|
||||
pa.field("vec", pa.list_(pa.float64()), False),
|
||||
pa.field("li", pa.list_(pa.int64()), False),
|
||||
pa.field("lili", pa.list_(pa.list_(pa.float64())), False),
|
||||
pa.field("litu", pa.list_(pa.list_(pa.float64())), False),
|
||||
pa.field("opt", pa.utf8(), True),
|
||||
pa.field(
|
||||
"st",
|
||||
@@ -122,6 +166,7 @@ def test_pydantic_to_arrow_py38():
|
||||
),
|
||||
pa.field("dt", pa.date32(), False),
|
||||
pa.field("dtt", pa.timestamp("us"), False),
|
||||
pa.field("dt_with_tz", pa.timestamp("us", tz="Asia/Shanghai"), False),
|
||||
]
|
||||
)
|
||||
assert schema == expect_schema
|
||||
|
||||
@@ -18,14 +18,17 @@ from lancedb.remote.client import VectorQuery, VectorQueryResult
|
||||
|
||||
|
||||
class FakeLanceDBClient:
|
||||
async def close(self):
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
async def query(self, table_name: str, query: VectorQuery) -> VectorQueryResult:
|
||||
def query(self, table_name: str, query: VectorQuery) -> VectorQueryResult:
|
||||
assert table_name == "test"
|
||||
t = pa.schema([]).empty_table()
|
||||
return VectorQueryResult(t)
|
||||
|
||||
def post(self, path: str):
|
||||
pass
|
||||
|
||||
|
||||
def test_remote_db():
|
||||
conn = lancedb.connect("db://client-will-be-injected", api_key="fake")
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
import functools
|
||||
from datetime import timedelta
|
||||
from datetime import date, datetime, timedelta
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
from unittest.mock import PropertyMock, patch
|
||||
@@ -20,8 +20,10 @@ from unittest.mock import PropertyMock, patch
|
||||
import lance
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import polars as pl
|
||||
import pyarrow as pa
|
||||
import pytest
|
||||
from pydantic import BaseModel
|
||||
|
||||
from lancedb.conftest import MockTextEmbeddingFunction
|
||||
from lancedb.db import LanceDBConnection
|
||||
@@ -141,14 +143,84 @@ def test_add(db):
|
||||
|
||||
|
||||
def test_add_pydantic_model(db):
|
||||
class TestModel(LanceModel):
|
||||
vector: Vector(16)
|
||||
li: List[int]
|
||||
# https://github.com/lancedb/lancedb/issues/562
|
||||
|
||||
data = TestModel(vector=list(range(16)), li=[1, 2, 3])
|
||||
table = LanceTable.create(db, "test", data=[data])
|
||||
assert len(table) == 1
|
||||
assert table.schema == TestModel.to_arrow_schema()
|
||||
class Metadata(BaseModel):
|
||||
source: str
|
||||
timestamp: datetime
|
||||
|
||||
class Document(BaseModel):
|
||||
content: str
|
||||
meta: Metadata
|
||||
|
||||
class LanceSchema(LanceModel):
|
||||
id: str
|
||||
vector: Vector(2)
|
||||
li: List[int]
|
||||
payload: Document
|
||||
|
||||
tbl = LanceTable.create(db, "mytable", schema=LanceSchema, mode="overwrite")
|
||||
assert tbl.schema == LanceSchema.to_arrow_schema()
|
||||
|
||||
# add works
|
||||
expected = LanceSchema(
|
||||
id="id",
|
||||
vector=[0.0, 0.0],
|
||||
li=[1, 2, 3],
|
||||
payload=Document(
|
||||
content="foo", meta=Metadata(source="bar", timestamp=datetime.now())
|
||||
),
|
||||
)
|
||||
tbl.add([expected])
|
||||
|
||||
result = tbl.search([0.0, 0.0]).limit(1).to_pydantic(LanceSchema)[0]
|
||||
assert result == expected
|
||||
|
||||
flattened = tbl.search([0.0, 0.0]).limit(1).to_pandas(flatten=1)
|
||||
assert len(flattened.columns) == 6 # _distance is automatically added
|
||||
|
||||
really_flattened = tbl.search([0.0, 0.0]).limit(1).to_pandas(flatten=True)
|
||||
assert len(really_flattened.columns) == 7
|
||||
|
||||
|
||||
def test_polars(db):
|
||||
data = {
|
||||
"vector": [[3.1, 4.1], [5.9, 26.5]],
|
||||
"item": ["foo", "bar"],
|
||||
"price": [10.0, 20.0],
|
||||
}
|
||||
# Ingest polars dataframe
|
||||
table = LanceTable.create(db, "test", data=pl.DataFrame(data))
|
||||
assert len(table) == 2
|
||||
|
||||
result = table.to_pandas()
|
||||
assert np.allclose(result["vector"].tolist(), data["vector"])
|
||||
assert result["item"].tolist() == data["item"]
|
||||
assert np.allclose(result["price"].tolist(), data["price"])
|
||||
|
||||
schema = pa.schema(
|
||||
[
|
||||
pa.field("vector", pa.list_(pa.float32(), 2)),
|
||||
pa.field("item", pa.large_string()),
|
||||
pa.field("price", pa.float64()),
|
||||
]
|
||||
)
|
||||
assert table.schema == schema
|
||||
|
||||
# search results to polars dataframe
|
||||
q = [3.1, 4.1]
|
||||
result = table.search(q).limit(1).to_polars()
|
||||
assert np.allclose(result["vector"][0], q)
|
||||
assert result["item"][0] == "foo"
|
||||
assert np.allclose(result["price"][0], 10.0)
|
||||
|
||||
# enter table to polars dataframe
|
||||
result = table.to_polars()
|
||||
assert np.allclose(result.collect()["vector"].to_list(), data["vector"])
|
||||
|
||||
# make sure filtering isn't broken
|
||||
filtered_result = result.filter(pl.col("item").is_in(["foo", "bar"])).collect()
|
||||
assert len(filtered_result) == 2
|
||||
|
||||
|
||||
def _add(table, schema):
|
||||
@@ -348,14 +420,79 @@ def test_update(db):
|
||||
assert len(table) == 2
|
||||
assert len(table.list_versions()) == 2
|
||||
table.update(where="id=0", values={"vector": [1.1, 1.1]})
|
||||
assert len(table.list_versions()) == 4
|
||||
assert table.version == 4
|
||||
assert len(table.list_versions()) == 3
|
||||
assert table.version == 3
|
||||
assert len(table) == 2
|
||||
v = table.to_arrow()["vector"].combine_chunks()
|
||||
v = v.values.to_numpy().reshape(2, 2)
|
||||
assert np.allclose(v, np.array([[1.2, 1.9], [1.1, 1.1]]))
|
||||
|
||||
|
||||
def test_update_types(db):
|
||||
table = LanceTable.create(
|
||||
db,
|
||||
"my_table",
|
||||
data=[
|
||||
{
|
||||
"id": 0,
|
||||
"str": "foo",
|
||||
"float": 1.1,
|
||||
"timestamp": datetime(2021, 1, 1),
|
||||
"date": date(2021, 1, 1),
|
||||
"vector1": [1.0, 0.0],
|
||||
"vector2": [1.0, 1.0],
|
||||
}
|
||||
],
|
||||
)
|
||||
# Update with SQL
|
||||
table.update(
|
||||
values_sql=dict(
|
||||
id="1",
|
||||
str="'bar'",
|
||||
float="2.2",
|
||||
timestamp="TIMESTAMP '2021-01-02 00:00:00'",
|
||||
date="DATE '2021-01-02'",
|
||||
vector1="[2.0, 2.0]",
|
||||
vector2="[3.0, 3.0]",
|
||||
)
|
||||
)
|
||||
actual = table.to_arrow().to_pylist()[0]
|
||||
expected = dict(
|
||||
id=1,
|
||||
str="bar",
|
||||
float=2.2,
|
||||
timestamp=datetime(2021, 1, 2),
|
||||
date=date(2021, 1, 2),
|
||||
vector1=[2.0, 2.0],
|
||||
vector2=[3.0, 3.0],
|
||||
)
|
||||
assert actual == expected
|
||||
|
||||
# Update with values
|
||||
table.update(
|
||||
values=dict(
|
||||
id=2,
|
||||
str="baz",
|
||||
float=3.3,
|
||||
timestamp=datetime(2021, 1, 3),
|
||||
date=date(2021, 1, 3),
|
||||
vector1=[3.0, 3.0],
|
||||
vector2=np.array([4.0, 4.0]),
|
||||
)
|
||||
)
|
||||
actual = table.to_arrow().to_pylist()[0]
|
||||
expected = dict(
|
||||
id=2,
|
||||
str="baz",
|
||||
float=3.3,
|
||||
timestamp=datetime(2021, 1, 3),
|
||||
date=date(2021, 1, 3),
|
||||
vector1=[3.0, 3.0],
|
||||
vector2=[4.0, 4.0],
|
||||
)
|
||||
assert actual == expected
|
||||
|
||||
|
||||
def test_create_with_embedding_function(db):
|
||||
class MyTable(LanceModel):
|
||||
text: str
|
||||
@@ -436,6 +573,33 @@ def test_multiple_vector_columns(db):
|
||||
assert result1["text"].iloc[0] != result2["text"].iloc[0]
|
||||
|
||||
|
||||
def test_create_scalar_index(db):
|
||||
vec_array = pa.array(
|
||||
[[1, 1], [2, 2], [3, 3], [4, 4], [5, 5]], pa.list_(pa.float32(), 2)
|
||||
)
|
||||
test_data = pa.Table.from_pydict(
|
||||
{"x": ["c", "b", "a", "e", "b"], "y": [1, 2, 3, 4, 5], "vector": vec_array}
|
||||
)
|
||||
table = LanceTable.create(
|
||||
db,
|
||||
"my_table",
|
||||
data=test_data,
|
||||
)
|
||||
table.create_scalar_index("x")
|
||||
indices = table.to_lance().list_indices()
|
||||
assert len(indices) == 1
|
||||
scalar_index = indices[0]
|
||||
assert scalar_index["type"] == "Scalar"
|
||||
|
||||
# Confirm that prefiltering still works with the scalar index column
|
||||
results = table.search().where("x = 'c'").to_arrow()
|
||||
assert results == test_data.slice(0, 1)
|
||||
results = table.search([5, 5]).to_arrow()
|
||||
assert results["_distance"][0].as_py() == 0
|
||||
results = table.search([5, 5]).where("x != 'b'").to_arrow()
|
||||
assert results["_distance"][0].as_py() > 0
|
||||
|
||||
|
||||
def test_empty_query(db):
|
||||
table = LanceTable.create(
|
||||
db,
|
||||
@@ -446,6 +610,14 @@ def test_empty_query(db):
|
||||
val = df.id.iloc[0]
|
||||
assert val == 1
|
||||
|
||||
table = LanceTable.create(db, "my_table2", data=[{"id": i} for i in range(100)])
|
||||
df = table.search().select(["id"]).to_pandas()
|
||||
assert len(df) == 10
|
||||
df = table.search().select(["id"]).limit(None).to_pandas()
|
||||
assert len(df) == 100
|
||||
df = table.search().select(["id"]).limit(-1).to_pandas()
|
||||
assert len(df) == 100
|
||||
|
||||
|
||||
def test_compact_cleanup(db):
|
||||
table = LanceTable.create(
|
||||
@@ -474,3 +646,14 @@ def test_compact_cleanup(db):
|
||||
|
||||
with pytest.raises(Exception, match="Version 3 no longer exists"):
|
||||
table.checkout(3)
|
||||
|
||||
|
||||
def test_count_rows(db):
|
||||
table = LanceTable.create(
|
||||
db,
|
||||
"my_table",
|
||||
data=[{"text": "foo", "id": 0}, {"text": "bar", "id": 1}],
|
||||
)
|
||||
assert len(table) == 2
|
||||
assert table.count_rows() == 2
|
||||
assert table.count_rows(filter="text='bar'") == 1
|
||||
|
||||
@@ -11,7 +11,12 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from lancedb.util import get_uri_scheme
|
||||
import os
|
||||
import pathlib
|
||||
|
||||
import pytest
|
||||
|
||||
from lancedb.util import get_uri_scheme, join_uri
|
||||
|
||||
|
||||
def test_normalize_uri():
|
||||
@@ -28,3 +33,55 @@ def test_normalize_uri():
|
||||
for uri, expected_scheme in zip(uris, schemes):
|
||||
parsed_scheme = get_uri_scheme(uri)
|
||||
assert parsed_scheme == expected_scheme
|
||||
|
||||
|
||||
def test_join_uri_remote():
|
||||
schemes = ["s3", "az", "gs"]
|
||||
for scheme in schemes:
|
||||
expected = f"{scheme}://bucket/path/to/table.lance"
|
||||
base_uri = f"{scheme}://bucket/path/to/"
|
||||
parts = ["table.lance"]
|
||||
assert join_uri(base_uri, *parts) == expected
|
||||
|
||||
base_uri = f"{scheme}://bucket"
|
||||
parts = ["path", "to", "table.lance"]
|
||||
assert join_uri(base_uri, *parts) == expected
|
||||
|
||||
|
||||
# skip this test if on windows
|
||||
@pytest.mark.skipif(os.name == "nt", reason="Windows paths are not POSIX")
|
||||
def test_join_uri_posix():
|
||||
for base in [
|
||||
# relative path
|
||||
"relative/path",
|
||||
"relative/path/",
|
||||
# an absolute path
|
||||
"/absolute/path",
|
||||
"/absolute/path/",
|
||||
# a file URI
|
||||
"file:///absolute/path",
|
||||
"file:///absolute/path/",
|
||||
]:
|
||||
joined = join_uri(base, "table.lance")
|
||||
assert joined == str(pathlib.Path(base) / "table.lance")
|
||||
joined = join_uri(pathlib.Path(base), "table.lance")
|
||||
assert joined == pathlib.Path(base) / "table.lance"
|
||||
|
||||
|
||||
# skip this test if not on windows
|
||||
@pytest.mark.skipif(os.name != "nt", reason="Windows paths are not POSIX")
|
||||
def test_local_join_uri_windows():
|
||||
# https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats
|
||||
for base in [
|
||||
# windows relative path
|
||||
"relative\\path",
|
||||
"relative\\path\\",
|
||||
# windows absolute path from current drive
|
||||
"c:\\absolute\\path",
|
||||
# relative path from root of current drive
|
||||
"\\relative\\path",
|
||||
]:
|
||||
joined = join_uri(base, "table.lance")
|
||||
assert joined == str(pathlib.Path(base) / "table.lance")
|
||||
joined = join_uri(pathlib.Path(base), "table.lance")
|
||||
assert joined == pathlib.Path(base) / "table.lance"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "vectordb-node"
|
||||
version = "0.3.8"
|
||||
version = "0.4.3"
|
||||
description = "Serverless, low-latency vector database for AI applications"
|
||||
license = "Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
@@ -36,7 +36,7 @@ fn validate_vector_column(record_batch: &RecordBatch) -> Result<()> {
|
||||
pub(crate) fn arrow_buffer_to_record_batch(slice: &[u8]) -> Result<(Vec<RecordBatch>, SchemaRef)> {
|
||||
let mut batches: Vec<RecordBatch> = Vec::new();
|
||||
let file_reader = FileReader::try_new(Cursor::new(slice), None)?;
|
||||
let schema = file_reader.schema().clone();
|
||||
let schema = file_reader.schema();
|
||||
for b in file_reader {
|
||||
let record_batch = b?;
|
||||
validate_vector_column(&record_batch)?;
|
||||
@@ -50,7 +50,7 @@ pub(crate) fn record_batch_to_buffer(batches: Vec<RecordBatch>) -> Result<Vec<u8
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
||||
let schema = batches.get(0).unwrap().schema();
|
||||
let schema = batches.first().unwrap().schema();
|
||||
let mut fr = FileWriter::try_new(Vec::new(), schema.deref())?;
|
||||
for batch in batches.iter() {
|
||||
fr.write(batch)?
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
// limitations under the License.
|
||||
|
||||
use neon::prelude::*;
|
||||
use neon::types::buffer::TypedArray;
|
||||
|
||||
use crate::error::ResultExt;
|
||||
|
||||
pub(crate) fn vec_str_to_array<'a, C: Context<'a>>(
|
||||
vec: &Vec<String>,
|
||||
@@ -34,3 +37,20 @@ pub(crate) fn js_array_to_vec(array: &JsArray, cx: &mut FunctionContext) -> Vec<
|
||||
}
|
||||
query_vec
|
||||
}
|
||||
|
||||
// Creates a new JsBuffer from a rust buffer with a special logic for electron
|
||||
pub(crate) fn new_js_buffer<'a>(
|
||||
buffer: Vec<u8>,
|
||||
cx: &mut TaskContext<'a>,
|
||||
is_electron: bool,
|
||||
) -> NeonResult<Handle<'a, JsBuffer>> {
|
||||
if is_electron {
|
||||
// Electron does not support `external`: https://github.com/neon-bindings/neon/pull/937
|
||||
let mut js_buffer = JsBuffer::new(cx, buffer.len()).or_throw(cx)?;
|
||||
let buffer_data = js_buffer.as_mut_slice(cx);
|
||||
buffer_data.copy_from_slice(buffer.as_slice());
|
||||
Ok(js_buffer)
|
||||
} else {
|
||||
Ok(JsBuffer::external(cx, buffer))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ pub enum Error {
|
||||
#[snafu(display("column '{name}' is missing"))]
|
||||
MissingColumn { name: String },
|
||||
#[snafu(display("{name}: {message}"))]
|
||||
RangeError { name: String, message: String },
|
||||
OutOfRange { name: String, message: String },
|
||||
#[snafu(display("{index_type} is not a valid index type"))]
|
||||
InvalidIndexType { index_type: String },
|
||||
|
||||
|
||||
@@ -12,4 +12,5 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
pub mod scalar;
|
||||
pub mod vector;
|
||||
|
||||
43
rust/ffi/node/src/index/scalar.rs
Normal file
43
rust/ffi/node/src/index/scalar.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright 2023 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.
|
||||
|
||||
use neon::{
|
||||
context::{Context, FunctionContext},
|
||||
result::JsResult,
|
||||
types::{JsBoolean, JsBox, JsPromise, JsString},
|
||||
};
|
||||
|
||||
use crate::{error::ResultExt, runtime, table::JsTable};
|
||||
|
||||
pub(crate) fn table_create_scalar_index(mut cx: FunctionContext) -> JsResult<JsPromise> {
|
||||
let js_table = cx.this().downcast_or_throw::<JsBox<JsTable>, _>(&mut cx)?;
|
||||
let column = cx.argument::<JsString>(0)?.value(&mut cx);
|
||||
let replace = cx.argument::<JsBoolean>(1)?.value(&mut cx);
|
||||
|
||||
let rt = runtime(&mut cx)?;
|
||||
|
||||
let (deferred, promise) = cx.promise();
|
||||
let channel = cx.channel();
|
||||
let mut table = js_table.table.clone();
|
||||
|
||||
rt.spawn(async move {
|
||||
let idx_result = table.create_scalar_index(&column, replace).await;
|
||||
|
||||
deferred.settle_with(&channel, move |mut cx| {
|
||||
idx_result.or_throw(&mut cx)?;
|
||||
Ok(cx.undefined())
|
||||
});
|
||||
});
|
||||
Ok(promise)
|
||||
}
|
||||
@@ -65,12 +65,10 @@ fn get_index_params_builder(
|
||||
obj.get_opt::<JsString, _, _>(cx, "index_name")?
|
||||
.map(|s| index_builder.index_name(s.value(cx)));
|
||||
|
||||
obj.get_opt::<JsString, _, _>(cx, "metric_type")?
|
||||
.map(|s| MetricType::try_from(s.value(cx).as_str()))
|
||||
.map(|mt| {
|
||||
let metric_type = mt.unwrap();
|
||||
index_builder.metric_type(metric_type);
|
||||
});
|
||||
if let Some(metric_type) = obj.get_opt::<JsString, _, _>(cx, "metric_type")? {
|
||||
let metric_type = MetricType::try_from(metric_type.value(cx).as_str()).unwrap();
|
||||
index_builder.metric_type(metric_type);
|
||||
}
|
||||
|
||||
let num_partitions = obj.get_opt_usize(cx, "num_partitions")?;
|
||||
let max_iters = obj.get_opt_usize(cx, "max_iters")?;
|
||||
@@ -85,23 +83,29 @@ fn get_index_params_builder(
|
||||
index_builder.ivf_params(ivf_params)
|
||||
});
|
||||
|
||||
obj.get_opt::<JsBoolean, _, _>(cx, "use_opq")?
|
||||
.map(|s| pq_params.use_opq = s.value(cx));
|
||||
if let Some(use_opq) = obj.get_opt::<JsBoolean, _, _>(cx, "use_opq")? {
|
||||
pq_params.use_opq = use_opq.value(cx);
|
||||
}
|
||||
|
||||
obj.get_opt_usize(cx, "num_sub_vectors")?
|
||||
.map(|s| pq_params.num_sub_vectors = s);
|
||||
if let Some(num_sub_vectors) = obj.get_opt_usize(cx, "num_sub_vectors")? {
|
||||
pq_params.num_sub_vectors = num_sub_vectors;
|
||||
}
|
||||
|
||||
obj.get_opt_usize(cx, "num_bits")?
|
||||
.map(|s| pq_params.num_bits = s);
|
||||
if let Some(num_bits) = obj.get_opt_usize(cx, "num_bits")? {
|
||||
pq_params.num_bits = num_bits;
|
||||
}
|
||||
|
||||
obj.get_opt_usize(cx, "max_iters")?
|
||||
.map(|s| pq_params.max_iters = s);
|
||||
if let Some(max_iters) = obj.get_opt_usize(cx, "max_iters")? {
|
||||
pq_params.max_iters = max_iters;
|
||||
}
|
||||
|
||||
obj.get_opt_usize(cx, "max_opq_iters")?
|
||||
.map(|s| pq_params.max_opq_iters = s);
|
||||
if let Some(max_opq_iters) = obj.get_opt_usize(cx, "max_opq_iters")? {
|
||||
pq_params.max_opq_iters = max_opq_iters;
|
||||
}
|
||||
|
||||
obj.get_opt::<JsBoolean, _, _>(cx, "replace")?
|
||||
.map(|s| index_builder.replace(s.value(cx)));
|
||||
if let Some(replace) = obj.get_opt::<JsBoolean, _, _>(cx, "replace")? {
|
||||
index_builder.replace(replace.value(cx));
|
||||
}
|
||||
|
||||
Ok(index_builder)
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user