neighbor 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +1 -1
- data/README.md +3 -3
- data/lib/neighbor/model.rb +39 -8
- data/lib/neighbor/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da5f64785d929d673be65b5cf224894b6e5d6bbd8d66a27b84339ced5e8c1334
|
4
|
+
data.tar.gz: fbb217005dcd6a3c1d946eec178acf7f0f87ac3521e2deb4b7c8c2bc5433b633
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d293a32bfd18e00851bcbbaecac507374e9105071fbf7ab8446eaea093b9741b573356a7b292bf19dd420c2d7208c62023be4f7106711e19f9e84970aedba2bd
|
7
|
+
data.tar.gz: 07ed7bccab0924fe183df1176937d6ce98d1e53313e2be53d96605d691ad697ff4e14abc722b7a3501b20a5ca2880774625a306c274f81d308895fa78a1bf068
|
data/CHANGELOG.md
CHANGED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -9,12 +9,12 @@ Nearest neighbor search for Rails and Postgres
|
|
9
9
|
Add this line to your application’s Gemfile:
|
10
10
|
|
11
11
|
```ruby
|
12
|
-
gem
|
12
|
+
gem "neighbor"
|
13
13
|
```
|
14
14
|
|
15
15
|
## Choose An Extension
|
16
16
|
|
17
|
-
Neighbor supports two extensions: [cube](https://www.postgresql.org/docs/current/cube.html) and [vector](https://github.com/
|
17
|
+
Neighbor supports two extensions: [cube](https://www.postgresql.org/docs/current/cube.html) and [vector](https://github.com/pgvector/pgvector). cube ships with Postgres, while vector supports approximate nearest neighbor search.
|
18
18
|
|
19
19
|
For cube, run:
|
20
20
|
|
@@ -23,7 +23,7 @@ rails generate neighbor:cube
|
|
23
23
|
rails db:migrate
|
24
24
|
```
|
25
25
|
|
26
|
-
For vector, [install pgvector](https://github.com/
|
26
|
+
For vector, [install pgvector](https://github.com/pgvector/pgvector#installation) and run:
|
27
27
|
|
28
28
|
```sh
|
29
29
|
rails generate neighbor:vector
|
data/lib/neighbor/model.rb
CHANGED
@@ -1,16 +1,43 @@
|
|
1
1
|
module Neighbor
|
2
2
|
module Model
|
3
|
-
def has_neighbors(dimensions: nil, normalize: nil)
|
4
|
-
|
5
|
-
# likely use argument
|
6
|
-
attribute_name = :neighbor_vector
|
3
|
+
def has_neighbors(attribute_name = :neighbor_vector, dimensions: nil, normalize: nil)
|
4
|
+
attribute_name = attribute_name.to_sym
|
7
5
|
|
8
6
|
class_eval do
|
9
|
-
|
7
|
+
@neighbor_attributes ||= {}
|
8
|
+
|
9
|
+
if @neighbor_attributes.empty?
|
10
|
+
def self.neighbor_attributes
|
11
|
+
parent_attributes =
|
12
|
+
if superclass.respond_to?(:neighbor_attributes)
|
13
|
+
superclass.neighbor_attributes
|
14
|
+
else
|
15
|
+
{}
|
16
|
+
end
|
17
|
+
|
18
|
+
parent_attributes.merge(@neighbor_attributes || {})
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
raise Error, "has_neighbors already called for #{attribute_name.inspect}" if neighbor_attributes[attribute_name]
|
23
|
+
@neighbor_attributes[attribute_name] = {dimensions: dimensions, normalize: normalize}
|
10
24
|
|
11
25
|
attribute attribute_name, Neighbor::Vector.new(dimensions: dimensions, normalize: normalize, model: self, attribute_name: attribute_name)
|
12
26
|
|
13
|
-
|
27
|
+
return if @neighbor_attributes.size != 1
|
28
|
+
|
29
|
+
scope :nearest_neighbors, ->(attribute_name, vector = nil, distance:) {
|
30
|
+
if vector.nil? && !attribute_name.nil? && attribute_name.respond_to?(:to_a)
|
31
|
+
vector = attribute_name
|
32
|
+
attribute_name = :neighbor_vector
|
33
|
+
end
|
34
|
+
attribute_name = attribute_name.to_sym
|
35
|
+
|
36
|
+
options = neighbor_attributes[attribute_name]
|
37
|
+
raise ArgumentError, "Invalid attribute" unless options
|
38
|
+
normalize = options[:normalize]
|
39
|
+
dimensions = options[:dimensions]
|
40
|
+
|
14
41
|
return none if vector.nil?
|
15
42
|
|
16
43
|
distance = distance.to_s
|
@@ -80,10 +107,14 @@ module Neighbor
|
|
80
107
|
.order(Arel.sql(order))
|
81
108
|
}
|
82
109
|
|
83
|
-
|
110
|
+
def nearest_neighbors(attribute_name = :neighbor_vector, **options)
|
111
|
+
attribute_name = attribute_name.to_sym
|
112
|
+
# important! check if neighbor attribute before calling send
|
113
|
+
raise ArgumentError, "Invalid attribute" unless self.class.neighbor_attributes[attribute_name]
|
114
|
+
|
84
115
|
self.class
|
85
116
|
.where.not(self.class.primary_key => send(self.class.primary_key))
|
86
|
-
.nearest_neighbors(send(attribute_name), **options)
|
117
|
+
.nearest_neighbors(attribute_name, send(attribute_name), **options)
|
87
118
|
end
|
88
119
|
end
|
89
120
|
end
|
data/lib/neighbor/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: neighbor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -60,7 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
requirements: []
|
63
|
-
rubygems_version: 3.
|
63
|
+
rubygems_version: 3.3.7
|
64
64
|
signing_key:
|
65
65
|
specification_version: 4
|
66
66
|
summary: Nearest neighbor search for Rails and Postgres
|