Skip to content

Integration with Chewy

Sam Pohlenz edited this page Oct 28, 2020 · 4 revisions

For heavy-duty search functionality, you may wish to run an Elasticsearch instance and integrate using the Chewy gem.

Model

class Movie < ApplicationRecord
  update_index('movies#movie') { self }
end

Index

class MoviesIndex < Chewy::Index
  settings({
    index: {
      max_result_window: 1_000_000
    },

    analysis: {
      normalizer: {
        lowercase: {
          type: 'custom',
          filter: ['lowercase', 'asciifolding']
        }
      }
    }
  })

  define_type Movie do
    field :title, type: "text" do
      field :sort, type: "keyword", normalizer: "lowercase"
    end
    field :director, type: "text" do
      field :sort, type: "keyword", normalizer: "lowercase"
    end
    field :cast, type: "text" do
      field :sort, type: "keyword", normalizer: "lowercase"
    end
    field :genre, type: "text" do
      field :sort, type: "keyword", normalizer: "lowercase"
    end
    field :notes, type: "text" do
      field :sort, type: "keyword", normalizer: "lowercase"
    end
    field :year, type: "integer"
  end
end

Admin

Trestle.resource(:movies) do
  adapter.include Trestle::Search::ChewyAdapter

  search do |query|
    MoviesIndex
      .query(query ? { prefix: { _all: query } } : nil)
      .order("title.sort": :asc)
  end

  scope :year_1900_1949, label: "1900-1949" do
    MoviesIndex.query(range: { year: { gte: 1900, lte: 1949 } })
  end
  scope :year_1950_1999, label: "1950-1999" do
    MoviesIndex.query(range: { year: { gte: 1950, lte: 1999 } })
  end
  scope :year_2000_2049, label: "2000-2049" do
    MoviesIndex.query(range: { year: { gte: 2000, lte: 2049 } })
  end

  table do
    column(:title, link: true, sort: { default: true })
    column(:year)
    column(:director, sort: "director.sort")
    column(:cast, sort: "cast.sort")
    column(:genre, sort: "genre.sort")
    column(:notes, sort: "notes.sort")
  end
end
Clone this wiki locally