neighbor 0.2.1 → 0.2.2

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: 8a71d9aff5133b9551dc47cfe490d5d6a0ee63d2b77ac1d3d2f381f58aef67d6
4
- data.tar.gz: d22cab3140b979ee0d13ddd2c99f064282e896d49c265bf9b1946dafbda7783a
3
+ metadata.gz: da5f64785d929d673be65b5cf224894b6e5d6bbd8d66a27b84339ced5e8c1334
4
+ data.tar.gz: fbb217005dcd6a3c1d946eec178acf7f0f87ac3521e2deb4b7c8c2bc5433b633
5
5
  SHA512:
6
- metadata.gz: 3e24a71c6ace693525fc4866aaa21ee7c75f7251d5d6e0820da3b6abc0bd6fd5921b20c2edbb7fc656b75991e1fc5607357dc02870072900e7b6ef972c840280
7
- data.tar.gz: 5b75200355c62c549c2d61820e74e1cc71e4ebce68a1e390af60dbe76b6e1b7a69e71d73c8121db42ea05fc296db4ecc1f5776c71ad988685f13f71fc00fec66
6
+ metadata.gz: d293a32bfd18e00851bcbbaecac507374e9105071fbf7ab8446eaea093b9741b573356a7b292bf19dd420c2d7208c62023be4f7106711e19f9e84970aedba2bd
7
+ data.tar.gz: 07ed7bccab0924fe183df1176937d6ce98d1e53313e2be53d96605d691ad697ff4e14abc722b7a3501b20a5ca2880774625a306c274f81d308895fa78a1bf068
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.2.2 (2022-07-13)
2
+
3
+ - Added support for configurable attribute name
4
+ - Added support for multiple attributes per model
5
+
1
6
  ## 0.2.1 (2021-12-15)
2
7
 
3
8
  - Added support for Active Record 7
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2021 Andrew Kane
3
+ Copyright (c) 2021-2022 Andrew Kane
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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 'neighbor'
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/ankane/pgvector). cube ships with Postgres, while vector supports approximate nearest neighbor search.
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/ankane/pgvector#installation) and run:
26
+ For vector, [install pgvector](https://github.com/pgvector/pgvector#installation) and run:
27
27
 
28
28
  ```sh
29
29
  rails generate neighbor:vector
@@ -1,16 +1,43 @@
1
1
  module Neighbor
2
2
  module Model
3
- def has_neighbors(dimensions: nil, normalize: nil)
4
- # TODO make configurable
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
- raise Error, "nearest_neighbors already defined" if method_defined?(:nearest_neighbors)
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
- scope :nearest_neighbors, ->(vector, distance:) {
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
- define_method :nearest_neighbors do |**options|
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
@@ -1,3 +1,3 @@
1
1
  module Neighbor
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
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.1
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: 2021-12-16 00:00:00.000000000 Z
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.2.32
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