[Search 2.0] Match both word boundaries when filtering tags (#13554)
This commit is contained in:
parent
1a48b3151a
commit
8762815709
4 changed files with 14 additions and 5 deletions
|
|
@ -69,10 +69,11 @@ module Homepage
|
|||
# would put all the previous filters in `OR` mode with tags, but what we need
|
||||
# is to only consider tags as a `OR` sub-condition
|
||||
if tags.present?
|
||||
# `~` is the regexp operator and the `\M` modifier signifies the "end of word"
|
||||
# `~` is the regexp operator, the `\m` modifier signifies the "beginning of word",
|
||||
# and the `\M` modifier signifies the "end of word".
|
||||
# see https://www.postgresql.org/docs/11/functions-matching.html#FUNCTIONS-POSIX-REGEXP
|
||||
# for additional info
|
||||
conditions = tags.map { |tag| relation.sanitize_sql_array(["cached_tag_list ~ ?", "#{tag}\\M"]) }
|
||||
conditions = tags.map { |tag| relation.sanitize_sql_array(["cached_tag_list ~ ?", "\\m#{tag}\\M"]) }
|
||||
@relation = @relation.where(conditions.join(" OR "))
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ module Search
|
|||
# The preferred solution, as we don't need the `Tag` model itself, is to use
|
||||
# `articles.cached_tag_list` and the `~` regexp operator with it
|
||||
tags.each do |tag|
|
||||
relation = relation.where("articles.cached_tag_list ~ ?", "#{tag}\\M")
|
||||
relation = relation.where("articles.cached_tag_list ~ ?", "\\m#{tag}\\M")
|
||||
end
|
||||
|
||||
# here we issue a COUNT(*) after all the conditions are applied,
|
||||
|
|
|
|||
|
|
@ -127,11 +127,13 @@ RSpec.describe Homepage::ArticlesQuery, type: :query do
|
|||
expect(described_class.call(tags: %i[beginners ruby]).ids).to match_array([article1.id, article2.id])
|
||||
end
|
||||
|
||||
it "does not return results for partial matches" do
|
||||
it "does not return results for partial matches", :aggregate_failures do
|
||||
article1.tag_list.add(:javascript)
|
||||
article1.save
|
||||
|
||||
expect(described_class.call(tags: %i[java]).ids).to be_empty
|
||||
expect(described_class.call(tags: %i[asc]).ids).to be_empty
|
||||
expect(described_class.call(tags: %i[script]).ids).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ RSpec.describe Search::Postgres::ReadingList, type: :service do
|
|||
expect(extract_from_results(result, :path)).not_to include(article_2.path)
|
||||
end
|
||||
|
||||
it "does not match on partial tags" do
|
||||
it "does not match on partial tags", :aggregate_failures do
|
||||
article_1.tag_list.add(:javascript)
|
||||
article_1.save!
|
||||
|
||||
|
|
@ -175,6 +175,12 @@ RSpec.describe Search::Postgres::ReadingList, type: :service do
|
|||
|
||||
result = described_class.search_documents(user, tags: [:java])
|
||||
expect(extract_from_results(result, :path)).to be_empty
|
||||
|
||||
result = described_class.search_documents(user, tags: [:asc])
|
||||
expect(extract_from_results(result, :path)).to be_empty
|
||||
|
||||
result = described_class.search_documents(user, tags: [:script])
|
||||
expect(extract_from_results(result, :path)).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue