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

Support for augmenting with websearch_to_tsquery, phraseto_tsquery, plainto_tsquery #552

Open
stv8 opened this issue Feb 6, 2025 · 2 comments

Comments

@stv8
Copy link

stv8 commented Feb 6, 2025

As seen here: https://www.postgresql.org/docs/current/textsearch-controls.html

class Post < ApplicationRecord
    pg_search_scope :search_by_title, against: :title
end
Post.search_by_title("word|word")
Post.search_by_title.phrase("somebody once told me the world was gonna roll me")
Post.search_by_title.plain("Shrek is the best")

def tsquery_for_term(unsanitized_term)
if options[:negation] && unsanitized_term.start_with?("!")
unsanitized_term[0] = ""
negated = true
end
sanitized_term = unsanitized_term.gsub(DISALLOWED_TSQUERY_CHARACTERS, " ")
term_sql = Arel.sql(normalize(connection.quote(sanitized_term)))
tsquery = tsquery_expression(term_sql, negated: negated, prefix: options[:prefix])
Arel::Nodes::NamedFunction.new("to_tsquery", [dictionary, tsquery]).to_sql

Maybe we can add an options hash here to swap out the desired function? I'm new to Ruby but this is my best guess.

@mikehale
Copy link

mikehale commented Feb 13, 2025

Drop this into config/initializers/pg_search.rb

  module PgSearch::Features::TSearchOptions
    module Websearch
      extend ActiveSupport::Concern

      def tsquery
        if options[:websearch]
          return "''" if query.blank?

          term_sql = Arel.sql(normalize(connection.quote(query)))
          Arel::Nodes::NamedFunction.new('websearch_to_tsquery', [dictionary, term_sql]).to_sql
        else
          super
        end
      end

      class_methods do
        def valid_options
          super + %i[websearch]
        end
      end
    end
  end

  PgSearch::Features::TSearch.prepend(PgSearch::Features::TSearchOptions::Websearch)

Then update your scope options on your model to include websearch: true

  pg_search_scope :search,
    using: {
      tsearch: { dictionary: 'simple', websearch: true }
    }

@stv8
Copy link
Author

stv8 commented Feb 18, 2025

@mikehale Going to give this a shot tonight, thanks for the snippet!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants