Skip to content

pgvector/pgvector-swift

Repository files navigation

pgvector-swift

pgvector support for Swift

Supports PostgresNIO and PostgresClientKit

Build Status

Getting Started

Follow the instructions for your database library:

Or check out an example:

PostgresNIO

Add to your application’s Package.swift

     dependencies: [
+        .package(url: "https://github.com/pgvector/pgvector-swift", from: "0.1.0")
     ],
     targets: [
         .executableTarget(name: "App", dependencies: [
+            .product(name: "Pgvector", package: "pgvector-swift"),
+            .product(name: "PgvectorNIO", package: "pgvector-swift")
         ])
     ]

Import the packages

import Pgvector
import PgvectorNIO

Enable the extension

try await client.query("CREATE EXTENSION IF NOT EXISTS vector")

Register the types

try await PgvectorNIO.registerTypes(client)

Create a table

try await client.query("CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))")

Insert vectors

let embedding1 = Vector([1, 1, 1])
let embedding2 = Vector([2, 2, 2])
let embedding3 = Vector([1, 1, 2])
try await client.query("INSERT INTO items (embedding) VALUES (\(embedding1)), (\(embedding2)), (\(embedding3))")

Get the nearest neighbors

let embedding = Vector([1, 1, 1])
let rows = try await client.query("SELECT id, embedding::text FROM items ORDER BY embedding <-> \(embedding) LIMIT 5")
for try await row in rows {
    print(row)
}

Add an approximate index

try await client.query("CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)")
// or
try await client.query("CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)")

Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance

See a full example

PostgresClientKit

Add to your application’s Package.swift

     dependencies: [
+        .package(url: "https://github.com/pgvector/pgvector-swift", from: "0.1.0")
     ],
     targets: [
         .executableTarget(name: "App", dependencies: [
+            .product(name: "Pgvector", package: "pgvector-swift"),
+            .product(name: "PgvectorClientKit", package: "pgvector-swift")
         ])
     ]

Import the packages

import Pgvector
import PgvectorClientKit

Enable the extension

let text = "CREATE EXTENSION IF NOT EXISTS vector"
let statement = try connection.prepareStatement(text: text)
try statement.execute()

Create a table

let text = "CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3))"
let statement = try connection.prepareStatement(text: text)
try statement.execute()

Insert vectors

let text = "INSERT INTO items (embedding) VALUES ($1), ($2), ($3)"
let statement = try connection.prepareStatement(text: text)
try statement.execute(parameterValues: [Vector([1, 1, 1]), Vector([2, 2, 2]), Vector([1, 1, 2])])

Get the nearest neighbors

let text = "SELECT * FROM items ORDER BY embedding <-> $1 LIMIT 5"
let statement = try connection.prepareStatement(text: text)
let cursor = try statement.execute(parameterValues: [Vector([1, 1, 1])])

for row in cursor {
    let columns = try row.get().columns
    let id = try columns[0].int()
    let embedding = try columns[1].vector()
    print(id, embedding)
}

Add an approximate index

let text = "CREATE INDEX ON items USING hnsw (embedding vector_l2_ops)"
// or
let text = "CREATE INDEX ON items USING ivfflat (embedding vector_l2_ops) WITH (lists = 100)"
let statement = try connection.prepareStatement(text: text)
try statement.execute()

Use vector_ip_ops for inner product and vector_cosine_ops for cosine distance

See a full example

Reference

Vectors

Create a vector from an array

let vec = Vector([1, 2, 3])

Half Vectors

Create a half vector from an array

let vec = HalfVector([1, 2, 3])

Sparse Vectors

Create a sparse vector from an array

let vec = SparseVector([1, 0, 2, 0, 3, 0])

Or a dictionary of non-zero elements

let vec = SparseVector([0: 1, 2: 2, 4: 3], dim: 6)!

Note: Indices start at 0

Get the number of dimensions

let dim = vec.dim

Get the indices and values of non-zero elements

let indices = vec.indices
let values = vec.values

Contributing

Everyone is encouraged to help improve this project. Here are a few ways you can help:

To get started with development:

git clone https://github.com/pgvector/pgvector-swift.git
cd pgvector-swift
createdb pgvector_swift_test
swift test

To run an example:

cd Examples/Ollama
createdb pgvector_example
swift run

About

pgvector support for Swift

Resources

License

Security policy

Stars

Watchers

Forks

Packages

No packages published

Languages