Skip to content

Commit

Permalink
add meilisearch
Browse files Browse the repository at this point in the history
this thing is way too fast!  only downside is that indexing takes a bit
longer, and the search indexes are big (16Gi for 2.7 million records)

i have no idea how to properly integrate it in the UI, but it seems
promising :^)
  • Loading branch information
nilsding committed Oct 22, 2023
1 parent d5c1e66 commit f4d1a1f
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 8 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,4 @@ gem "mail", "~> 2.7.1"

gem "prometheus-client", "~> 4.2"

gem "meilisearch-rails", "~> 0.10.1"
5 changes: 5 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,10 @@ GEM
mail (2.7.1)
mini_mime (>= 0.1.1)
marcel (1.0.2)
meilisearch (0.25.1)
httparty (>= 0.17.1, < 0.22.0)
meilisearch-rails (0.10.1)
meilisearch (~> 0.25.0)
method_source (1.0.0)
mime-types (3.5.1)
mime-types-data (~> 3.2015)
Expand Down Expand Up @@ -535,6 +539,7 @@ DEPENDENCIES
letter_opener
lograge
mail (~> 2.7.1)
meilisearch-rails (~> 0.10.1)
mini_magick
net-imap
net-pop
Expand Down
1 change: 1 addition & 0 deletions Procfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ web: unset PORT && bin/rails server
worker: bundle exec sidekiq
css: yarn build:css --watch
js: yarn build --watch
search: meilisearch --no-analytics --env development --db-path tmp/meilisearch/db --dump-dir tmp/meilisearch/dump --master-key justfordev42069e621
32 changes: 29 additions & 3 deletions app/controllers/search_controller.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,35 @@
class SearchController < ApplicationController

Check notice on line 1 in app/controllers/search_controller.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] app/controllers/search_controller.rb#L1 <Style/FrozenStringLiteralComment>

Missing frozen string literal comment.
Raw output
app/controllers/search_controller.rb:1:1: C: Style/FrozenStringLiteralComment: Missing frozen string literal comment.
def index
@results = []
query = params[:q]
return if query.blank?
@query = params[:q]
return if @query.blank?

@results = []
@results = if params[:multi_search] == "1"
multi_search_experiment
else
[*Answer.search(@query), *Question.search(@query)]
end
end

private

def multi_search_experiment
MeiliSearch::Rails.client.multi_search(
[Answer, Question].map do |klass|
{
q: @query,
index_uid: klass.name.to_s,
show_ranking_score: true,
}
end

Check notice on line 24 in app/controllers/search_controller.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] app/controllers/search_controller.rb#L24 <Style/TrailingCommaInArguments>

Put a comma after the last parameter of a multiline method call.
Raw output
app/controllers/search_controller.rb:24:7: C: Style/TrailingCommaInArguments: Put a comma after the last parameter of a multiline method call.
)["results"].flat_map do |h|
model = h["indexUid"].constantize # bad practice!
results = model.find(h["hits"].pluck("id")).map { |r| [r.id.to_s, r] }.to_h

Check notice on line 27 in app/controllers/search_controller.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] app/controllers/search_controller.rb#L27 <Rails/IndexBy>

Prefer `index_by` over `map { ... }.to_h`.
Raw output
app/controllers/search_controller.rb:27:17: C: Rails/IndexBy: Prefer `index_by` over `map { ... }.to_h`.

Check notice on line 27 in app/controllers/search_controller.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] app/controllers/search_controller.rb#L27 <Style/MapToHash>

Pass a block to `to_h` instead of calling `map.to_h`.
Raw output
app/controllers/search_controller.rb:27:51: C: Style/MapToHash: Pass a block to `to_h` instead of calling `map.to_h`.
h["hits"].map { |hit| [hit["_rankingScore"], results[hit["id"]]] }
end
.sort_by(&:first)
.reverse
.tap { |results| Rails.logger.debug(results) }

Check notice on line 32 in app/controllers/search_controller.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] app/controllers/search_controller.rb#L29-L32 <Style/MultilineBlockChain>

Avoid multi-line chains of blocks.
Raw output
app/controllers/search_controller.rb:29:5: C: Style/MultilineBlockChain: Avoid multi-line chains of blocks.
.map(&:last)

Check notice on line 33 in app/controllers/search_controller.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] app/controllers/search_controller.rb#L33 <Layout/MultilineMethodCallIndentation>

Align `.map` with `.client` on line 17.
Raw output
app/controllers/search_controller.rb:33:7: C: Layout/MultilineMethodCallIndentation: Align `.map` with `.client` on line 17.
end
end
6 changes: 6 additions & 0 deletions app/models/answer.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
class Answer < ApplicationRecord
extend Answer::TimelineMethods

include MeiliSearch::Rails

meilisearch do
attribute :content
end

belongs_to :user, counter_cache: :answered_count
belongs_to :question, counter_cache: :answer_count
has_many :comments, dependent: :destroy
Expand Down
6 changes: 6 additions & 0 deletions app/models/question.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
class Question < ApplicationRecord
include Question::AnswerMethods

include MeiliSearch::Rails

meilisearch do
attribute :content
end

belongs_to :user, optional: true
has_many :answers, dependent: :destroy
has_many :inboxes, dependent: :destroy
Expand Down
11 changes: 6 additions & 5 deletions app/views/search/index.haml
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@
.col-sm-10.col-md-10.col-lg-9.mx-auto
.card
.card-body
= bootstrap_form_tag layout: :inline, method: :get do |f|
= f.text_field :q, skip_label: true, append: f.primary("Search")
= bootstrap_form_with url: search_path, layout: :inline, method: :get do |f|
= f.text_field :q, skip_label: true, append: f.primary("Search"), value: params[:q]
= f.check_box :multi_search, label: "Multisearch"
- unless @results.blank?
.container-lg.container--main
.row
.col-sm-10.col-md-10.col-lg-9.mx-auto
- @results.each do |result|
- case result.searchable
- case result
- when Answer
= render "answerbox", a: result.searchable, display_all: false, subscribed_answer_ids: []
= render "answerbox", a: result, display_all: false, subscribed_answer_ids: []
- when Question
= render "shared/question", q: result.searchable, type: nil
= render "shared/question", q: result, type: nil

= render 'shared/links'

Expand Down
8 changes: 8 additions & 0 deletions config/initializers/meilisearch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

return unless ENV["SEARCH_ENABLED"] == "true"

MeiliSearch::Rails.configuration = {
meilisearch_url: ENV.fetch("MEILISEARCH_HOST", "http://localhost:7700"),
meilisearch_api_key: ENV.fetch("MEILISEARCH_API_KEY", "justfordev42069e621")
}

0 comments on commit f4d1a1f

Please sign in to comment.