Skip to content

Commit

Permalink
Added experimental support for MariaDB 11.7
Browse files Browse the repository at this point in the history
  • Loading branch information
ankane committed Dec 3, 2024
1 parent 05638f0 commit 77af6d4
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
services:
mariadb:
image: quay.io/mariadb-foundation/mariadb-devel:11.6-vector-preview
image: mariadb:11.7-rc
env:
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: 1
MARIADB_DATABASE: neighbor_test
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.5.1 (unreleased)

- Added experimental support for MariaDB 11.7
- Dropped experimental support for MariaDB 11.6 Vector

## 0.5.0 (2024-10-07)

- Added experimental support for SQLite (sqlite-vec)
Expand Down
18 changes: 5 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Supports:

- Postgres (cube and pgvector)
- SQLite (sqlite-vec) - experimental
- MariaDB 11.6 Vector - experimental
- MariaDB 11.7 - experimental
- MySQL 9 (searching requires HeatWave) - experimental

[![Build Status](https://github.com/ankane/neighbor/actions/workflows/build.yml/badge.svg)](https://github.com/ankane/neighbor/actions)
Expand Down Expand Up @@ -61,10 +61,10 @@ class AddEmbeddingToItems < ActiveRecord::Migration[8.0]
# cube
add_column :items, :embedding, :cube

# pgvector and MySQL
# pgvector, MariaDB, and MySQL
add_column :items, :embedding, :vector, limit: 3 # dimensions

# sqlite-vec and MariaDB
# sqlite-vec
add_column :items, :embedding, :binary
end
end
Expand Down Expand Up @@ -387,14 +387,6 @@ Supported values are:
- `cosine`
- `hamming`

For cosine distance with MariaDB, vectors must be normalized before being stored.

```ruby
class Item < ApplicationRecord
has_neighbors :embedding, normalize: true
end
```

### Indexing

Vector columns must use `null: false` to add a vector index
Expand All @@ -403,7 +395,7 @@ Vector columns must use `null: false` to add a vector index
class CreateItems < ActiveRecord::Migration[8.0]
def change
create_table :items do |t|
t.binary :embedding, null: false
t.vector :embedding, limit: 3, null: false
t.index :embedding, type: :vector
end
end
Expand Down Expand Up @@ -892,7 +884,7 @@ bundle exec rake test:postgresql
bundle exec rake test:sqlite

# MariaDB
docker run -e MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 -e MARIADB_DATABASE=neighbor_test -p 3307:3306 quay.io/mariadb-foundation/mariadb-devel:11.6-vector-preview
docker run -e MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 -e MARIADB_DATABASE=neighbor_test -p 3307:3306 mariadb:11.7-rc
bundle exec rake test:mariadb

# MySQL
Expand Down
14 changes: 7 additions & 7 deletions lib/neighbor/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def self.validate(value, dimensions:, type:, adapter:)
def self.normalize(value, column_info:)
return nil if value.nil?

raise Error, "Normalize not supported for type" unless [:cube, :vector, :halfvec, :binary].include?(column_info&.type)
raise Error, "Normalize not supported for type" unless [:cube, :vector, :halfvec].include?(column_info&.type)

norm = Math.sqrt(value.sum { |v| v * v })

Expand Down Expand Up @@ -86,10 +86,12 @@ def self.operator(adapter, column_type, distance)
end
when :mariadb
case column_type
when :binary
when :vector
case distance
when "euclidean", "cosine"
"VEC_DISTANCE"
when "euclidean"
"VEC_DISTANCE_EUCLIDEAN"
when "cosine"
"VEC_DISTANCE_COSINE"
end
when :integer
case distance
Expand Down Expand Up @@ -168,7 +170,7 @@ def self.order(adapter, type, operator, quoted_attribute, query)
if operator == "BIT_COUNT"
"BIT_COUNT(#{quoted_attribute} ^ #{query})"
else
"VEC_DISTANCE(#{quoted_attribute}, #{query})"
"#{operator}(#{quoted_attribute}, #{query})"
end
when :mysql
if operator == "BIT_COUNT"
Expand All @@ -191,8 +193,6 @@ def self.normalize_required?(adapter, column_type)
case adapter
when :postgresql
column_type == :cube
when :mariadb
true
else
false
end
Expand Down
10 changes: 1 addition & 9 deletions test/mariadb_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@ def test_cosine
assert_elements_in_delta [0, 0.05719095841050148], result.map(&:neighbor_distance)
end

def test_cosine_no_normalize
create_items(MariadbItem, :embedding)
error = assert_raises(Neighbor::Error) do
MariadbItem.find(1).nearest_neighbors(:embedding, distance: "cosine").first(3)
end
assert_equal "Set normalize for cosine distance with cube", error.message
end

def test_euclidean
create_items(MariadbItem, :embedding)
result = MariadbItem.find(1).nearest_neighbors(:embedding, distance: "euclidean").first(3)
Expand All @@ -41,7 +33,7 @@ def test_create

def test_vec_totext
MariadbItem.create!(embedding: [1, 2, 3])
assert_equal "[1.000000,2.000000,3.000000]", MariadbItem.pluck("VEC_ToText(embedding)").last
assert_equal "[1,2,3]", MariadbItem.pluck("VEC_ToText(embedding)").last
end

def test_vec_fromtext
Expand Down
2 changes: 1 addition & 1 deletion test/support/mariadb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class MariadbRecord < ActiveRecord::Base

MariadbRecord.connection.instance_eval do
create_table :mariadb_items, force: true do |t|
t.binary :embedding, null: false
t.vector :embedding, limit: 3, null: false
t.index :embedding, type: :vector
end

Expand Down

0 comments on commit 77af6d4

Please sign in to comment.