pgvector 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a0729ce3ec22ea08be365fc6c7a5c5e0b038860d5c9a57ccd2554d9d8b57a3f2
4
- data.tar.gz: c36eabc18ca6db3dd47204df3c48b58f7ac635e230bb9039269506d7d8afa834
3
+ metadata.gz: 215f975cafa2f782f3777ec65dd2fea587b420286f7f5ccf63b6b68376756dfd
4
+ data.tar.gz: e1979a1aa4fd4157cb04ae73c0c62b378046ca97154a25d4355e827be5abc53b
5
5
  SHA512:
6
- metadata.gz: ff4dc7d6a7a26b1ff3502d2305b62fc25fff38f3bf314261dcb6aa0f40cc520963cfd9562af03b11678cad7819aef9951b480a61e138ae2ae02459ed668a5298
7
- data.tar.gz: 6aa39019d5566f83331f3c95bb6404b065b7f7a29be62e84be2f2b6ea58bc27d20002543d93dfec7a17256c970e32b9676e2d319d07758cf49fc31b89d3d4d7b
6
+ metadata.gz: 1e54d7c41f8750b99262021e402f329252b428678ee99510dd52a1a113aeffdf35628a23b6ca9408ce55350a237cb2d224e66dfe7aafefd645612a29b74529ff
7
+ data.tar.gz: c8a014bb3708690cf3e463954aa7a846ce79075da039e23b3f94644e50e3c28d05376539699fd8ffe3c3b93d54eecb393fed472bddb60619ba897a5204bc511a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 0.2.1 (2023-06-04)
2
+
3
+ - Added support for Sequel
4
+
1
5
  ## 0.2.0 (2023-05-11)
2
6
 
3
7
  - Dropped support for Ruby < 3
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [pgvector](https://github.com/pgvector/pgvector) support for Ruby
4
4
 
5
- Supports the [pg](https://github.com/ged/ruby-pg) gem
5
+ Supports [pg](https://github.com/ged/ruby-pg) and [Sequel](https://github.com/jeremyevans/sequel)
6
6
 
7
7
  For Rails, check out [Neighbor](https://github.com/ankane/neighbor)
8
8
 
@@ -19,6 +19,13 @@ gem "pgvector"
19
19
  And follow the instructions for your database library:
20
20
 
21
21
  - [pg](#pg)
22
+ - [Sequel](#sequel)
23
+
24
+ Or check out some examples:
25
+
26
+ - [Embeddings](examples/openai_embeddings.rb) with OpenAI
27
+ - [User-based recommendations](examples/disco_user_recs.rb) with Disco
28
+ - [Item-based recommendations](examples/disco_item_recs.rb) with Disco
22
29
 
23
30
  ## pg
24
31
 
@@ -43,6 +50,45 @@ Get the nearest neighbors to a vector
43
50
  conn.exec_params("SELECT * FROM items ORDER BY embedding <-> $1 LIMIT 5", [embedding]).to_a
44
51
  ```
45
52
 
53
+ ## Sequel
54
+
55
+ Create a table
56
+
57
+ ```ruby
58
+ DB.create_table :items do
59
+ primary_key :id
60
+ column :embedding, "vector(3)"
61
+ end
62
+ ```
63
+
64
+ Add the plugin to your model
65
+
66
+ ```ruby
67
+ class Item < Sequel::Model
68
+ plugin :pgvector, :embedding
69
+ end
70
+ ```
71
+
72
+ Insert a vector
73
+
74
+ ```ruby
75
+ Item.create(embedding: [1, 1, 1])
76
+ ```
77
+
78
+ Get the nearest neighbors to a record
79
+
80
+ ```ruby
81
+ item.nearest_neighbors(:embedding, distance: "euclidean").limit(5)
82
+ ```
83
+
84
+ Also supports `inner_product` and `cosine` distance
85
+
86
+ Get the nearest neighbors to a vector
87
+
88
+ ```ruby
89
+ Item.nearest_neighbors(:embedding, [1, 1, 1], distance: "euclidean").limit(5)
90
+ ```
91
+
46
92
  ## History
47
93
 
48
94
  View the [changelog](https://github.com/pgvector/pgvector-ruby/blob/master/CHANGELOG.md)
data/lib/pgvector/pg.rb CHANGED
@@ -20,7 +20,7 @@ module Pgvector
20
20
  module TextDecoder
21
21
  class Vector < ::PG::SimpleDecoder
22
22
  def decode(string, tuple = nil, field = nil)
23
- string[1..-2].split(",").map(&:to_f)
23
+ Pgvector.decode(string)
24
24
  end
25
25
  end
26
26
  end
@@ -1,3 +1,3 @@
1
1
  module Pgvector
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
data/lib/pgvector.rb CHANGED
@@ -1,5 +1,14 @@
1
- require "pgvector/version"
1
+ # modules
2
+ require_relative "pgvector/version"
2
3
 
3
4
  module Pgvector
4
5
  autoload :PG, "pgvector/pg"
6
+
7
+ def self.encode(data)
8
+ "[#{data.to_a.map(&:to_f).join(",")}]"
9
+ end
10
+
11
+ def self.decode(string)
12
+ string[1..-2].split(",").map(&:to_f)
13
+ end
5
14
  end
@@ -0,0 +1,77 @@
1
+ module Sequel
2
+ module Plugins
3
+ module Pgvector
4
+ def self.configure(model, *columns)
5
+ model.vector_columns ||= {}
6
+ columns.each do |column|
7
+ model.vector_columns[column.to_sym] = {}
8
+ end
9
+ end
10
+
11
+ module ClassMethods
12
+ attr_accessor :vector_columns
13
+
14
+ def nearest_neighbors(column, value, distance:)
15
+ value = ::Pgvector.encode(value) unless value.is_a?(String)
16
+ quoted_column = dataset.quote_identifier(column)
17
+ distance = distance.to_s
18
+
19
+ operator =
20
+ case distance
21
+ when "inner_product"
22
+ "<#>"
23
+ when "cosine"
24
+ "<=>"
25
+ when "euclidean"
26
+ "<->"
27
+ end
28
+
29
+ raise ArgumentError, "Invalid distance: #{distance}" unless operator
30
+
31
+ order = "#{quoted_column} #{operator} ?"
32
+
33
+ neighbor_distance =
34
+ if distance == "inner_product"
35
+ "(#{order}) * -1"
36
+ else
37
+ order
38
+ end
39
+
40
+ select_append(Sequel.lit("#{neighbor_distance} AS neighbor_distance", value))
41
+ .exclude(column => nil)
42
+ .order(Sequel.lit(order, value))
43
+ end
44
+
45
+ Plugins.inherited_instance_variables(self, :@vector_columns => :dup)
46
+ end
47
+
48
+ module InstanceMethods
49
+ def nearest_neighbors(column, **options)
50
+ column = column.to_sym
51
+ # important! check if neighbor attribute before calling send
52
+ raise ArgumentError, "Invalid column" unless self.class.vector_columns[column]
53
+
54
+ self.class
55
+ .nearest_neighbors(column, self[column], **options)
56
+ .exclude(primary_key => self[primary_key])
57
+ end
58
+
59
+ def []=(k, v)
60
+ if self.class.vector_columns.key?(k.to_sym) && !v.is_a?(String)
61
+ super(k, ::Pgvector.encode(v))
62
+ else
63
+ super
64
+ end
65
+ end
66
+
67
+ def [](k)
68
+ if self.class.vector_columns.key?(k.to_sym)
69
+ ::Pgvector.decode(super)
70
+ else
71
+ super
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pgvector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-05-12 00:00:00.000000000 Z
11
+ date: 2023-06-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: andrew@ankane.org
@@ -22,6 +22,7 @@ files:
22
22
  - lib/pgvector.rb
23
23
  - lib/pgvector/pg.rb
24
24
  - lib/pgvector/version.rb
25
+ - lib/sequel/plugins/pgvector.rb
25
26
  homepage: https://github.com/pgvector/pgvector-ruby
26
27
  licenses:
27
28
  - MIT