Migration of trigram search in Rails
Asked Answered
H

4

5

I have a migration:

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

It generates this code in schema.rb:

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

and later, when I execute rake db:schema:load it generates wrong sql:

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

Firstly, it says:

ERROR: data type character varying has no default operator class for access method "gin"

Secondly, there are lost gin_trgm_ops.

How to make it works?

Rails 4.2

Hardihood answered 17/3, 2015 at 12:9 Comment(0)
S
4

You can use the order param to define the operator class.

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}

Found this solution here: http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index#1553-Adding-index-with-other-operator-classes-PostgreSQL-

Swirsky answered 15/4, 2015 at 19:18 Comment(1)
Thank you, but it still generates wrong schema.rb without gin_trgm_opsHardihood
H
2

Unfortunately, this cannot be solved unless schema is changed to sql. Few links:

Rails and Postgres Hstore: Can you add an index in a migration?

Why does add_index using 'gin' create a 'btree' index instead?

Once I have changed schema format to sql it works fine.

Hardihood answered 17/4, 2015 at 12:18 Comment(1)
You should include the important information from the links, and add them as reference. Please have a look at the help centerLogan
R
1

You can nowadays use the opclass option:

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 }
Ronald answered 15/6, 2018 at 11:20 Comment(2)
It's showing me an error like this 'Unknown key: :opclass. Valid keys are: :unique, :order, :name, :where, :length, :internal, :using, :algorithm, :type'Anaconda
NOTE: opclass option requires Rails 5.2+Binnings
R
0

You need to install the btree_gin Postgres extension in order to use GIN indexes.

Simply add enable_extension('btree_gin') to the migration and it all should work fine.

Reposit answered 25/1, 2016 at 11:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.