From efd534bd6bb37e8c70c4376940aa033e60b1b891 Mon Sep 17 00:00:00 2001 From: Andrew Kane Date: Mon, 30 Oct 2023 23:46:13 -0700 Subject: [PATCH] First commit --- .github/workflows/build.yml | 20 ++++++++++ .gitignore | 1 + LICENSE.txt | 21 ++++++++++ README.md | 78 +++++++++++++++++++++++++++++++++++++ example.nim | 18 +++++++++ 5 files changed, 138 insertions(+) create mode 100644 .github/workflows/build.yml create mode 100644 .gitignore create mode 100644 LICENSE.txt create mode 100644 README.md create mode 100644 example.nim diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..3c71313 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,20 @@ +name: build +on: [push, pull_request] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: sudo apt-get update && sudo apt-get install nim + - uses: ankane/setup-postgres@v1 + with: + database: pgvector_nim_test + dev-files: true + - run: | + cd /tmp + git clone --branch v0.5.1 https://github.com/pgvector/pgvector.git + cd pgvector + make + sudo make install + - run: nimble install db_connector + - run: nim c --run example.nim diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6f30a3a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/example diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..0e5e609 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2023 Andrew Kane + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b435d0d --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ +# pgvector-nim + +[pgvector](https://github.com/pgvector/pgvector) examples for Nim + +Supports [db_connector](https://github.com/nim-lang/db_connector) + +[![Build Status](https://github.com/pgvector/pgvector-nim/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/pgvector/pgvector-nim/actions) + +## Getting Started + +Follow the instructions for your database library: + +- [db_connector](#db_connector) + +## db_connector + +Enable the extension + +```nim +db.exec(sql"CREATE EXTENSION IF NOT EXISTS vector") +``` + +Create a table + +```nim +db.exec(sql"CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))") +``` + +Insert vectors + +```nim +db.exec(sql"INSERT INTO items (embedding) VALUES (?), (?), (?)", "[1,1,1]", "[2,2,2]", "[1,1,2]") +``` + +Get the nearest neighbors + +```nim +let rows = db.getAllRows(sql"SELECT * FROM items ORDER BY embedding <-> ? LIMIT 5", "[1,1,1]") +for row in rows: + echo row +``` + +Add an approximate index + +```nim +db.exec(sql"CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)") +# or +db.exec(sql"CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)") +``` + +Use `vector_ip_ops` for inner product and `vector_cosine_ops` for cosine distance + +See a [full example](example.nim) + +## Contributing + +Everyone is encouraged to help improve this project. Here are a few ways you can help: + +- [Report bugs](https://github.com/pgvector/pgvector-nim/issues) +- Fix bugs and [submit pull requests](https://github.com/pgvector/pgvector-nim/pulls) +- Write, clarify, or fix documentation +- Suggest or add new features + +To get started with development: + +```sh +git clone https://github.com/pgvector/pgvector-nim.git +cd pgvector-nim +createdb pgvector_nim_test +nimble install db_connector +nim c --run example.nim +``` + +Specify the path to libpq if needed: + +```sh +nim c --run --dynlibOverride:pq --passL:"/opt/homebrew/opt/libpq/lib/libpq.dylib" example.nim +``` diff --git a/example.nim b/example.nim new file mode 100644 index 0000000..83a76ea --- /dev/null +++ b/example.nim @@ -0,0 +1,18 @@ +import db_connector/db_postgres + +let db = db_postgres.open("localhost", "", "", "pgvector_nim_test") + +db.exec(sql"CREATE EXTENSION IF NOT EXISTS vector") +db.exec(sql"DROP TABLE IF EXISTS items") + +db.exec(sql"CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))") + +db.exec(sql"INSERT INTO items (embedding) VALUES (?), (?), (?)", "[1,1,1]", "[2,2,2]", "[1,1,2]") + +let rows = db.getAllRows(sql"SELECT * FROM items ORDER BY embedding <-> ? LIMIT 5", "[1,1,1]") +for row in rows: + echo row + +db.exec(sql"CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)") + +db.close()