From edcbce4a5b52fca0093187ca45b5eb9a422932ad Mon Sep 17 00:00:00 2001 From: Ilia Lobsanov Date: Thu, 5 Sep 2019 10:31:19 -0400 Subject: [PATCH] Support tsearch `followed by` operator (<->) --- lib/pg_search/features/tsearch.rb | 12 ++++++++++-- spec/integration/pg_search_spec.rb | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/lib/pg_search/features/tsearch.rb b/lib/pg_search/features/tsearch.rb index e91f2d6d..f9d7d935 100644 --- a/lib/pg_search/features/tsearch.rb +++ b/lib/pg_search/features/tsearch.rb @@ -7,7 +7,7 @@ module PgSearch module Features class TSearch < Feature # rubocop:disable Metrics/ClassLength def self.valid_options - super + %i[dictionary prefix negation any_word normalization tsvector_column highlight] + super + %i[dictionary prefix negation any_word followed_by normalization tsvector_column highlight] end def conditions @@ -133,7 +133,15 @@ def tsquery query_terms = query.split(" ").compact tsquery_terms = query_terms.map { |term| tsquery_for_term(term) } - tsquery_terms.join(options[:any_word] ? ' || ' : ' && ') + join_op = + if options[:any_word] + ' || ' + elsif options[:followed_by] + ' <-> ' + else + ' && ' + end + tsquery_terms.join(join_op) end def tsdocument diff --git a/spec/integration/pg_search_spec.rb b/spec/integration/pg_search_spec.rb index b6f376e2..898cfed9 100644 --- a/spec/integration/pg_search_spec.rb +++ b/spec/integration/pg_search_spec.rb @@ -785,6 +785,28 @@ end end + context "searching followed_by option" do + before do + ModelWithPgSearch.pg_search_scope :search_title_with_followed_by, + against: :title, + using: { + tsearch: { followed_by: true } + } + end + + it "returns all results containing word followed by another word in their title" do + numbers = %w[one two three four].each_cons(2) { |word_sequence| ModelWithPgSearch.create!(title: word_sequence.join(' ')) } + + results = ModelWithPgSearch.search_title_with_followed_by("one two") + + expect(results.map(&:title)).to eq(["one two"]) + + results = ModelWithPgSearch.search_title_with_followed_by("one three") + + expect(results.map(&:title)).to eq([]) + end + end + context "with :negation" do before do ModelWithPgSearch.pg_search_scope :search_with_negation,