Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pg_bigmを使った検索を有効にする #615

Merged
merged 6 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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/6720 や https://github.com/codeforjapan/decidim-cfj/issues/101 などの対応のために導入。
Expand Down
Loading