Миграция поиска триграмм в Rails

У меня есть миграция:

class AddGinIndexToContacts < ActiveRecord::Migration
  def up
    execute("CREATE INDEX contacts_search_idx ON contacts USING gin (first_name gin_trgm_ops, last_name gin_trgm_ops, name gin_trgm_ops)")
  end

  def down
    execute("DROP INDEX contacts_search_idx")
  end
end

Он генерирует этот код в schema.rb:

add_index "contacts", ["first_name", "last_name", "name"], name: "contacts_search_idx", using: :gin

и позже, когда я выполняю rake db:schema:load, он генерирует неправильный sql:

CREATE  INDEX  "contacts_search_idx" ON "contacts" USING gin ("first_name", "last_name", "name")

Во-первых, там сказано:

ОШИБКА: переменный тип данных не имеет класса оператора по умолчанию для метода доступа "gin"

Во-вторых, есть потерянные gin_trgm_ops.

Как заставить это работать?

Rails 4.2


person Dmitry Silchenko    schedule 17.03.2015    source источник


Ответы (4)


Вы можете использовать параметр порядка для определения класса оператора.

add_index "contacts", ["first_name", "last_name", "name"], name: "contacts_search_idx", using: :gin, order: {first_name: :gin_trgm_ops, last_name: :gin_trgm_ops, name: :gin_trgm_ops}

Нашел это решение здесь: http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index#1553-Adding-index-with-other-operator-classes-PostgreSQL-

person Marcus Derencius    schedule 15.04.2015
comment
Спасибо, но он по-прежнему генерирует неправильный schema.rb без gin_trgm_ops - person Dmitry Silchenko; 17.04.2015

В настоящее время вы можете использовать опцию opclass:

add_index :contacts, [:first_name, :last_name, :name], name: "contacts_search_idx", using: :gin, opclass: { first_name: :gin_trgm_ops, last_name: :gin_trgm_ops, name: :gin_trgm_ops }
person Ivan Navarrete    schedule 15.06.2018
comment
Он показывает мне ошибку, подобную этой: «Неизвестный ключ:: opclass. Допустимые ключи: :unique, :order, :name, :where, :length, :internal, :using, :algorithm, :type. - person NAREN PUSHPARAJU; 05.06.2019
comment
ПРИМЕЧАНИЕ. Для опции opclass требуется Rails 5.2+. - person Yarin; 12.10.2019

К сожалению, это не может быть решено, если схема не изменена на sql. Несколько ссылок:

Rails и Postgres Hstore: можете ли вы добавить индекс в миграции?

Почему add_index с помощью 'gin' создает ' вместо индекса btree'?

Как только я изменил формат схемы на sql, он отлично работает.

person Dmitry Silchenko    schedule 17.04.2015
comment
Вы должны включить важную информацию из ссылок и добавить их в качестве ссылки. Пожалуйста, загляните в справочный центр - person NatureShade; 17.04.2015

Вам необходимо установить btree_gin Postgres расширение, чтобы использовать GIN индексы.

Просто добавьте enable_extension('btree_gin') к миграции, и все должно работать нормально.

person mrstif    schedule 25.01.2016