Skip to content

Commit

Permalink
Merge pull request #615 from codeforjapan/search-with-pg_bigm
Browse files Browse the repository at this point in the history
pg_bigmを使った検索を有効にする
  • Loading branch information
ayuki-joto authored Jul 25, 2024
2 parents eae919b + 691508e commit a69942d
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 7 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/_check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ jobs:
IMAGEMAGICK_SRC: 7.1.0-50.tar.gz
SLACK_API_TOKEN: xoxb-dummy
SLACK_MESSAGE_CHANNEL: '#test'
permissions:
packages: read
services:
db:
image: postgres:12.14
image: ghcr.io/codeforjapan/postgresql_bigm:12-latest
ports:
- 5432:5432
env:
Expand Down
38 changes: 38 additions & 0 deletions app/models/decidim/searchable_resource.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# frozen_string_literal: true

require "pg_search"

module Decidim
# A Searchable Resource.
# This is a model to a PgSearch table that indexes all searchable resources.
# This table is used to perform textual searches.
#
# Main attributes are:
# - locale: One entry per locale is required, so each resource will be indexed once per locale.
# - content_a: The most relevant textual content.
# - content_b: The second most relevant textual content.
# - content_c: The third most relevant textual content.
# - content_d: The less relevant textual content.
# - datetime: The timestamp that places this resource in the line of time. Used as second criteria (first is text relevance) for sorting.
#
class SearchableResource < ApplicationRecord
include PgSearch::Model

belongs_to :organization,
foreign_key: "decidim_organization_id",
class_name: "Decidim::Organization"
belongs_to :scope,
foreign_key: "decidim_scope_id",
class_name: "Decidim::Scope",
optional: true
belongs_to :resource, polymorphic: true
belongs_to :decidim_participatory_space, polymorphic: true, optional: true

validates :locale, uniqueness: { scope: [:decidim_organization_id, :resource_type, :resource_id] } # rubocop:disable Rails/UniqueValidationWithoutIndex

pg_search_scope :global_search,
against: { content_a: "A", content_b: "B", content_c: "C", content_d: "D" },
ranked_by: ":bigram",
using: :bigram
end
end
4 changes: 0 additions & 4 deletions app/packs/stylesheets/decidim/cfj/search.scss

This file was deleted.

1 change: 0 additions & 1 deletion app/packs/stylesheets/decidim/decidim_application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,5 @@
@import "./cfj/buttons";
@import "./cfj/comment_content";
@import "./cfj/forms";
@import "./cfj/search";
@import "./cfj/media_print";
@import "./cfj/ql_html_editor";
74 changes: 74 additions & 0 deletions config/initializers/pg_search_override.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# frozen_string_literal: true

require "pg_search"

Rails.application.config.to_prepare do
## define `PgSearch::Features::Bigram` to use pg_bigm extension
module PgSearch
module Features
class Bigram < Feature
def conditions
if options[:threshold]
Arel::Nodes::Grouping.new(
similarity.gteq(options[:threshold])
)
else
Arel::Nodes::Grouping.new(
Arel::Nodes::InfixOperation.new(
infix_operator,
normalized_document,
normalized_query_for_like
)
)
end
end

def rank
Arel::Nodes::Grouping.new(similarity)
end

private

def similarity_function
"bigm_similarity"
end

def infix_operator
"like"
end

def similarity
Arel::Nodes::NamedFunction.new(
similarity_function,
[
normalized_query,
normalized_document
]
)
end

def normalized_document
Arel::Nodes::Grouping.new(Arel.sql(normalize(document)))
end

def normalized_query_for_like
sanitized_query = connection.quote(query)
Arel.sql("likequery(#{normalize(sanitized_query)})")
end

def normalized_query
sanitized_query = connection.quote(query)
Arel.sql(normalize(sanitized_query))
end
end
end
end

## override `PgSearch::ScopeOptions::FEATURE_CLASSES`
PgSearch::ScopeOptions::FEATURE_CLASSES = {
dmetaphone: PgSearch::Features::DMetaphone,
tsearch: PgSearch::Features::TSearch,
trigram: PgSearch::Features::Trigram,
bigram: PgSearch::Features::Bigram
}.freeze
end
1 change: 0 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
Rails.application.routes.draw do
# Redirect to Metadecidim Japan
get "/", to: redirect("https://meta.diycities.jp/"), constraints: { host: "www.diycities.jp" }
get "/search", to: redirect("/")

mount Decidim::Core::Engine => "/"
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
Expand Down
9 changes: 9 additions & 0 deletions db/migrate/20240713180919_enable_pg_bigm_extension.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class EnablePgBigmExtension < ActiveRecord::Migration[6.1]
def up
enable_extension 'pg_bigm'
end

def down
disable_extension 'pg_bigm'
end
end
4 changes: 4 additions & 0 deletions docs/UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ Decidim本体のバージョンを更新する際、特に注意が必要な内

https://github.com/codeforjapan/decidim-cfj/pull/415 で追加されたファイル。ディベートでconclusionsに空文字列を許すための修正。

* `app/models/decidim/searchable_resource.rb`

https://github.com/codeforjapan/decidim-cfj/pull/615 で追加したファイル。pg_searchのfeatureとしてbigram(`pg_bigm`)に対応させるためのもの。

* `app/uploaders/decidim/cw/application_uploader.rb`

https://github.com/decidim/decidim/issues/6720https://github.com/codeforjapan/decidim-cfj/issues/101 などの対応のために導入。
Expand Down

0 comments on commit a69942d

Please sign in to comment.