pgvector 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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